Compare commits

...

68 Commits

Author SHA1 Message Date
Peter Lieven
2f487a3d40 ui/vnc: fix vmware VGA incompatiblities
this fixes invalid rectangle updates observed after commit 12b316d
with the vmware VGA driver. The issues occured because the server
and client surface update seems to be out of sync at some points
and the max width of the surface is not dividable by
VNC_DIRTY_BITS_PER_PIXEL (16).

Reported-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-18 08:21:24 +01:00
Peter Maydell
315b593441 Merge remote-tracking branch 'remotes/borntraeger/tags/kvm-s390-20140317' into staging
4 small patches:
- Fixing findings of valgrind regarding minor memory leaks:
  Currently we forget the pointer of qemu_allocate_irqs. Since we never
  free the irqs, this is not critical, but obviously not good programming
  style. While we are at it, we dont need the irq infrastructure for
  the sclp consoles.
- Handle new ELF error codes for BIOS loading

# gpg: Signature made Mon 17 Mar 2014 21:34:12 GMT using RSA key ID B5A61C7C
# gpg: Can't check signature: public key not found

* remotes/borntraeger/tags/kvm-s390-20140317:
  s390x/sclpconsole-lm: Fix and simplify irq setup
  s390x/sclpconsole: Fix and simplify interrupt injection
  s390x/cpu hotplug: Fix memory leak
  s390/ipl: Fix error path on BIOS loading

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-17 22:31:33 +00:00
Peter Maydell
cdf0592cb8 Merge remote-tracking branch 'remotes/rth/tcg-v8p-2' into staging
* remotes/rth/tcg-v8p-2:
  tcg-sparc: Convert to new ldst opcodes
  tcg-sparc: Convert to new ldst helpers
  tcg-sparc: Tidy tcg_out_tlb_load interface
  tcg-sparc: Use TCGMemOp within qemu_ldst routines
  tcg-sparc: Improve tcg_out_movi
  tcg-sparc: Dont handle constant arguments to ext32 ops
  tcg-sparc: Don't handle remainder
  tcg-sparc: Use intptr_t as appropriate
  tcg-sparc: Tidy call+jump patterns
  tcg-sparc: Fix tlb read
  tcg-sparc: Fix ld64 for 32-bit mode

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-17 22:15:52 +00:00
Christian Borntraeger
4f3ed190a6 s390x/sclpconsole-lm: Fix and simplify irq setup
valgrind complains about a memory leak in irq setup of sclpconsole:

==42117== 8 bytes in 1 blocks are definitely lost in loss record 89of 833
==42117==    at 0x4031AFE: malloc (vg_replace_malloc.c:292)
==42117==    by 0x8022F855: malloc_and_trace (vl.c:2715)
==42117==    by 0x4145569: g_malloc (in /usr/lib64/libglib-2.0.so.0.3400.2)
==42117==    by 0x800F696D: qemu_extend_irqs (irq.c:51)
==42117==    by 0x800F6AF7: qemu_allocate_irqs (irq.c:68)
==42117==    by 0x800F5685: console_init (sclpconsole.c:235)
==42117==    by 0x80297C79: event_realize (event-facility.c:386)
==42117==    by 0x80105071: device_set_realized (qdev.c:693)
==42117==    by 0x801CDC4B: property_set_bool (object.c:1337)
 ==42117==    by 0x801CBD7F: object_property_set (object.c:819)
[...]

We dont need the indirection of an qemu irq to inject an slcp interrupt.
Fixes a valgrind error and makes the code simpler.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com>
2014-03-17 22:01:19 +01:00
Christian Borntraeger
b074e62205 s390x/sclpconsole: Fix and simplify interrupt injection
valgrind complains about a memory leak in irq setup of sclpconsole:

==42117== 8 bytes in 1 blocks are definitely lost in loss record 89 of 833
==42117==    at 0x4031AFE: malloc (vg_replace_malloc.c:292)
==42117==    by 0x8022F855: malloc_and_trace (vl.c:2715)
==42117==    by 0x4145569: g_malloc (in /usr/lib64/libglib-2.0.so.0.3400.2)
==42117==    by 0x800F696D: qemu_extend_irqs (irq.c:51)
==42117==    by 0x800F6AF7: qemu_allocate_irqs (irq.c:68)
==42117==    by 0x800F5685: console_init (sclpconsole.c:235)
==42117==    by 0x80297C79: event_realize (event-facility.c:386)
==42117==    by 0x80105071: device_set_realized (qdev.c:693)
==42117==    by 0x801CDC4B: property_set_bool (object.c:1337)
==42117==    by 0x801CBD7F: object_property_set (object.c:819)
[...]

Turns out that we actually dont need the indirection, so trigger the
sclp interrupt directly.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: Heinz Graalfs <graalfs@linux.vnet.ibm.com>
2014-03-17 22:01:19 +01:00
Christian Borntraeger
7b53f2940e s390x/cpu hotplug: Fix memory leak
valgrind complains about the following:
==42117== 8 bytes in 1 blocks are definitely lost in loss record 88 of 833
==42117==    at 0x4031AFE: malloc (vg_replace_malloc.c:292)
==42117==    by 0x8022F855: malloc_and_trace (vl.c:2715)
==42117==    by 0x4145569: g_malloc (in /usr/lib64/libglib-2.0.so.0.3400.2)
==42117==    by 0x800F696D: qemu_extend_irqs (irq.c:51)
==42117==    by 0x800F6AF7: qemu_allocate_irqs (irq.c:68)
==42117==    by 0x8029FA4B: irq_cpu_hotplug_init (sclpcpu.c:84)
==42117==    by 0x80297C79: event_realize (event-facility.c:386)
==42117==    by 0x80105071: device_set_realized (qdev.c:693)
[...]

Right it is. Don't drop the pointer of the irq.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Jason J. Herne <jjherne@us.ibm.com>
2014-03-17 22:01:19 +01:00
Christian Borntraeger
0a1bec8a4e s390/ipl: Fix error path on BIOS loading
commit 18674b2678
(elf-loader: add more return codes) enabled the elf loader to return
other errors than -1.

Lets also handle that case for our "BIOS" on s390.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
CC: Alexey Kardashevskiy <aik@ozlabs.ru>
CC: Alexander Graf <agraf@suse.de>
2014-03-17 22:01:19 +01:00
Richard Henderson
cab0a7ea00 tcg-sparc: Convert to new ldst opcodes
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-03-17 11:13:26 -07:00
Richard Henderson
7ea5d7256d tcg-sparc: Convert to new ldst helpers
All of the helpers with the explicit big/little endian option
require the return address as a parameter.  Acquire this via
a trampoline.

Move the load of areg0 into the trampoline.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-03-17 11:13:26 -07:00
Richard Henderson
a8b12c108c tcg-sparc: Tidy tcg_out_tlb_load interface
Pass address registers explicitly, rather than as indicies of args[].
It's two argument registers either way.  Use more TCGReg as appropriate.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-03-17 11:13:26 -07:00
Richard Henderson
eef0d9e740 tcg-sparc: Use TCGMemOp within qemu_ldst routines
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-03-17 11:13:26 -07:00
Richard Henderson
a9c7d27bd1 tcg-sparc: Improve tcg_out_movi
If bits 31:13 are zero, reduce the insn count by one.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-03-17 11:13:26 -07:00
Richard Henderson
1d0a60681a tcg-sparc: Dont handle constant arguments to ext32 ops
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-03-17 11:13:26 -07:00
Richard Henderson
5f9eb02555 tcg-sparc: Don't handle remainder
The generic fallback is exactly what we implemented.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-03-17 11:13:26 -07:00
Richard Henderson
c8fc56cedd tcg-sparc: Use intptr_t as appropriate
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-03-17 11:13:26 -07:00
Richard Henderson
aad2f06a7f tcg-sparc: Tidy call+jump patterns
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-03-17 11:13:25 -07:00
Richard Henderson
d801a8f2ce tcg-sparc: Fix tlb read
We were computing the full address into %o0 and then not using it.
Adjust some of the computation to rely less on having to pull immediate
values into registers.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-03-17 11:13:25 -07:00
Richard Henderson
e7bc9004e7 tcg-sparc: Fix ld64 for 32-bit mode
Since were not using an annulled branch, we need to put a nop
in the delay slot.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-03-17 11:13:25 -07:00
Peter Maydell
87f6396293 Merge remote-tracking branch 'remotes/kraxel/tags/pull-gtk-3' into staging
gtk: warp bugfixes.
gtk: Allow to activate grab-on-hover from the command line

# gpg: Signature made Mon 17 Mar 2014 13:35:35 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-gtk-3:
  gtk: Don't warp absolute pointer
  gtk: Fix mouse warping with gtk3
  gtk: Allow to activate grab-on-hover from the command line

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-17 15:51:57 +00:00
Cole Robinson
2bda66028b gtk: Don't warp absolute pointer
This matches the behavior of SDL, and makes the mouse usable when
using -display gtk -vga qxl

https://bugzilla.redhat.com/show_bug.cgi?id=1051724
Signed-off-by: Cole Robinson <crobinso@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-17 14:34:28 +01:00
Cole Robinson
298526fe92 gtk: Fix mouse warping with gtk3
We were using the wrong coordinates, this fixes things to match the
original gtk2 implementation.

You can see this error in action by using -vga qxl, however even after this
patch the mouse warps in small increments up and to the left, -7x and -3y
pixels at a time, until the pointer is warped off the widget. I think it's
a qxl bug, but the next patch covers it up.

Signed-off-by: Cole Robinson <crobinso@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-17 14:34:28 +01:00
Jan Kiszka
881249c792 gtk: Allow to activate grab-on-hover from the command line
As long as we have no persistent GTK configuration, this allows to
enable the useful grab-on-hover feature already when starting the VM.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>

[ kraxel: fix warning with CONFIG_GTK=n ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-03-17 14:33:55 +01:00
Peter Maydell
087edb503a Merge remote-tracking branch 'remotes/bonzini/fixes-for-2.0' into staging
* remotes/bonzini/fixes-for-2.0:
  vl.c: Output error on invalid machine type
  target-alpha: fix subl and s8subl indentation
  qemu-nbd: Fix coverity issues
  rules.mak: Fix per object libs extraction

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-17 13:05:48 +00:00
Miroslav Rezanina
025172d56e vl.c: Output error on invalid machine type
Output error message using qemu's error_report() function when user
provides the invalid machine type on the command line. This also saves
time to find what issue is when you downgrade from one version of qemu
to another that doesn't support required machine type yet (the version
user downgraded to have to have this patch applied too, of course).

Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
[Replace printf with error_printf, suggested by Markus Armbruster. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-03-17 13:21:12 +01:00
Paolo Bonzini
83d1c8ae88 target-alpha: fix subl and s8subl indentation
Two missing braces, one close and one open, fabulously let the code
compile.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-03-17 13:21:12 +01:00
Paolo Bonzini
0c544d73bb qemu-nbd: Fix coverity issues
There are two issues in qemu-nbd: a missing return value check after
calling accept(), and file descriptor leaks in nbd_client_thread.

Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-03-17 13:21:11 +01:00
Fam Zheng
6295b98d7b rules.mak: Fix per object libs extraction
Don't sort the extracted options, sort the objects.

Reported-by: Christian Mahnke <cmahnke@googlemail.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-03-17 13:21:11 +01:00
Fam Zheng
f4b11eee2f Makefile: Fix "make clean"
This fixes a dangerous bug: "make clean" after "make distclean" will
delete every single file including those under .git, if you do in-tree
build!

Rationale: A first "make distclean" will unset $(DSOSUF), a following
"make distclean" or "make clean" will find all the files and delete it.

Fix it by explicitly typing the file extensions here, and combine
multiple find invocations into one.

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-id: 1395020122-4957-1-git-send-email-famz@redhat.com
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-17 11:50:19 +00:00
Peter Maydell
6fffa26244 Merge remote-tracking branch 'remotes/mjt/tags/trivial-patches-2014-03-15' into staging
trivial patches for 2014-03-15

# gpg: Signature made Sat 15 Mar 2014 09:54:30 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-15:
  FSL eTSEC: Fix typo in rx ring
  scripts/make-release: Don't distribute .git directories
  configure: Don't use __int128_t for clang versions before 3.2
  audio: Add 'static' attributes to several variables
  tests: Fix 'make test' for i686 hosts (build regression)
  misc: Fix typos in comments
  Add qga/qapi-generated to .gitignore
  hw/timer/grlib_gptimer: Avoid integer overflows
  .travis.yml: add IRC notifications for build failures
  .travis.yml: trivial whitespace fixup
  .travis.yml: re-enable lttng user space trace test
  .travis.yml: add a new build target with non-core devlibs
  sasl: Avoid 'Could not find keytab file' in syslog

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-15 18:22:11 +00:00
Peter Maydell
e638308097 Merge remote-tracking branch 'remotes/rth/tcg-aarch-6-2' into staging
* remotes/rth/tcg-aarch-6-2:
  tcg-aarch64: Introduce tcg_out_insn_3405
  tcg-aarch64: Support div, rem
  tcg-aarch64: Support muluh, mulsh
  tcg-aarch64: Support add2, sub2
  tcg-aarch64: Support deposit
  tcg-aarch64: Use tcg_out_insn for setcond
  tcg-aarch64: Support movcond
  tcg-aarch64: Support andc, orc, eqv, not, neg
  tcg-aarch64: Handle constant operands to and, or, xor
  tcg-aarch64: Handle constant operands to add, sub, and compare
  tcg-aarch64: Implement mov with tcg_out_insn
  tcg-aarch64: Introduce tcg_out_insn_3401
  tcg-aarch64: Convert shift insns to tcg_out_insn
  tcg-aarch64: Introduce tcg_out_insn

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-15 18:03:15 +00:00
Fabien Chouteau
9c749e4dbe FSL eTSEC: Fix typo in rx ring
Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-15 13:54:18 +04:00
Cole Robinson
379e21c258 scripts/make-release: Don't distribute .git directories
[crobinso@localhost qemu-2.0.0-rc0]$ find . -name .git
./dtc/.git
./pixman/.git

This is already done for the rom submodules.

https://bugs.launchpad.net/qemu/+bug/1224414
Signed-off-by: Cole Robinson <crobinso@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-15 13:54:18 +04:00
Stefan Weil
a00f66ab9b configure: Don't use __int128_t for clang versions before 3.2
Those versions don't fully support __int128_t.

Cc: qemu-stable@nongnu.org
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-15 13:54:18 +04:00
Stefan Weil
69df1c3c9d audio: Add 'static' attributes to several variables
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-15 13:54:18 +04:00
Stefan Weil
6d4adef48d tests: Fix 'make test' for i686 hosts (build regression)
'make test' is broken at least since commit
baacf04799. Several source files were moved
to util/, and some of them there split, so add the missing prefix and new
files to fix the compiler and linker errors.

There remain more issues, but these changes allow running the test on a
Linux i686 host.

Cc: qemu-stable@nongnu.org
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-15 13:54:18 +04:00
Stefan Weil
3b163b0165 misc: Fix typos in comments
Codespell found and fixed these new typos:

* doesnt -> doesn't
* funtion -> function
* perfomance -> performance
* remaing -> remaining

A coding style issue (line too long) was fixed manually.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-15 13:54:18 +04:00
Gabriel L. Somlo
f214530f56 Add qga/qapi-generated to .gitignore
The folder "qga/qapi-generated" shows up after building QEMU, and
gets in the way during e.g. "git add ."; Add it to .gitignore to
keep it from accidentally ending up in the wrong place.

Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-15 13:54:18 +04:00
Sebastian Huber
9d5614d582 hw/timer/grlib_gptimer: Avoid integer overflows
The GPTIMER uses 32-bit registers.  Use a 64-bit operation to get the
ptimer count, otherwise we end up with a count of 0 for GPTIMER counter
values of 0xffffffff.

Use the GPTIMER counter value for tracing to avoid an overflow of the
32-bit value passed to trace_grlib_gptimer_enable().

Reviewed-by: Fabien Chouteau <chouteau@adacore.com>
Signed-off-by: Sebastian Huber <sebastian.huber@embedded-brains.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-15 13:54:18 +04:00
Alex Bennée
39d16d29c8 .travis.yml: add IRC notifications for build failures
I'm trying to avoid spamming the IRC channel (not overly likely as
builds take a while). So failure will always be reported but if the
build continues to work then the IRC notifications will be quiet.

Note any GitHub based repository with Travis enabled will use this
notification. If it proves to be too spammy we may want to ask users not
to use Travis themselves although this seems sub-optimal.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-15 13:54:18 +04:00
Alex Bennée
cc13eead53 .travis.yml: trivial whitespace fixup
Purely cosmetic but satisfies my OCD.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-15 13:54:18 +04:00
Alex Bennée
86c3b20a5f .travis.yml: re-enable lttng user space trace test
This build was disabled while the lttng tracing was broken. Stefan has
recently submitted a pull request with it re-enabled.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-15 13:54:18 +04:00
Alex Bennée
6d585ca559 .travis.yml: add a new build target with non-core devlibs
The current builds don't include all the features which are
auto-detected and then disabled when the appropriate test packages don't
exist. I've added another target that enables all known additional
packages for increased coverage. I didn't add it to the core package
list to reduce build time.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-15 13:54:18 +04:00
Laszlo Ersek
dfb3804d47 sasl: Avoid 'Could not find keytab file' in syslog
The "keytab" specification in "qemu.sasl" only makes sense if "gssapi" is
selected in "mech_list". Even if the latter is not done (ie. "gssapi" is
not selected), the cyrus-sasl library tries to open the specified keytab
file, although nothing has a use for it outside the gssapi backend.

Since the default keytab file "/etc/qemu/krb5.tab" is usually absent, the
cyrus-sasl library emits a warning to syslog at startup, which tends to
annoy users (who didn't ask for gssapi in the first place).

Comment out the keytab specification per default.

"qemu-doc.texi" already correctly explains how to use "mech_list: gssapi"
together with "keytab:".

See also:
- upstream libvirt commit fe772f24,
- Red Hat Bugzilla <https://bugzilla.redhat.com/show_bug.cgi?id=1018434>.

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
ACKed-By: Cole Robinson <crobinso@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-03-15 13:54:18 +04:00
Peter Maydell
4191d0eb41 Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Block pull request

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

* remotes/stefanha/tags/block-pull-request:
  qemu-iotests: remove 085 and 087 from 'quick' group
  qemu-iotests: add 083 NBD client disconnect tests
  tests: add nbd-fault-injector.py utility
  nbd: close socket if connection breaks
  block: Explicitly specify 'unsigned long long' for VHDX 64-bit constants
  blockdev: Refuse to open encrypted image unless paused

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-14 18:44:22 +00:00
Peter Maydell
03d51428e2 Merge remote-tracking branch 'remotes/bonzini/scsi-next' into staging
* remotes/bonzini/scsi-next:
  virtio-scsi: actually honor sense_size from configuration space
  scsi: Fix migration of scsi sense data
  spapr-vscsi: fix CRQ status

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-03-14 18:17:25 +00:00
Richard Henderson
582ab779c5 tcg-aarch64: Introduce tcg_out_insn_3405
Cleaning up the implementation of tcg_out_movi at the same time.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 11:00:15 -07:00
Richard Henderson
8678b71ce6 tcg-aarch64: Support div, rem
Clean up multiply at the same time.

For remainder, generic code will produce mul+sub,
whereas we can implement with msub.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 11:00:10 -07:00
Richard Henderson
1fcc9ddfb3 tcg-aarch64: Support muluh, mulsh
Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 11:00:07 -07:00
Richard Henderson
c6e929e784 tcg-aarch64: Support add2, sub2
Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 11:00:04 -07:00
Richard Henderson
b3c56df769 tcg-aarch64: Support deposit
Also tidy the implementation of ubfm, sbfm, extr in order to share code.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 11:00:01 -07:00
Richard Henderson
ed7a0aa8bc tcg-aarch64: Use tcg_out_insn for setcond
Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 10:59:58 -07:00
Richard Henderson
04ce397b33 tcg-aarch64: Support movcond
Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 10:59:55 -07:00
Richard Henderson
14b155ddc4 tcg-aarch64: Support andc, orc, eqv, not, neg
Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 10:59:52 -07:00
Richard Henderson
e029f29385 tcg-aarch64: Handle constant operands to and, or, xor
Handle a simplified set of logical immediates for the moment.

The way gcc and binutils do it, with 52k worth of tables, and
a binary search depth of log2(5334) = 13, seems slow for the
most common cases.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 10:59:47 -07:00
Richard Henderson
90f1cd9138 tcg-aarch64: Handle constant operands to add, sub, and compare
Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 10:59:44 -07:00
Richard Henderson
7d11fc7c2b tcg-aarch64: Implement mov with tcg_out_insn
Avoid the magic numbers in the current implementation.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 10:59:41 -07:00
Richard Henderson
096c46c0ff tcg-aarch64: Introduce tcg_out_insn_3401
This merges the implementation of tcg_out_addi and tcg_out_subi.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 10:59:38 -07:00
Richard Henderson
df9351e372 tcg-aarch64: Convert shift insns to tcg_out_insn
Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 10:59:35 -07:00
Richard Henderson
50573c66eb tcg-aarch64: Introduce tcg_out_insn
Converting the add/sub (3.5.2) and logical shifted (3.5.10) instruction
groups to the new scheme.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Tested-by: Claudio Fontana <claudio.fontana@huawei.com>
2014-03-14 10:59:13 -07:00
Stefan Hajnoczi
46dea4160d qemu-iotests: remove 085 and 087 from 'quick' group
The 'quick' group in qemu-iotests are not allowed to run QEMU since we
don't know which targets are available.  In other words, they may only
use qemu-img, qemu-io, and qemu-nbd.

Drop 085 and 087 from the 'quick' group since they run QEMU.  This
makes "make check-block" pass again.

Reported-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-03-14 16:30:38 +01:00
Stefan Hajnoczi
dc668ded10 qemu-iotests: add 083 NBD client disconnect tests
This new test case uses nbd-fault-injector.py to simulate broken TCP
connections at each stage in the NBD protocol.  This way we can exercise
block/nbd-client.c's socket error handling code paths.

In particular, this serves as a regression test to make sure
nbd-client.c doesn't cause an infinite loop by leaving its
nbd_receive_reply() fd handler registered after the connection has been
closed.  This bug was fixed in an earlier patch.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-03-14 16:29:02 +01:00
Stefan Hajnoczi
1e8ece0db3 tests: add nbd-fault-injector.py utility
The nbd-fault-injector.py script is a special kind of NBD server.  It
throws away all writes and produces zeroes for reads.  Given a list of
fault injection rules, it can simulate NBD protocol errors and is useful
for testing NBD client error handling code paths.

See the patch for documentation.  This scripts is modelled after Kevin
Wolf <kwolf@redhat.com>'s blkdebug block driver.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-03-14 16:28:28 +01:00
Stefan Hajnoczi
4a41a2d68a nbd: close socket if connection breaks
nbd_receive_reply() is called by the event loop whenever data is
available or the socket has been closed by the remote side.

This patch closes the socket when an error occurs to prevent the
nbd_receive_reply() handler from being called indefinitely after the
connection has failed.

Note that we were already correctly returning EIO for pending requests
but leaving the nbd_receive_reply() handler registered resulted in high
CPU consumption and a flood of error messages.

Reuse nbd_teardown_connection() to close the socket.

Reported-by: Zhifeng Cai <bluewindow@h3c.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-03-14 16:28:28 +01:00
Jeff Cody
62e466e845 block: Explicitly specify 'unsigned long long' for VHDX 64-bit constants
On 32-bit hosts, some compilers will warn on too large integer constants
for constants that are 64-bit in length.  Explicitly put a 'ULL' suffix
on those defines.

Reported-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-03-14 16:25:24 +01:00
Markus Armbruster
c3adb58fe0 blockdev: Refuse to open encrypted image unless paused
Opening an encrypted image takes an additional step: setting the key.
Between open and the key set, the image must not be used.

We have some protection against accidental use in place: you can't
unpause a guest while we're missing keys.  You can, however, hot-plug
block devices lacking keys into a running guest just fine, or insert
media lacking keys.  In the latter case, notifying the guest of the
insert is delayed until the key is set, which may suffice to protect
at least some guests in common usage.

This patch makes the protection apply in more cases, in a rather
heavy-handed way: it doesn't let you open encrypted images unless
we're in a paused state.

It doesn't extend the protection to users other than the guest (block
jobs?).  Use of runstate_check() from block.c is disgusting.  Best I
can do right now.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-03-14 16:24:42 +01:00
Paolo Bonzini
aa7a6a399f virtio-scsi: actually honor sense_size from configuration space
We were always truncating the sense size to 96 bytes.

Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-03-14 13:38:03 +01:00
Fam Zheng
2e323f03bf scsi: Fix migration of scsi sense data
c5f52875 changed the size of sense array in vmstate_scsi_device by
mistake. This patch restores the old size, and add a subsection for the
remaining part of the buffer size. So that migration is not broken.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-03-14 10:06:55 +01:00
Alexey Kardashevskiy
22956a3755 spapr-vscsi: fix CRQ status
Normally VIOSRP_OK (0) means success and non-zero value means error
except VIOSRP_OK2 (0x99) which is another success code by weird accident.

This uses 0 as success code always as some guests do not cope with
the 0x99 value well. The existing linux driver checks for both VIOSRP_OK
and VIOSRP_OK2 since 2.6.32.

This returns non-zero code (VIOSRP_ADAPTER_FAIL == 0x10) on errors which
can only happen if DMA write failed.

Suggested-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-03-14 10:06:55 +01:00
46 changed files with 1718 additions and 704 deletions

1
.gitignore vendored
View File

@@ -21,6 +21,7 @@
libdis*
libuser
/linux-headers/asm
/qga/qapi-generated
/qapi-generated
/qapi-types.[ch]
/qapi-visit.[ch]

View File

@@ -4,6 +4,12 @@ python:
compiler:
- gcc
- clang
notifications:
irc:
channels:
- "irc.oftc.net#qemu"
on_success: change
on_failure: always
env:
global:
- TEST_CMD="make check"
@@ -14,23 +20,23 @@ env:
- GUI_PKGS="libgtk-3-dev libvte-2.90-dev libsdl1.2-dev libpng12-dev libpixman-1-dev"
- EXTRA_PKGS=""
matrix:
- TARGETS=alpha-softmmu,alpha-linux-user
- TARGETS=arm-softmmu,arm-linux-user
- TARGETS=aarch64-softmmu,aarch64-linux-user
- TARGETS=cris-softmmu
- TARGETS=i386-softmmu,x86_64-softmmu
- TARGETS=lm32-softmmu
- TARGETS=m68k-softmmu
- TARGETS=microblaze-softmmu,microblazeel-softmmu
- TARGETS=mips-softmmu,mips64-softmmu,mips64el-softmmu,mipsel-softmmu
- TARGETS=moxie-softmmu
- TARGETS=or32-softmmu,
- TARGETS=ppc-softmmu,ppc64-softmmu,ppcemb-softmmu
- TARGETS=s390x-softmmu
- TARGETS=sh4-softmmu,sh4eb-softmmu
- TARGETS=sparc-softmmu,sparc64-softmmu
- TARGETS=unicore32-softmmu
- TARGETS=xtensa-softmmu,xtensaeb-softmmu
- TARGETS=alpha-softmmu,alpha-linux-user
- TARGETS=arm-softmmu,arm-linux-user
- TARGETS=aarch64-softmmu,aarch64-linux-user
- TARGETS=cris-softmmu
- TARGETS=i386-softmmu,x86_64-softmmu
- TARGETS=lm32-softmmu
- TARGETS=m68k-softmmu
- TARGETS=microblaze-softmmu,microblazeel-softmmu
- TARGETS=mips-softmmu,mips64-softmmu,mips64el-softmmu,mipsel-softmmu
- TARGETS=moxie-softmmu
- TARGETS=or32-softmmu,
- TARGETS=ppc-softmmu,ppc64-softmmu,ppcemb-softmmu
- TARGETS=s390x-softmmu
- TARGETS=sh4-softmmu,sh4eb-softmmu
- TARGETS=sparc-softmmu,sparc64-softmmu
- TARGETS=unicore32-softmmu
- TARGETS=xtensa-softmmu,xtensaeb-softmmu
before_install:
- git submodule update --init --recursive
- sudo apt-get update -qq
@@ -46,6 +52,10 @@ matrix:
- env: TARGETS=i386-softmmu,x86_64-softmmu
EXTRA_CONFIG="--enable-debug --enable-tcg-interpreter"
compiler: gcc
# All the extra -dev packages
- env: TARGETS=i386-softmmu,x86_64-softmmu
EXTRA_PKGS="libaio-dev libcap-ng-dev libattr1-dev libbrlapi-dev uuid-dev libusb-1.0.0-dev"
compiler: gcc
# Currently configure doesn't force --disable-pie
- env: TARGETS=i386-softmmu,x86_64-softmmu
EXTRA_CONFIG="--enable-gprof --enable-gcov --disable-pie"
@@ -65,8 +75,7 @@ matrix:
EXTRA_CONFIG="--enable-trace-backend=ftrace"
TEST_CMD=""
compiler: gcc
# This disabled make check for the ftrace backend which needs more setting up
# Currently broken on 12.04 due to mis-packaged liburcu and changed API, will be pulled.
#- env: TARGETS=i386-softmmu,x86_64-softmmu
# EXTRA_PKGS="liblttng-ust-dev liburcu-dev"
# EXTRA_CONFIG="--enable-trace-backend=ust"
- env: TARGETS=i386-softmmu,x86_64-softmmu
EXTRA_PKGS="liblttng-ust-dev liburcu-dev"
EXTRA_CONFIG="--enable-trace-backend=ust"
compiler: gcc

View File

@@ -265,10 +265,7 @@ clean:
# avoid old build problems by removing potentially incorrect old files
rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
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 {} +
find . \( -name '*.l[oa]' -o -name '*.so' -o -name '*.dll' -o -name '*.mo' -o -name '*.[oda]' \) -type f -exec rm {} +
rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~
rm -f fsdev/*.pod
rm -rf .libs */.libs

View File

@@ -1388,12 +1388,19 @@ done:
ret = -EINVAL;
goto close_and_fail;
}
QDECREF(options);
if (!bdrv_key_required(bs)) {
bdrv_dev_change_media_cb(bs, true);
} else if (!runstate_check(RUN_STATE_PRELAUNCH)
&& !runstate_check(RUN_STATE_INMIGRATE)
&& !runstate_check(RUN_STATE_PAUSED)) { /* HACK */
error_setg(errp,
"Guest must be stopped for opening of encrypted image");
ret = -EBUSY;
goto close_and_fail;
}
QDECREF(options);
*pbs = bs;
return 0;

View File

@@ -43,6 +43,17 @@ static void nbd_recv_coroutines_enter_all(NbdClientSession *s)
}
}
static void nbd_teardown_connection(NbdClientSession *client)
{
/* finish any pending coroutines */
shutdown(client->sock, 2);
nbd_recv_coroutines_enter_all(client);
qemu_aio_set_fd_handler(client->sock, NULL, NULL, NULL);
closesocket(client->sock);
client->sock = -1;
}
static void nbd_reply_ready(void *opaque)
{
NbdClientSession *s = opaque;
@@ -78,7 +89,7 @@ static void nbd_reply_ready(void *opaque)
}
fail:
nbd_recv_coroutines_enter_all(s);
nbd_teardown_connection(s);
}
static void nbd_restart_write(void *opaque)
@@ -324,7 +335,7 @@ int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num,
}
static void nbd_teardown_connection(NbdClientSession *client)
void nbd_client_session_close(NbdClientSession *client)
{
struct nbd_request request = {
.type = NBD_CMD_DISC,
@@ -332,22 +343,14 @@ static void nbd_teardown_connection(NbdClientSession *client)
.len = 0
};
nbd_send_request(client->sock, &request);
/* finish any pending coroutines */
shutdown(client->sock, 2);
nbd_recv_coroutines_enter_all(client);
qemu_aio_set_fd_handler(client->sock, NULL, NULL, NULL);
closesocket(client->sock);
client->sock = -1;
}
void nbd_client_session_close(NbdClientSession *client)
{
if (!client->bs) {
return;
}
if (client->sock == -1) {
return;
}
nbd_send_request(client->sock, &request);
nbd_teardown_connection(client);
client->bs = NULL;

View File

@@ -61,7 +61,7 @@
/* These structures are ones that are defined in the VHDX specification
* document */
#define VHDX_FILE_SIGNATURE 0x656C696678646876 /* "vhdxfile" in ASCII */
#define VHDX_FILE_SIGNATURE 0x656C696678646876ULL /* "vhdxfile" in ASCII */
typedef struct VHDXFileIdentifier {
uint64_t signature; /* "vhdxfile" in ASCII */
uint16_t creator[256]; /* optional; utf-16 string to identify
@@ -238,7 +238,7 @@ typedef struct QEMU_PACKED VHDXLogDataSector {
/* upper 44 bits are the file offset in 1MB units lower 3 bits are the state
other bits are reserved */
#define VHDX_BAT_STATE_BIT_MASK 0x07
#define VHDX_BAT_FILE_OFF_MASK 0xFFFFFFFFFFF00000 /* upper 44 bits */
#define VHDX_BAT_FILE_OFF_MASK 0xFFFFFFFFFFF00000ULL /* upper 44 bits */
typedef uint64_t VHDXBatEntry;
/* ---- METADATA REGION STRUCTURES ---- */
@@ -247,7 +247,7 @@ typedef uint64_t VHDXBatEntry;
#define VHDX_METADATA_MAX_ENTRIES 2047 /* not including the header */
#define VHDX_METADATA_TABLE_MAX_SIZE \
(VHDX_METADATA_ENTRY_SIZE * (VHDX_METADATA_MAX_ENTRIES+1))
#define VHDX_METADATA_SIGNATURE 0x617461646174656D /* "metadata" in ASCII */
#define VHDX_METADATA_SIGNATURE 0x617461646174656DULL /* "metadata" in ASCII */
typedef struct QEMU_PACKED VHDXMetadataTableHeader {
uint64_t signature; /* "metadata" in ASCII */
uint16_t reserved;

5
configure vendored
View File

@@ -3822,6 +3822,11 @@ fi
int128=no
cat > $TMPC << EOF
#if defined(__clang_major__) && defined(__clang_minor__)
# if ((__clang_major__ < 3) || (__clang_major__ == 3) && (__clang_minor__ < 2))
# error __int128_t does not work in CLANG before 3.2
# endif
#endif
__int128_t a;
__uint128_t b;
int main (void) {

View File

@@ -223,13 +223,13 @@ static void *cur_chip = NULL; /* current chip point */
/* static OPLSAMPLE *bufL,*bufR; */
static OPL_CH *S_CH;
static OPL_CH *E_CH;
OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2;
static OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2;
static INT32 outd[1];
static INT32 ams;
static INT32 vib;
INT32 *ams_table;
INT32 *vib_table;
static INT32 *ams_table;
static INT32 *vib_table;
static INT32 amsIncr;
static INT32 vibIncr;
static INT32 feedback2; /* connect for SLOT 2 */

View File

@@ -41,7 +41,6 @@ typedef struct SCLPConsoleLM {
uint32_t write_errors; /* errors writing to char layer */
uint32_t length; /* length of byte stream in buffer */
uint8_t buf[SIZE_CONSOLE_BUFFER];
qemu_irq irq_console_read;
} SCLPConsoleLM;
/*
@@ -68,13 +67,15 @@ static int chr_can_read(void *opaque)
return 0;
}
static void receive_from_chr_layer(SCLPConsoleLM *scon, const uint8_t *buf,
int size)
static void chr_read(void *opaque, const uint8_t *buf, int size)
{
SCLPConsoleLM *scon = opaque;
assert(size == 1);
if (*buf == '\r' || *buf == '\n') {
scon->event.event_pending = true;
sclp_service_interrupt(0);
return;
}
scon->buf[scon->length] = *buf;
@@ -84,20 +85,6 @@ static void receive_from_chr_layer(SCLPConsoleLM *scon, const uint8_t *buf,
}
}
/*
* Send data from a char device over to the guest
*/
static void chr_read(void *opaque, const uint8_t *buf, int size)
{
SCLPConsoleLM *scon = opaque;
receive_from_chr_layer(scon, buf, size);
if (scon->event.event_pending) {
/* trigger SCLP read operation */
qemu_irq_raise(scon->irq_console_read);
}
}
/* functions to be called by event facility */
static bool can_handle_event(uint8_t type)
@@ -298,11 +285,6 @@ static int write_event_data(SCLPEvent *event, EventBufferHeader *ebh)
return SCLP_RC_NORMAL_COMPLETION;
}
static void trigger_console_data(void *opaque, int n, int level)
{
sclp_service_interrupt(0);
}
/* functions for live migration */
static const VMStateDescription vmstate_sclplmconsole = {
@@ -338,7 +320,6 @@ static int console_init(SCLPEvent *event)
if (scon->chr) {
qemu_chr_add_handlers(scon->chr, chr_can_read, chr_read, NULL, scon);
}
scon->irq_console_read = *qemu_allocate_irqs(trigger_console_data, NULL, 1);
return 0;
}

View File

@@ -36,7 +36,6 @@ typedef struct SCLPConsole {
uint32_t iov_bs; /* offset in buf for char layer read operation */
uint32_t iov_data_len; /* length of byte stream in buffer */
uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */
qemu_irq irq_read_vt220;
} SCLPConsole;
/* character layer call-back functions */
@@ -49,11 +48,12 @@ static int chr_can_read(void *opaque)
return SIZE_BUFFER_VT220 - scon->iov_data_len;
}
/* Receive n bytes from character layer, save in iov buffer,
* and set event pending */
static void receive_from_chr_layer(SCLPConsole *scon, const uint8_t *buf,
int size)
/* Send data from a char device over to the guest */
static void chr_read(void *opaque, const uint8_t *buf, int size)
{
SCLPConsole *scon = opaque;
assert(scon);
/* read data must fit into current buffer */
assert(size <= SIZE_BUFFER_VT220 - scon->iov_data_len);
@@ -63,18 +63,7 @@ static void receive_from_chr_layer(SCLPConsole *scon, const uint8_t *buf,
scon->iov_sclp_rest += size;
scon->iov_bs += size;
scon->event.event_pending = true;
}
/* Send data from a char device over to the guest */
static void chr_read(void *opaque, const uint8_t *buf, int size)
{
SCLPConsole *scon = opaque;
assert(scon);
receive_from_chr_layer(scon, buf, size);
/* trigger SCLP read operation */
qemu_irq_raise(scon->irq_read_vt220);
sclp_service_interrupt(0);
}
/* functions to be called by event facility */
@@ -192,11 +181,6 @@ static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
return rc;
}
static void trigger_ascii_console_data(void *opaque, int n, int level)
{
sclp_service_interrupt(0);
}
static const VMStateDescription vmstate_sclpconsole = {
.name = "sclpconsole",
.version_id = 0,
@@ -232,8 +216,6 @@ static int console_init(SCLPEvent *event)
qemu_chr_add_handlers(scon->chr, chr_can_read,
chr_read, NULL, scon);
}
scon->irq_read_vt220 = *qemu_allocate_irqs(trigger_ascii_console_data,
NULL, 1);
return 0;
}

View File

@@ -25,6 +25,7 @@
#include "hw/loader.h"
#include "trace.h"
#include "ui/console.h"
#include "ui/vnc.h"
#include "hw/pci/pci.h"
#undef VERBOSE
@@ -218,7 +219,7 @@ enum {
/* These values can probably be changed arbitrarily. */
#define SVGA_SCRATCH_SIZE 0x8000
#define SVGA_MAX_WIDTH 2360
#define SVGA_MAX_WIDTH ROUND_UP(2360, VNC_DIRTY_PIXELS_PER_BIT)
#define SVGA_MAX_HEIGHT 1770
#ifdef VERBOSE

View File

@@ -148,7 +148,7 @@ 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
* clear a setting using a clear-register before setting the remaining bits
* using a set-register */
static void translate_clear(GICState *s, int irq, int cpu,
uint32_t *field, bool to_kernel)

View File

@@ -195,8 +195,8 @@ static void process_tx_fcb(eTSEC *etsec)
/* if packet is IP4 and IP checksum is requested */
if (flags & FCB_TX_IP && flags & FCB_TX_CIP) {
/* do IP4 checksum (TODO This funtion does TCP/UDP checksum but not sure
* if it also does IP4 checksum. */
/* do IP4 checksum (TODO This function does TCP/UDP checksum
* but not sure if it also does IP4 checksum.) */
net_checksum_calculate(etsec->tx_buffer + 8,
etsec->tx_buffer_len - 8);
}
@@ -592,7 +592,7 @@ void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr)
/* TODO: Broadcast and Multicast */
if (bd.flags | BD_INTERRUPT) {
if (bd.flags & BD_INTERRUPT) {
/* Set RXFx */
etsec->regs[RSTAT].value |= 1 << (7 - ring_nbr);
@@ -601,7 +601,7 @@ void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr)
}
} else {
if (bd.flags | BD_INTERRUPT) {
if (bd.flags & BD_INTERRUPT) {
/* Set IEVENT */
ievent_set(etsec, IEVENT_RXB);
}

View File

@@ -80,7 +80,7 @@ static int s390_ipl_init(SysBusDevice *dev)
bios_size = load_elf(bios_filename, NULL, NULL, &ipl->start_addr, NULL,
NULL, 1, ELF_MACHINE, 0);
if (bios_size == -1) {
if (bios_size < 0) {
bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START,
4096);
ipl->start_addr = ZIPL_IMAGE_START;

View File

@@ -25,13 +25,13 @@ typedef struct ConfigMgtData {
uint8_t event_qualifier;
} QEMU_PACKED ConfigMgtData;
static qemu_irq irq_cpu_hotplug; /* Only used in this file */
static qemu_irq *irq_cpu_hotplug; /* Only used in this file */
#define EVENT_QUAL_CPU_CHANGE 1
void raise_irq_cpu_hotplug(void)
{
qemu_irq_raise(irq_cpu_hotplug);
qemu_irq_raise(*irq_cpu_hotplug);
}
static unsigned int send_mask(void)
@@ -81,7 +81,7 @@ static void trigger_signal(void *opaque, int n, int level)
static int irq_cpu_hotplug_init(SCLPEvent *event)
{
irq_cpu_hotplug = *qemu_allocate_irqs(trigger_signal, event, 1);
irq_cpu_hotplug = qemu_allocate_irqs(trigger_signal, event, 1);
return 0;
}

View File

@@ -1905,6 +1905,26 @@ static const VMStateInfo vmstate_info_scsi_requests = {
.put = put_scsi_requests,
};
static bool scsi_sense_state_needed(void *opaque)
{
SCSIDevice *s = opaque;
return s->sense_len > SCSI_SENSE_BUF_SIZE_OLD;
}
static const VMStateDescription vmstate_scsi_sense_state = {
.name = "SCSIDevice/sense",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
VMSTATE_UINT8_SUB_ARRAY(sense, SCSIDevice,
SCSI_SENSE_BUF_SIZE_OLD,
SCSI_SENSE_BUF_SIZE - SCSI_SENSE_BUF_SIZE_OLD),
VMSTATE_END_OF_LIST()
}
};
const VMStateDescription vmstate_scsi_device = {
.name = "SCSIDevice",
.version_id = 1,
@@ -1915,7 +1935,7 @@ const VMStateDescription vmstate_scsi_device = {
VMSTATE_UINT8(unit_attention.asc, SCSIDevice),
VMSTATE_UINT8(unit_attention.ascq, SCSIDevice),
VMSTATE_BOOL(sense_is_ua, SCSIDevice),
VMSTATE_UINT8_ARRAY(sense, SCSIDevice, SCSI_SENSE_BUF_SIZE),
VMSTATE_UINT8_SUB_ARRAY(sense, SCSIDevice, 0, SCSI_SENSE_BUF_SIZE_OLD),
VMSTATE_UINT32(sense_len, SCSIDevice),
{
.name = "requests",
@@ -1927,6 +1947,14 @@ const VMStateDescription vmstate_scsi_device = {
.offset = 0,
},
VMSTATE_END_OF_LIST()
},
.subsections = (VMStateSubsection []) {
{
.vmsd = &vmstate_scsi_sense_state,
.needed = scsi_sense_state_needed,
}, {
/* empty */
}
}
};

View File

@@ -195,9 +195,9 @@ static int vscsi_send_iu(VSCSIState *s, vscsi_req *req,
req->crq.s.IU_data_ptr = req->iu.srp.rsp.tag; /* right byte order */
if (rc == 0) {
req->crq.s.status = 0x99; /* Just needs to be non-zero */
req->crq.s.status = VIOSRP_OK;
} else {
req->crq.s.status = 0x00;
req->crq.s.status = VIOSRP_ADAPTER_FAIL;
}
rc1 = spapr_vio_send_crq(&s->vdev, req->crq.raw);

View File

@@ -304,6 +304,8 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
size_t resid)
{
VirtIOSCSIReq *req = r->hba_private;
VirtIOSCSI *s = req->dev;
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
uint32_t sense_len;
if (r->io_canceled) {
@@ -317,7 +319,7 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
} else {
req->resp.cmd->resid = 0;
sense_len = scsi_req_get_sense(r, req->resp.cmd->sense,
VIRTIO_SCSI_SENSE_SIZE);
vs->sense_size);
req->resp.cmd->sense_len = tswap32(sense_len);
}
virtio_scsi_complete_req(req);

View File

@@ -106,9 +106,9 @@ static void grlib_gptimer_enable(GPTimer *timer)
/* ptimer is triggered when the counter reach 0 but GPTimer is triggered at
underflow. Set count + 1 to simulate the GPTimer behavior. */
trace_grlib_gptimer_enable(timer->id, timer->counter + 1);
trace_grlib_gptimer_enable(timer->id, timer->counter);
ptimer_set_count(timer->ptimer, timer->counter + 1);
ptimer_set_count(timer->ptimer, (uint64_t)timer->counter + 1);
ptimer_run(timer->ptimer, 1);
}

View File

@@ -31,6 +31,7 @@ typedef struct SCSISense {
uint8_t ascq;
} SCSISense;
#define SCSI_SENSE_BUF_SIZE_OLD 96
#define SCSI_SENSE_BUF_SIZE 252
struct SCSICommand {

View File

@@ -650,6 +650,9 @@ extern const VMStateInfo vmstate_info_bitmap;
#define VMSTATE_UINT8_ARRAY(_f, _s, _n) \
VMSTATE_UINT8_ARRAY_V(_f, _s, _n, 0)
#define VMSTATE_UINT8_SUB_ARRAY(_f, _s, _start, _num) \
VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint8, uint8_t)
#define VMSTATE_UINT8_2DARRAY(_f, _s, _n1, _n2) \
VMSTATE_UINT8_2DARRAY_V(_f, _s, _n1, _n2, 0)

View File

@@ -345,6 +345,6 @@ int index_from_key(const char *key);
/* gtk.c */
void early_gtk_display_init(void);
void gtk_display_init(DisplayState *ds, bool full_screen);
void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover);
#endif

View File

@@ -288,19 +288,19 @@ static void *nbd_client_thread(void *arg)
ret = nbd_receive_negotiate(sock, NULL, &nbdflags,
&size, &blocksize);
if (ret < 0) {
goto out;
goto out_socket;
}
fd = open(device, O_RDWR);
if (fd < 0) {
/* Linux-only, we can use %m in printf. */
fprintf(stderr, "Failed to open %s: %m", device);
goto out;
goto out_socket;
}
ret = nbd_init(fd, sock, nbdflags, size, blocksize);
if (ret < 0) {
goto out;
goto out_fd;
}
/* update partition table */
@@ -316,12 +316,16 @@ static void *nbd_client_thread(void *arg)
ret = nbd_client(fd);
if (ret) {
goto out;
goto out_fd;
}
close(fd);
kill(getpid(), SIGTERM);
return (void *) EXIT_SUCCESS;
out_fd:
close(fd);
out_socket:
closesocket(sock);
out:
kill(getpid(), SIGTERM);
return (void *) EXIT_FAILURE;
@@ -355,6 +359,11 @@ static void nbd_accept(void *opaque)
socklen_t addr_len = sizeof(addr);
int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len);
if (fd < 0) {
perror("accept");
return;
}
if (state >= TERMINATE) {
close(fd);
return;

View File

@@ -810,6 +810,7 @@ ETEXI
DEF("display", HAS_ARG, QEMU_OPTION_display,
"-display sdl[,frame=on|off][,alt_grab=on|off][,ctrl_grab=on|off]\n"
" [,window_close=on|off]|curses|none|\n"
" gtk[,grab_on_hover=on|off]|\n"
" vnc=<display>[,<optargs>]\n"
" select display type\n", QEMU_ARCH_ALL)
STEXI
@@ -833,6 +834,10 @@ graphics card, but its output will not be displayed to the QEMU
user. This option differs from the -nographic option in that it
only affects what is done with video output; -nographic also changes
the destination of the serial and parallel port data.
@item gtk
Display video output in a GTK window. This interface provides drop-down
menus and other UI elements to configure and control the VM during
runtime.
@item vnc
Start a VNC server on display <arg>
@end table

View File

@@ -22,7 +22,9 @@ mech_list: digest-md5
# Some older builds of MIT kerberos on Linux ignore this option &
# instead need KRB5_KTNAME env var.
# For modern Linux, and other OS, this should be sufficient
keytab: /etc/qemu/krb5.tab
#
# There is no default value here, uncomment if you need this
#keytab: /etc/qemu/krb5.tab
# If using digest-md5 for username/passwds, then this is the file
# containing the passwds. Use 'saslpasswd2 -a qemu [username]'

View File

@@ -23,8 +23,8 @@ QEMU_DGFLAGS += -MMD -MP -MT $@ -MF $(*D)/$(*F).d
QEMU_INCLUDES += -I$(<D) -I$(@D)
maybe-add = $(filter-out $1, $2) $1
extract-libs = $(strip $(sort $(foreach o,$1,$($o-libs)) \
$(foreach o,$(call expand-objs,$1),$($o-libs))))
extract-libs = $(strip $(sort $(foreach o,$1,$($o-libs))) \
$(foreach o,$(call expand-objs,$1),$($o-libs)))
expand-objs = $(strip $(sort $(filter %.o,$1)) \
$(foreach o,$(filter %.mo,$1),$($o-objs)) \
$(filter-out %.o %.mo,$1))

View File

@@ -18,7 +18,7 @@ git clone "${src}" ${destination}
pushd ${destination}
git checkout "v${version}"
git submodule update --init
rm -rf .git roms/*/.git
rm -rf .git roms/*/.git dtc/.git pixman/.git
popd
tar cfj ${destination}.tar.bz2 ${destination}
rm -rf ${destination}

View File

@@ -20,6 +20,7 @@ stub-obj-y += mon-set-error.o
stub-obj-y += pci-drive-hot-add.o
stub-obj-y += qtest.o
stub-obj-y += reset.o
stub-obj-y += runstate-check.o
stub-obj-y += set-fd-handler.o
stub-obj-y += slirp.o
stub-obj-y += sysbus.o

6
stubs/runstate-check.c Normal file
View File

@@ -0,0 +1,6 @@
#include "sysemu/sysemu.h"
bool runstate_check(RunState state)
{
return state == RUN_STATE_PRELAUNCH;
}

View File

@@ -1927,6 +1927,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
else {
tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
}
}
}
break;
@@ -1991,7 +1992,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
} else {
if (islit)
tcg_gen_movi_i64(cpu_ir[rc], -lit);
else
else {
tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
}

View File

@@ -488,7 +488,7 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
{
/* Perfomance monitor registers user accessibility is controlled
/* Performance monitor registers user accessibility is controlled
* by PMUSERENR.
*/
if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {

View File

@@ -2216,7 +2216,7 @@ static int bcd_cmp_mag(ppc_avr_t *a, ppc_avr_t *b)
uint8_t dig_a = bcd_get_digit(a, i, &invalid);
uint8_t dig_b = bcd_get_digit(b, i, &invalid);
if (unlikely(invalid)) {
return 0; /* doesnt matter */
return 0; /* doesn't matter */
} else if (dig_a > dig_b) {
return 1;
} else if (dig_a < dig_b) {

File diff suppressed because it is too large Load Diff

View File

@@ -39,33 +39,33 @@ typedef enum {
#define TCG_TARGET_CALL_STACK_OFFSET 0
/* optional instructions */
#define TCG_TARGET_HAS_div_i32 0
#define TCG_TARGET_HAS_rem_i32 0
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 0
#define TCG_TARGET_HAS_neg_i32 0
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_neg_i32 1
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_andc_i32 0
#define TCG_TARGET_HAS_orc_i32 0
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_eqv_i32 1
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
#define TCG_TARGET_HAS_deposit_i32 0
#define TCG_TARGET_HAS_movcond_i32 0
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
#define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_movcond_i32 1
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_div_i64 0
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
@@ -75,22 +75,22 @@ typedef enum {
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_not_i64 0
#define TCG_TARGET_HAS_neg_i64 0
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_neg_i64 1
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_andc_i64 0
#define TCG_TARGET_HAS_orc_i64 0
#define TCG_TARGET_HAS_eqv_i64 0
#define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_eqv_i64 1
#define TCG_TARGET_HAS_nand_i64 0
#define TCG_TARGET_HAS_nor_i64 0
#define TCG_TARGET_HAS_deposit_i64 0
#define TCG_TARGET_HAS_movcond_i64 0
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
#define TCG_TARGET_HAS_deposit_i64 1
#define TCG_TARGET_HAS_movcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
enum {
TCG_AREG0 = TCG_REG_X19,

View File

@@ -384,37 +384,47 @@ static inline void tcg_out_movi_imm13(TCGContext *s, int ret, uint32_t arg)
tcg_out_arithi(s, ret, TCG_REG_G0, arg, ARITH_OR);
}
static inline void tcg_out_movi_imm32(TCGContext *s, int ret, uint32_t arg)
static void tcg_out_movi(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
{
if (check_fit_tl(arg, 13))
tcg_out_movi_imm13(s, ret, arg);
else {
tcg_out_sethi(s, ret, arg);
if (arg & 0x3ff)
tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
}
}
tcg_target_long hi, lo;
static inline void tcg_out_movi(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
{
/* All 32-bit constants, as well as 64-bit constants with
no high bits set go through movi_imm32. */
/* A 13-bit constant sign-extended to 64-bits. */
if (check_fit_tl(arg, 13)) {
tcg_out_movi_imm13(s, ret, arg);
return;
}
/* A 32-bit constant, or 32-bit zero-extended to 64-bits. */
if (TCG_TARGET_REG_BITS == 32
|| type == TCG_TYPE_I32
|| (arg & ~(tcg_target_long)0xffffffff) == 0) {
tcg_out_movi_imm32(s, ret, arg);
} else if (check_fit_tl(arg, 13)) {
/* A 13-bit constant sign-extended to 64-bits. */
tcg_out_movi_imm13(s, ret, arg);
} else if (check_fit_tl(arg, 32)) {
/* A 32-bit constant sign-extended to 64-bits. */
|| (arg & ~0xffffffffu) == 0) {
tcg_out_sethi(s, ret, arg);
if (arg & 0x3ff) {
tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
}
return;
}
/* A 32-bit constant sign-extended to 64-bits. */
if (check_fit_tl(arg, 32)) {
tcg_out_sethi(s, ret, ~arg);
tcg_out_arithi(s, ret, ret, (arg & 0x3ff) | -0x400, ARITH_XOR);
} else {
tcg_out_movi_imm32(s, ret, arg >> (TCG_TARGET_REG_BITS / 2));
return;
}
/* A 64-bit constant decomposed into 2 32-bit pieces. */
lo = (int32_t)arg;
if (check_fit_tl(lo, 13)) {
hi = (arg - lo) >> 31 >> 1;
tcg_out_movi(s, TCG_TYPE_I32, ret, hi);
tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);
tcg_out_arithi(s, ret, ret, lo, ARITH_ADD);
} else {
hi = arg >> 31 >> 1;
tcg_out_movi(s, TCG_TYPE_I32, ret, hi);
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T2, lo);
tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);
tcg_out_movi_imm32(s, TCG_REG_T2, arg);
tcg_out_arith(s, ret, ret, TCG_REG_T2, ARITH_OR);
}
}
@@ -449,13 +459,14 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
tcg_out_ldst(s, arg, arg1, arg2, (type == TCG_TYPE_I32 ? STW : STX));
}
static inline void tcg_out_ld_ptr(TCGContext *s, int ret,
tcg_target_long arg)
static inline void tcg_out_ld_ptr(TCGContext *s, TCGReg ret, uintptr_t arg)
{
TCGReg base = TCG_REG_G0;
if (!check_fit_tl(arg, 10)) {
tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ff);
base = ret;
}
tcg_out_ld(s, TCG_TYPE_PTR, ret, ret, arg & 0x3ff);
tcg_out_ld(s, TCG_TYPE_PTR, ret, base, arg & 0x3ff);
}
static inline void tcg_out_sety(TCGContext *s, int rs)
@@ -480,19 +491,6 @@ static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
}
}
static inline void tcg_out_andi(TCGContext *s, int rd, int rs,
tcg_target_long val)
{
if (val != 0) {
if (check_fit_tl(val, 13))
tcg_out_arithi(s, rd, rs, val, ARITH_AND);
else {
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T1, val);
tcg_out_arith(s, rd, rs, TCG_REG_T1, ARITH_AND);
}
}
}
static void tcg_out_div32(TCGContext *s, int rd, int rs1,
int val2, int val2const, int uns)
{
@@ -796,6 +794,110 @@ static void tcg_out_addsub2(TCGContext *s, TCGArg rl, TCGArg rh,
tcg_out_mov(s, TCG_TYPE_I32, rl, tmp);
}
static inline void tcg_out_calli(TCGContext *s, uintptr_t dest)
{
intptr_t disp = dest - (uintptr_t)s->code_ptr;
if (disp == (int32_t)disp) {
tcg_out32(s, CALL | (uint32_t)disp >> 2);
} else {
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, dest & ~0xfff);
tcg_out_arithi(s, TCG_REG_O7, TCG_REG_T1, dest & 0xfff, JMPL);
}
}
#ifdef CONFIG_SOFTMMU
static uintptr_t qemu_ld_trampoline[16];
static uintptr_t qemu_st_trampoline[16];
static void build_trampolines(TCGContext *s)
{
static uintptr_t const qemu_ld_helpers[16] = {
[MO_UB] = (uintptr_t)helper_ret_ldub_mmu,
[MO_SB] = (uintptr_t)helper_ret_ldsb_mmu,
[MO_LEUW] = (uintptr_t)helper_le_lduw_mmu,
[MO_LESW] = (uintptr_t)helper_le_ldsw_mmu,
[MO_LEUL] = (uintptr_t)helper_le_ldul_mmu,
[MO_LEQ] = (uintptr_t)helper_le_ldq_mmu,
[MO_BEUW] = (uintptr_t)helper_be_lduw_mmu,
[MO_BESW] = (uintptr_t)helper_be_ldsw_mmu,
[MO_BEUL] = (uintptr_t)helper_be_ldul_mmu,
[MO_BEQ] = (uintptr_t)helper_be_ldq_mmu,
};
static uintptr_t const qemu_st_helpers[16] = {
[MO_UB] = (uintptr_t)helper_ret_stb_mmu,
[MO_LEUW] = (uintptr_t)helper_le_stw_mmu,
[MO_LEUL] = (uintptr_t)helper_le_stl_mmu,
[MO_LEQ] = (uintptr_t)helper_le_stq_mmu,
[MO_BEUW] = (uintptr_t)helper_be_stw_mmu,
[MO_BEUL] = (uintptr_t)helper_be_stl_mmu,
[MO_BEQ] = (uintptr_t)helper_be_stq_mmu,
};
int i;
TCGReg ra;
uintptr_t tramp;
for (i = 0; i < 16; ++i) {
if (qemu_ld_helpers[i] == 0) {
continue;
}
/* May as well align the trampoline. */
tramp = (uintptr_t)s->code_ptr;
while (tramp & 15) {
tcg_out_nop(s);
tramp += 4;
}
qemu_ld_trampoline[i] = tramp;
/* Find the retaddr argument register. */
ra = TCG_REG_O3 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
/* Set the retaddr operand. */
tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
/* Set the env operand. */
tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);
/* Tail call. */
tcg_out_calli(s, qemu_ld_helpers[i]);
tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);
}
for (i = 0; i < 16; ++i) {
if (qemu_st_helpers[i] == 0) {
continue;
}
/* May as well align the trampoline. */
tramp = (uintptr_t)s->code_ptr;
while (tramp & 15) {
tcg_out_nop(s);
tramp += 4;
}
qemu_st_trampoline[i] = tramp;
/* Find the retaddr argument. For 32-bit, this may be past the
last argument register, and need passing on the stack. */
ra = (TCG_REG_O4
+ (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)
+ (TCG_TARGET_REG_BITS == 32 && (i & MO_SIZE) == MO_64));
/* Set the retaddr operand. */
if (ra >= TCG_REG_O6) {
tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_O7, TCG_REG_CALL_STACK,
TCG_TARGET_CALL_STACK_OFFSET);
ra = TCG_REG_G1;
}
tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
/* Set the env operand. */
tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);
/* Tail call. */
tcg_out_calli(s, qemu_st_helpers[i]);
tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);
}
}
#endif
/* Generate global QEMU prologue and epilogue code */
static void tcg_target_qemu_prologue(TCGContext *s)
{
@@ -823,39 +925,22 @@ static void tcg_target_qemu_prologue(TCGContext *s)
}
#endif
tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) |
INSN_RS2(TCG_REG_G0));
tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I1, 0, JMPL);
/* delay slot */
tcg_out_nop(s);
/* No epilogue required. We issue ret + restore directly in the TB. */
#ifdef CONFIG_SOFTMMU
build_trampolines(s);
#endif
}
#if defined(CONFIG_SOFTMMU)
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
int mmu_idx) */
static const void * const qemu_ld_helpers[4] = {
helper_ldb_mmu,
helper_ldw_mmu,
helper_ldl_mmu,
helper_ldq_mmu,
};
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
uintxx_t val, int mmu_idx) */
static const void * const qemu_st_helpers[4] = {
helper_stb_mmu,
helper_stw_mmu,
helper_stl_mmu,
helper_stq_mmu,
};
/* Perform the TLB load and compare.
Inputs:
ADDRLO_IDX contains the index into ARGS of the low part of the
address; the high part of the address is at ADDR_LOW_IDX+1.
ADDRLO and ADDRHI contain the possible two parts of the address.
MEM_INDEX and S_BITS are the memory context and log2 size of the load.
@@ -865,32 +950,38 @@ static const void * const qemu_st_helpers[4] = {
The result of the TLB comparison is in %[ix]cc. The sanitized address
is in the returned register, maybe %o0. The TLB addend is in %o1. */
static int tcg_out_tlb_load(TCGContext *s, int addrlo_idx, int mem_index,
int s_bits, const TCGArg *args, int which)
static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addrlo, TCGReg addrhi,
int mem_index, TCGMemOp s_bits, int which)
{
const int addrlo = args[addrlo_idx];
const int r0 = TCG_REG_O0;
const int r1 = TCG_REG_O1;
const int r2 = TCG_REG_O2;
int addr = addrlo;
const TCGReg r0 = TCG_REG_O0;
const TCGReg r1 = TCG_REG_O1;
const TCGReg r2 = TCG_REG_O2;
TCGReg addr = addrlo;
int tlb_ofs;
if (TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 64) {
/* Assemble the 64-bit address in R0. */
tcg_out_arithi(s, r0, addrlo, 0, SHIFT_SRL);
tcg_out_arithi(s, r1, args[addrlo_idx + 1], 32, SHIFT_SLLX);
tcg_out_arithi(s, r1, addrhi, 32, SHIFT_SLLX);
tcg_out_arith(s, r0, r0, r1, ARITH_OR);
addr = r0;
}
/* Shift the page number down to tlb-entry. */
tcg_out_arithi(s, r1, addrlo,
TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS, SHIFT_SRL);
/* Shift the page number down. */
tcg_out_arithi(s, r1, addrlo, TARGET_PAGE_BITS, SHIFT_SRL);
/* Mask out the page offset, except for the required alignment. */
tcg_out_andi(s, r0, addr, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_T1,
TARGET_PAGE_MASK | ((1 << s_bits) - 1));
/* Compute tlb index, modulo tlb size. */
tcg_out_andi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
/* Mask the tlb index. */
tcg_out_arithi(s, r1, r1, CPU_TLB_SIZE - 1, ARITH_AND);
/* Mask page, part 2. */
tcg_out_arith(s, r0, addr, TCG_REG_T1, ARITH_AND);
/* Shift the tlb index into place. */
tcg_out_arithi(s, r1, r1, CPU_TLB_ENTRY_BITS, SHIFT_SLL);
/* Relative to the current ENV. */
tcg_out_arith(s, r1, TCG_AREG0, r1, ARITH_ADD);
@@ -898,8 +989,8 @@ static int tcg_out_tlb_load(TCGContext *s, int addrlo_idx, int mem_index,
/* Find a base address that can load both tlb comparator and addend. */
tlb_ofs = offsetof(CPUArchState, tlb_table[mem_index][0]);
if (!check_fit_tl(tlb_ofs + sizeof(CPUTLBEntry), 13)) {
tcg_out_addi(s, r1, tlb_ofs);
tlb_ofs = 0;
tcg_out_addi(s, r1, tlb_ofs & ~0x3ff);
tlb_ofs &= 0x3ff;
}
/* Load the tlb comparator and the addend. */
@@ -918,56 +1009,71 @@ static int tcg_out_tlb_load(TCGContext *s, int addrlo_idx, int mem_index,
}
#endif /* CONFIG_SOFTMMU */
static const int qemu_ld_opc[8] = {
#ifdef TARGET_WORDS_BIGENDIAN
LDUB, LDUH, LDUW, LDX, LDSB, LDSH, LDSW, LDX
#else
LDUB, LDUH_LE, LDUW_LE, LDX_LE, LDSB, LDSH_LE, LDSW_LE, LDX_LE
#endif
static const int qemu_ld_opc[16] = {
[MO_UB] = LDUB,
[MO_SB] = LDSB,
[MO_BEUW] = LDUH,
[MO_BESW] = LDSH,
[MO_BEUL] = LDUW,
[MO_BESL] = LDSW,
[MO_BEQ] = LDX,
[MO_LEUW] = LDUH_LE,
[MO_LESW] = LDSH_LE,
[MO_LEUL] = LDUW_LE,
[MO_LESL] = LDSW_LE,
[MO_LEQ] = LDX_LE,
};
static const int qemu_st_opc[4] = {
#ifdef TARGET_WORDS_BIGENDIAN
STB, STH, STW, STX
#else
STB, STH_LE, STW_LE, STX_LE
#endif
static const int qemu_st_opc[16] = {
[MO_UB] = STB,
[MO_BEUW] = STH,
[MO_BEUL] = STW,
[MO_BEQ] = STX,
[MO_LEUW] = STH_LE,
[MO_LEUL] = STW_LE,
[MO_LEQ] = STX_LE,
};
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
{
int addrlo_idx = 1, datalo, datahi, addr_reg;
TCGReg addrlo, datalo, datahi, addrhi __attribute__((unused));
TCGMemOp memop, s_bits;
#if defined(CONFIG_SOFTMMU)
int memi_idx, memi, s_bits, n;
TCGReg addrz, param;
uintptr_t func;
int memi;
uint32_t *label_ptr[2];
#endif
datahi = datalo = args[0];
if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
datahi = args[1];
addrlo_idx = 2;
}
datalo = *args++;
datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0);
addrlo = *args++;
addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
memop = *args++;
s_bits = memop & MO_SIZE;
#if defined(CONFIG_SOFTMMU)
memi_idx = addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
memi = args[memi_idx];
s_bits = sizeop & 3;
memi = *args++;
addrz = tcg_out_tlb_load(s, addrlo, addrhi, memi, s_bits,
offsetof(CPUTLBEntry, addr_read));
addr_reg = tcg_out_tlb_load(s, addrlo_idx, memi, s_bits, args,
offsetof(CPUTLBEntry, addr_read));
if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
int reg64;
/* bne,pn %[xi]cc, label0 */
label_ptr[0] = (uint32_t *)s->code_ptr;
tcg_out_bpcc0(s, COND_NE, BPCC_PN
| (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
tcg_out_nop(s);
/* TLB Hit. */
/* Load all 64-bits into an O/G register. */
reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
tcg_out_ldst_rr(s, reg64, addr_reg, TCG_REG_O1, qemu_ld_opc[sizeop]);
tcg_out_ldst_rr(s, reg64, addrz, TCG_REG_O1, qemu_ld_opc[memop]);
/* Move the two 32-bit pieces into the destination registers. */
tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
@@ -989,7 +1095,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
| (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
/* delay slot */
tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_O1, qemu_ld_opc[sizeop]);
tcg_out_ldst_rr(s, datalo, addrz, TCG_REG_O1, qemu_ld_opc[memop]);
}
/* TLB Miss. */
@@ -998,103 +1104,93 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
*label_ptr[0] |= INSN_OFF19((unsigned long)s->code_ptr -
(unsigned long)label_ptr[0]);
}
n = 0;
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[n++], TCG_AREG0);
param = TCG_REG_O1;
if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
args[addrlo_idx + 1]);
tcg_out_mov(s, TCG_TYPE_REG, param++, addrhi);
}
tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
args[addrlo_idx]);
tcg_out_mov(s, TCG_TYPE_REG, param++, addrlo);
/* qemu_ld_helper[s_bits](arg0, arg1) */
tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits]
- (tcg_target_ulong)s->code_ptr) >> 2)
& 0x3fffffff));
/* We use the helpers to extend SB and SW data, leaving the case
of SL needing explicit extending below. */
if ((memop & ~MO_BSWAP) == MO_SL) {
func = qemu_ld_trampoline[memop & ~MO_SIGN];
} else {
func = qemu_ld_trampoline[memop];
}
assert(func != 0);
tcg_out_calli(s, func);
/* delay slot */
tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[n], memi);
tcg_out_movi(s, TCG_TYPE_I32, param, memi);
n = tcg_target_call_oarg_regs[0];
/* datalo = sign_extend(arg0) */
switch (sizeop) {
case 0 | 4:
/* Recall that SRA sign extends from bit 31 through bit 63. */
tcg_out_arithi(s, datalo, n, 24, SHIFT_SLL);
tcg_out_arithi(s, datalo, datalo, 24, SHIFT_SRA);
switch (memop & ~MO_BSWAP) {
case MO_SL:
tcg_out_arithi(s, datalo, TCG_REG_O0, 0, SHIFT_SRA);
break;
case 1 | 4:
tcg_out_arithi(s, datalo, n, 16, SHIFT_SLL);
tcg_out_arithi(s, datalo, datalo, 16, SHIFT_SRA);
break;
case 2 | 4:
tcg_out_arithi(s, datalo, n, 0, SHIFT_SRA);
break;
case 3:
case MO_Q:
if (TCG_TARGET_REG_BITS == 32) {
tcg_out_mov(s, TCG_TYPE_REG, datahi, n);
tcg_out_mov(s, TCG_TYPE_REG, datalo, n + 1);
tcg_out_mov(s, TCG_TYPE_REG, datahi, TCG_REG_O0);
tcg_out_mov(s, TCG_TYPE_REG, datalo, TCG_REG_O1);
break;
}
/* FALLTHRU */
case 0:
case 1:
case 2:
default:
/* mov */
tcg_out_mov(s, TCG_TYPE_REG, datalo, n);
tcg_out_mov(s, TCG_TYPE_REG, datalo, TCG_REG_O0);
break;
}
*label_ptr[1] |= INSN_OFF19((unsigned long)s->code_ptr -
(unsigned long)label_ptr[1]);
#else
addr_reg = args[addrlo_idx];
if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
tcg_out_arithi(s, TCG_REG_T1, addr_reg, 0, SHIFT_SRL);
addr_reg = TCG_REG_T1;
tcg_out_arithi(s, TCG_REG_T1, addrlo, 0, SHIFT_SRL);
addrlo = TCG_REG_T1;
}
if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
int reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
tcg_out_ldst_rr(s, reg64, addr_reg,
tcg_out_ldst_rr(s, reg64, addrlo,
(GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
qemu_ld_opc[sizeop]);
qemu_ld_opc[memop]);
tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
if (reg64 != datalo) {
tcg_out_mov(s, TCG_TYPE_I32, datalo, reg64);
}
} else {
tcg_out_ldst_rr(s, datalo, addr_reg,
tcg_out_ldst_rr(s, datalo, addrlo,
(GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
qemu_ld_opc[sizeop]);
qemu_ld_opc[memop]);
}
#endif /* CONFIG_SOFTMMU */
}
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
{
int addrlo_idx = 1, datalo, datahi, addr_reg;
TCGReg addrlo, datalo, datahi, addrhi __attribute__((unused));
TCGMemOp memop, s_bits;
#if defined(CONFIG_SOFTMMU)
int memi_idx, memi, n, datafull;
TCGReg addrz, datafull, param;
uintptr_t func;
int memi;
uint32_t *label_ptr;
#endif
datahi = datalo = args[0];
if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
datahi = args[1];
addrlo_idx = 2;
}
datalo = *args++;
datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0);
addrlo = *args++;
addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
memop = *args++;
s_bits = memop & MO_SIZE;
#if defined(CONFIG_SOFTMMU)
memi_idx = addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
memi = args[memi_idx];
addr_reg = tcg_out_tlb_load(s, addrlo_idx, memi, sizeop, args,
offsetof(CPUTLBEntry, addr_write));
memi = *args++;
addrz = tcg_out_tlb_load(s, addrlo, addrhi, memi, s_bits,
offsetof(CPUTLBEntry, addr_write));
datafull = datalo;
if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
/* Reconstruct the full 64-bit value. */
tcg_out_arithi(s, TCG_REG_T1, datalo, 0, SHIFT_SRL);
tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
@@ -1109,47 +1205,42 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
| (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
/* delay slot */
tcg_out_ldst_rr(s, datafull, addr_reg, TCG_REG_O1, qemu_st_opc[sizeop]);
tcg_out_ldst_rr(s, datafull, addrz, TCG_REG_O1, qemu_st_opc[memop]);
/* TLB Miss. */
n = 0;
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[n++], TCG_AREG0);
param = TCG_REG_O1;
if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
args[addrlo_idx + 1]);
tcg_out_mov(s, TCG_TYPE_REG, param++, addrhi);
}
tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
args[addrlo_idx]);
if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], datahi);
tcg_out_mov(s, TCG_TYPE_REG, param++, addrlo);
if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
tcg_out_mov(s, TCG_TYPE_REG, param++, datahi);
}
tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], datalo);
tcg_out_mov(s, TCG_TYPE_REG, param++, datalo);
/* qemu_st_helper[s_bits](arg0, arg1, arg2) */
tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[sizeop]
- (tcg_target_ulong)s->code_ptr) >> 2)
& 0x3fffffff));
func = qemu_st_trampoline[memop];
assert(func != 0);
tcg_out_calli(s, func);
/* delay slot */
tcg_out_movi(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n], memi);
tcg_out_movi(s, TCG_TYPE_REG, param, memi);
*label_ptr |= INSN_OFF19((unsigned long)s->code_ptr -
(unsigned long)label_ptr);
#else
addr_reg = args[addrlo_idx];
if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
tcg_out_arithi(s, TCG_REG_T1, addr_reg, 0, SHIFT_SRL);
addr_reg = TCG_REG_T1;
tcg_out_arithi(s, TCG_REG_T1, addrlo, 0, SHIFT_SRL);
addrlo = TCG_REG_T1;
}
if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
tcg_out_arithi(s, TCG_REG_T1, datalo, 0, SHIFT_SRL);
tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
tcg_out_arith(s, TCG_REG_O2, TCG_REG_T1, TCG_REG_O2, ARITH_OR);
datalo = TCG_REG_O2;
}
tcg_out_ldst_rr(s, datalo, addr_reg,
tcg_out_ldst_rr(s, datalo, addrlo,
(GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
qemu_st_opc[sizeop]);
qemu_st_opc[memop]);
#endif /* CONFIG_SOFTMMU */
}
@@ -1161,8 +1252,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
switch (opc) {
case INDEX_op_exit_tb:
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, args[0]);
tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I7) |
INSN_IMM13(8));
tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, JMPL);
tcg_out32(s, RESTORE | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_G0) |
INSN_RS2(TCG_REG_G0));
break;
@@ -1175,24 +1265,17 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
tcg_out32(s, CALL | (old_insn & ~INSN_OP(-1)));
} else {
/* indirect jump method */
tcg_out_ld_ptr(s, TCG_REG_T1,
(tcg_target_long)(s->tb_next + args[0]));
tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_T1) |
INSN_RS2(TCG_REG_G0));
tcg_out_ld_ptr(s, TCG_REG_T1, (uintptr_t)(s->tb_next + args[0]));
tcg_out_arithi(s, TCG_REG_G0, TCG_REG_T1, 0, JMPL);
}
tcg_out_nop(s);
s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
break;
case INDEX_op_call:
if (const_args[0]) {
tcg_out32(s, CALL | ((((tcg_target_ulong)args[0]
- (tcg_target_ulong)s->code_ptr) >> 2)
& 0x3fffffff));
tcg_out_calli(s, args[0]);
} else {
tcg_out_ld_ptr(s, TCG_REG_T1,
(tcg_target_long)(s->tb_next + args[0]));
tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_T1) |
INSN_RS2(TCG_REG_G0));
tcg_out_arithi(s, TCG_REG_O7, args[0], 0, JMPL);
}
/* delay slot */
tcg_out_nop(s);
@@ -1294,15 +1377,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 1);
break;
case INDEX_op_rem_i32:
case INDEX_op_remu_i32:
tcg_out_div32(s, TCG_REG_T1, args[1], args[2], const_args[2],
opc == INDEX_op_remu_i32);
tcg_out_arithc(s, TCG_REG_T1, TCG_REG_T1, args[2], const_args[2],
ARITH_UMUL);
tcg_out_arith(s, args[0], args[1], TCG_REG_T1, ARITH_SUB);
break;
case INDEX_op_brcond_i32:
tcg_out_brcond_i32(s, args[2], args[0], args[1], const_args[1],
args[3]);
@@ -1345,44 +1419,18 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
tcg_out_rdy(s, args[1]);
break;
case INDEX_op_qemu_ld8u:
case INDEX_op_qemu_ld_i32:
tcg_out_qemu_ld(s, args, 0);
break;
case INDEX_op_qemu_ld8s:
tcg_out_qemu_ld(s, args, 0 | 4);
break;
case INDEX_op_qemu_ld16u:
case INDEX_op_qemu_ld_i64:
tcg_out_qemu_ld(s, args, 1);
break;
case INDEX_op_qemu_ld16s:
tcg_out_qemu_ld(s, args, 1 | 4);
break;
case INDEX_op_qemu_ld32:
#if TCG_TARGET_REG_BITS == 64
case INDEX_op_qemu_ld32u:
#endif
tcg_out_qemu_ld(s, args, 2);
break;
#if TCG_TARGET_REG_BITS == 64
case INDEX_op_qemu_ld32s:
tcg_out_qemu_ld(s, args, 2 | 4);
break;
#endif
case INDEX_op_qemu_ld64:
tcg_out_qemu_ld(s, args, 3);
break;
case INDEX_op_qemu_st8:
case INDEX_op_qemu_st_i32:
tcg_out_qemu_st(s, args, 0);
break;
case INDEX_op_qemu_st16:
case INDEX_op_qemu_st_i64:
tcg_out_qemu_st(s, args, 1);
break;
case INDEX_op_qemu_st32:
tcg_out_qemu_st(s, args, 2);
break;
case INDEX_op_qemu_st64:
tcg_out_qemu_st(s, args, 3);
break;
#if TCG_TARGET_REG_BITS == 64
case INDEX_op_movi_i64:
@@ -1418,27 +1466,11 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
case INDEX_op_divu_i64:
c = ARITH_UDIVX;
goto gen_arith;
case INDEX_op_rem_i64:
case INDEX_op_remu_i64:
tcg_out_arithc(s, TCG_REG_T1, args[1], args[2], const_args[2],
opc == INDEX_op_rem_i64 ? ARITH_SDIVX : ARITH_UDIVX);
tcg_out_arithc(s, TCG_REG_T1, TCG_REG_T1, args[2], const_args[2],
ARITH_MULX);
tcg_out_arith(s, args[0], args[1], TCG_REG_T1, ARITH_SUB);
break;
case INDEX_op_ext32s_i64:
if (const_args[1]) {
tcg_out_movi(s, TCG_TYPE_I64, args[0], (int32_t)args[1]);
} else {
tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRA);
}
tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRA);
break;
case INDEX_op_ext32u_i64:
if (const_args[1]) {
tcg_out_movi_imm32(s, args[0], args[1]);
} else {
tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRL);
}
tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRL);
break;
case INDEX_op_brcond_i64:
@@ -1489,8 +1521,6 @@ static const TCGTargetOpDef sparc_op_defs[] = {
{ INDEX_op_mul_i32, { "r", "rZ", "rJ" } },
{ INDEX_op_div_i32, { "r", "rZ", "rJ" } },
{ INDEX_op_divu_i32, { "r", "rZ", "rJ" } },
{ INDEX_op_rem_i32, { "r", "rZ", "rJ" } },
{ INDEX_op_remu_i32, { "r", "rZ", "rJ" } },
{ INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
{ INDEX_op_and_i32, { "r", "rZ", "rJ" } },
{ INDEX_op_andc_i32, { "r", "rZ", "rJ" } },
@@ -1537,8 +1567,6 @@ static const TCGTargetOpDef sparc_op_defs[] = {
{ INDEX_op_mul_i64, { "r", "rZ", "rJ" } },
{ INDEX_op_div_i64, { "r", "rZ", "rJ" } },
{ INDEX_op_divu_i64, { "r", "rZ", "rJ" } },
{ INDEX_op_rem_i64, { "r", "rZ", "rJ" } },
{ INDEX_op_remu_i64, { "r", "rZ", "rJ" } },
{ INDEX_op_sub_i64, { "r", "rZ", "rJ" } },
{ INDEX_op_and_i64, { "r", "rZ", "rJ" } },
{ INDEX_op_andc_i64, { "r", "rZ", "rJ" } },
@@ -1553,8 +1581,8 @@ static const TCGTargetOpDef sparc_op_defs[] = {
{ INDEX_op_neg_i64, { "r", "rJ" } },
{ INDEX_op_not_i64, { "r", "rJ" } },
{ INDEX_op_ext32s_i64, { "r", "ri" } },
{ INDEX_op_ext32u_i64, { "r", "ri" } },
{ INDEX_op_ext32s_i64, { "r", "r" } },
{ INDEX_op_ext32u_i64, { "r", "r" } },
{ INDEX_op_brcond_i64, { "rZ", "rJ" } },
{ INDEX_op_setcond_i64, { "r", "rZ", "rJ" } },
@@ -1562,43 +1590,20 @@ static const TCGTargetOpDef sparc_op_defs[] = {
#endif
#if TCG_TARGET_REG_BITS == 64
{ INDEX_op_qemu_ld8u, { "r", "L" } },
{ INDEX_op_qemu_ld8s, { "r", "L" } },
{ INDEX_op_qemu_ld16u, { "r", "L" } },
{ INDEX_op_qemu_ld16s, { "r", "L" } },
{ INDEX_op_qemu_ld32, { "r", "L" } },
{ INDEX_op_qemu_ld32u, { "r", "L" } },
{ INDEX_op_qemu_ld32s, { "r", "L" } },
{ INDEX_op_qemu_ld64, { "r", "L" } },
{ INDEX_op_qemu_st8, { "L", "L" } },
{ INDEX_op_qemu_st16, { "L", "L" } },
{ INDEX_op_qemu_st32, { "L", "L" } },
{ INDEX_op_qemu_st64, { "L", "L" } },
{ INDEX_op_qemu_ld_i32, { "r", "L" } },
{ INDEX_op_qemu_ld_i64, { "r", "L" } },
{ INDEX_op_qemu_st_i32, { "L", "L" } },
{ INDEX_op_qemu_st_i64, { "L", "L" } },
#elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
{ INDEX_op_qemu_ld8u, { "r", "L" } },
{ INDEX_op_qemu_ld8s, { "r", "L" } },
{ INDEX_op_qemu_ld16u, { "r", "L" } },
{ INDEX_op_qemu_ld16s, { "r", "L" } },
{ INDEX_op_qemu_ld32, { "r", "L" } },
{ INDEX_op_qemu_ld64, { "r", "r", "L" } },
{ INDEX_op_qemu_st8, { "L", "L" } },
{ INDEX_op_qemu_st16, { "L", "L" } },
{ INDEX_op_qemu_st32, { "L", "L" } },
{ INDEX_op_qemu_st64, { "L", "L", "L" } },
{ INDEX_op_qemu_ld_i32, { "r", "L" } },
{ INDEX_op_qemu_ld_i64, { "r", "r", "L" } },
{ INDEX_op_qemu_st_i32, { "L", "L" } },
{ INDEX_op_qemu_st_i64, { "L", "L", "L" } },
#else
{ INDEX_op_qemu_ld8u, { "r", "L", "L" } },
{ INDEX_op_qemu_ld8s, { "r", "L", "L" } },
{ INDEX_op_qemu_ld16u, { "r", "L", "L" } },
{ INDEX_op_qemu_ld16s, { "r", "L", "L" } },
{ INDEX_op_qemu_ld32, { "r", "L", "L" } },
{ INDEX_op_qemu_ld64, { "L", "L", "L", "L" } },
{ INDEX_op_qemu_st8, { "L", "L", "L" } },
{ INDEX_op_qemu_st16, { "L", "L", "L" } },
{ INDEX_op_qemu_st32, { "L", "L", "L" } },
{ INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
{ INDEX_op_qemu_ld_i32, { "r", "L", "L" } },
{ INDEX_op_qemu_ld_i64, { "L", "L", "L", "L" } },
{ INDEX_op_qemu_st_i32, { "L", "L", "L" } },
{ INDEX_op_qemu_st_i64, { "L", "L", "L", "L" } },
#endif
{ -1 },
@@ -1679,7 +1684,7 @@ static DebugFrame debug_frame = {
void tcg_register_jit(void *buf, size_t buf_size)
{
debug_frame.fde.func_start = (tcg_target_long) buf;
debug_frame.fde.func_start = (uintptr_t)buf;
debug_frame.fde.func_len = buf_size;
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
@@ -1688,14 +1693,12 @@ void tcg_register_jit(void *buf, size_t buf_size)
void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
{
uint32_t *ptr = (uint32_t *)jmp_addr;
tcg_target_long disp = (tcg_target_long)(addr - jmp_addr) >> 2;
uintptr_t disp = addr - jmp_addr;
/* We can reach the entire address space for 32-bit. For 64-bit
the code_gen_buffer can't be larger than 2GB. */
if (TCG_TARGET_REG_BITS == 64 && !check_fit_tl(disp, 30)) {
tcg_abort();
}
assert(disp == (int32_t)disp);
*ptr = CALL | (disp & 0x3fffffff);
*ptr = CALL | (uint32_t)disp >> 2;
flush_icache_range(jmp_addr, jmp_addr + 4);
}

View File

@@ -94,7 +94,7 @@ typedef enum {
/* optional instructions */
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 1
#define TCG_TARGET_HAS_rem_i32 0
#define TCG_TARGET_HAS_rot_i32 0
#define TCG_TARGET_HAS_ext8s_i32 0
#define TCG_TARGET_HAS_ext16s_i32 0
@@ -120,7 +120,7 @@ typedef enum {
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_rot_i64 0
#define TCG_TARGET_HAS_ext8s_i64 0
#define TCG_TARGET_HAS_ext16s_i64 0
@@ -148,7 +148,7 @@ typedef enum {
#define TCG_TARGET_HAS_mulsh_i64 0
#endif
#define TCG_TARGET_HAS_new_ldst 0
#define TCG_TARGET_HAS_new_ldst 1
#define TCG_AREG0 TCG_REG_I0

129
tests/qemu-iotests/083 Executable file
View File

@@ -0,0 +1,129 @@
#!/bin/bash
#
# Test NBD client unexpected disconnect
#
# Copyright Red Hat, Inc. 2014
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# creator
owner=stefanha@redhat.com
seq=`basename $0`
echo "QA output created by $seq"
here=`pwd`
tmp=/tmp/$$
status=1 # failure is the default!
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
_supported_fmt generic
_supported_proto nbd
_supported_os Linux
# Pick a TCP port based on our pid. This way multiple instances of this test
# can run in parallel without conflicting.
choose_tcp_port() {
echo $((($$ % 31744) + 1024)) # 1024 <= port < 32768
}
wait_for_tcp_port() {
while ! (netstat --tcp --listening --numeric | \
grep "$1.*0.0.0.0:\*.*LISTEN") 2>&1 >/dev/null; do
sleep 0.1
done
}
filter_nbd() {
# nbd.c error messages contain function names and line numbers that are prone
# to change. Message ordering depends on timing between send and receive
# callbacks sometimes, making them unreliable.
#
# Filter out the TCP port number since this changes between runs.
sed -e 's#^nbd.c:.*##g' \
-e 's#nbd:127.0.0.1:[^:]*:#nbd:127.0.0.1:PORT:#g'
}
check_disconnect() {
event=$1
when=$2
negotiation=$3
echo "=== Check disconnect $when $event ==="
echo
port=$(choose_tcp_port)
cat > "$TEST_DIR/nbd-fault-injector.conf" <<EOF
[inject-error]
event=$event
when=$when
EOF
if [ "$negotiation" = "--classic-negotiation" ]; then
extra_args=--classic-negotiation
nbd_url="nbd:127.0.0.1:$port"
else
nbd_url="nbd:127.0.0.1:$port:exportname=foo"
fi
./nbd-fault-injector.py $extra_args "127.0.0.1:$port" "$TEST_DIR/nbd-fault-injector.conf" 2>&1 >/dev/null &
wait_for_tcp_port "127.0.0.1:$port"
$QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | filter_nbd
echo
}
for event in neg1 "export" neg2 request reply data; do
for when in before after; do
check_disconnect "$event" "$when"
done
# Also inject short replies from the NBD server
case "$event" in
neg1)
for when in 8 16; do
check_disconnect "$event" "$when"
done
;;
"export")
for when in 4 12 16; do
check_disconnect "$event" "$when"
done
;;
neg2)
for when in 8 10; do
check_disconnect "$event" "$when"
done
;;
reply)
for when in 4 8; do
check_disconnect "$event" "$when"
done
;;
esac
done
# Also check classic negotiation without export information
for when in before 8 16 24 28 after; do
check_disconnect "neg-classic" "$when" --classic-negotiation
done
# success, all done
echo "*** done"
rm -f $seq.full
status=0

163
tests/qemu-iotests/083.out Normal file
View File

@@ -0,0 +1,163 @@
QA output created by 083
=== Check disconnect before neg1 ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect after neg1 ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect 8 neg1 ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect 16 neg1 ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect before export ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect after export ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect 4 export ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect 12 export ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect 16 export ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect before neg2 ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect after neg2 ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
no file open, try 'help open'
=== Check disconnect 8 neg2 ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect 10 neg2 ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect before request ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
no file open, try 'help open'
=== Check disconnect after request ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
no file open, try 'help open'
=== Check disconnect before reply ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
no file open, try 'help open'
=== Check disconnect after reply ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
no file open, try 'help open'
=== Check disconnect 4 reply ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
no file open, try 'help open'
=== Check disconnect 8 reply ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
no file open, try 'help open'
=== Check disconnect before data ===
qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
no file open, try 'help open'
=== Check disconnect after data ===
read failed: Input/output error
=== Check disconnect before neg-classic ===
qemu-io: can't open device nbd:127.0.0.1:PORT: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect 8 neg-classic ===
qemu-io: can't open device nbd:127.0.0.1:PORT: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect 16 neg-classic ===
qemu-io: can't open device nbd:127.0.0.1:PORT: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect 24 neg-classic ===
qemu-io: can't open device nbd:127.0.0.1:PORT: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect 28 neg-classic ===
qemu-io: can't open device nbd:127.0.0.1:PORT: Could not open image: Invalid argument
no file open, try 'help open'
=== Check disconnect after neg-classic ===
qemu-io: can't open device nbd:127.0.0.1:PORT: Could not read image for determining its format: Input/output error
no file open, try 'help open'
*** done

View File

@@ -99,6 +99,23 @@ echo === Encrypted image ===
echo
_make_test_img -o encryption=on $size
run_qemu -S <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "blockdev-add",
"arguments": {
"options": {
"driver": "$IMGFMT",
"id": "disk",
"file": {
"driver": "file",
"filename": "$TEST_IMG"
}
}
}
}
{ "execute": "quit" }
EOF
run_qemu <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "blockdev-add",

View File

@@ -28,7 +28,7 @@ QMP_VERSION
=== Encrypted image ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
Testing:
Testing: -S
QMP_VERSION
{"return": {}}
{"error": {"class": "GenericError", "desc": "blockdev-add doesn't support encrypted devices"}}
@@ -37,4 +37,13 @@ QMP_VERSION
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
Testing:
QMP_VERSION
{"return": {}}
{"error": {"class": "GenericError", "desc": "could not open disk image disk: Guest must be stopped for opening of encrypted image"}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
*** done

View File

@@ -85,6 +85,7 @@
079 rw auto
081 rw auto
082 rw auto quick
085 rw auto quick
083 rw auto
085 rw auto
086 rw auto quick
087 rw auto quick
087 rw auto

View File

@@ -0,0 +1,264 @@
#!/usr/bin/env python
# NBD server - fault injection utility
#
# Configuration file syntax:
# [inject-error "disconnect-neg1"]
# event=neg1
# io=readwrite
# when=before
#
# Note that Python's ConfigParser squashes together all sections with the same
# name, so give each [inject-error] a unique name.
#
# inject-error options:
# event - name of the trigger event
# "neg1" - first part of negotiation struct
# "export" - export struct
# "neg2" - second part of negotiation struct
# "request" - NBD request struct
# "reply" - NBD reply struct
# "data" - request/reply data
# io - I/O direction that triggers this rule:
# "read", "write", or "readwrite"
# default: readwrite
# when - after how many bytes to inject the fault
# -1 - inject error after I/O
# 0 - inject error before I/O
# integer - inject error after integer bytes
# "before" - alias for 0
# "after" - alias for -1
# default: before
#
# Currently the only error injection action is to terminate the server process.
# This resets the TCP connection and thus forces the client to handle
# unexpected connection termination.
#
# Other error injection actions could be added in the future.
#
# Copyright Red Hat, Inc. 2014
#
# Authors:
# Stefan Hajnoczi <stefanha@redhat.com>
#
# This work is licensed under the terms of the GNU GPL, version 2 or later.
# See the COPYING file in the top-level directory.
import sys
import socket
import struct
import collections
import ConfigParser
FAKE_DISK_SIZE = 8 * 1024 * 1024 * 1024 # 8 GB
# Protocol constants
NBD_CMD_READ = 0
NBD_CMD_WRITE = 1
NBD_CMD_DISC = 2
NBD_REQUEST_MAGIC = 0x25609513
NBD_REPLY_MAGIC = 0x67446698
NBD_PASSWD = 0x4e42444d41474943
NBD_OPTS_MAGIC = 0x49484156454F5054
NBD_CLIENT_MAGIC = 0x0000420281861253
NBD_OPT_EXPORT_NAME = 1 << 0
# Protocol structs
neg_classic_struct = struct.Struct('>QQQI124x')
neg1_struct = struct.Struct('>QQH')
export_tuple = collections.namedtuple('Export', 'reserved magic opt len')
export_struct = struct.Struct('>IQII')
neg2_struct = struct.Struct('>QH124x')
request_tuple = collections.namedtuple('Request', 'magic type handle from_ len')
request_struct = struct.Struct('>IIQQI')
reply_struct = struct.Struct('>IIQ')
def err(msg):
sys.stderr.write(msg + '\n')
sys.exit(1)
def recvall(sock, bufsize):
received = 0
chunks = []
while received < bufsize:
chunk = sock.recv(bufsize - received)
if len(chunk) == 0:
raise Exception('unexpected disconnect')
chunks.append(chunk)
received += len(chunk)
return ''.join(chunks)
class Rule(object):
def __init__(self, name, event, io, when):
self.name = name
self.event = event
self.io = io
self.when = when
def match(self, event, io):
if event != self.event:
return False
if io != self.io and self.io != 'readwrite':
return False
return True
class FaultInjectionSocket(object):
def __init__(self, sock, rules):
self.sock = sock
self.rules = rules
def check(self, event, io, bufsize=None):
for rule in self.rules:
if rule.match(event, io):
if rule.when == 0 or bufsize is None:
print 'Closing connection on rule match %s' % rule.name
sys.exit(0)
if rule.when != -1:
return rule.when
return bufsize
def send(self, buf, event):
bufsize = self.check(event, 'write', bufsize=len(buf))
self.sock.sendall(buf[:bufsize])
self.check(event, 'write')
def recv(self, bufsize, event):
bufsize = self.check(event, 'read', bufsize=bufsize)
data = recvall(self.sock, bufsize)
self.check(event, 'read')
return data
def close(self):
self.sock.close()
def negotiate_classic(conn):
buf = neg_classic_struct.pack(NBD_PASSWD, NBD_CLIENT_MAGIC,
FAKE_DISK_SIZE, 0)
conn.send(buf, event='neg-classic')
def negotiate_export(conn):
# Send negotiation part 1
buf = neg1_struct.pack(NBD_PASSWD, NBD_OPTS_MAGIC, 0)
conn.send(buf, event='neg1')
# Receive export option
buf = conn.recv(export_struct.size, event='export')
export = export_tuple._make(export_struct.unpack(buf))
assert export.magic == NBD_OPTS_MAGIC
assert export.opt == NBD_OPT_EXPORT_NAME
name = conn.recv(export.len, event='export-name')
# Send negotiation part 2
buf = neg2_struct.pack(FAKE_DISK_SIZE, 0)
conn.send(buf, event='neg2')
def negotiate(conn, use_export):
'''Negotiate export with client'''
if use_export:
negotiate_export(conn)
else:
negotiate_classic(conn)
def read_request(conn):
'''Parse NBD request from client'''
buf = conn.recv(request_struct.size, event='request')
req = request_tuple._make(request_struct.unpack(buf))
assert req.magic == NBD_REQUEST_MAGIC
return req
def write_reply(conn, error, handle):
buf = reply_struct.pack(NBD_REPLY_MAGIC, error, handle)
conn.send(buf, event='reply')
def handle_connection(conn, use_export):
negotiate(conn, use_export)
while True:
req = read_request(conn)
if req.type == NBD_CMD_READ:
write_reply(conn, 0, req.handle)
conn.send('\0' * req.len, event='data')
elif req.type == NBD_CMD_WRITE:
_ = conn.recv(req.len, event='data')
write_reply(conn, 0, req.handle)
elif req.type == NBD_CMD_DISC:
break
else:
print 'unrecognized command type %#02x' % req.type
break
conn.close()
def run_server(sock, rules, use_export):
while True:
conn, _ = sock.accept()
handle_connection(FaultInjectionSocket(conn, rules), use_export)
def parse_inject_error(name, options):
if 'event' not in options:
err('missing \"event\" option in %s' % name)
event = options['event']
if event not in ('neg-classic', 'neg1', 'export', 'neg2', 'request', 'reply', 'data'):
err('invalid \"event\" option value \"%s\" in %s' % (event, name))
io = options.get('io', 'readwrite')
if io not in ('read', 'write', 'readwrite'):
err('invalid \"io\" option value \"%s\" in %s' % (io, name))
when = options.get('when', 'before')
try:
when = int(when)
except ValueError:
if when == 'before':
when = 0
elif when == 'after':
when = -1
else:
err('invalid \"when\" option value \"%s\" in %s' % (when, name))
return Rule(name, event, io, when)
def parse_config(config):
rules = []
for name in config.sections():
if name.startswith('inject-error'):
options = dict(config.items(name))
rules.append(parse_inject_error(name, options))
else:
err('invalid config section name: %s' % name)
return rules
def load_rules(filename):
config = ConfigParser.RawConfigParser()
with open(filename, 'rt') as f:
config.readfp(f, filename)
return parse_config(config)
def open_socket(path):
'''Open a TCP or UNIX domain listen socket'''
if ':' in path:
host, port = path.split(':', 1)
sock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((host, int(port)))
else:
sock = socket.socket(socket.AF_UNIX)
sock.bind(path)
sock.listen(0)
print 'Listening on %s' % path
return sock
def usage(args):
sys.stderr.write('usage: %s [--classic-negotiation] <tcp-port>|<unix-path> <config-file>\n' % args[0])
sys.stderr.write('Run an fault injector NBD server with rules defined in a config file.\n')
sys.exit(1)
def main(args):
if len(args) != 3 and len(args) != 4:
usage(args)
use_export = True
if args[1] == '--classic-negotiation':
use_export = False
elif len(args) == 4:
usage(args)
sock = open_socket(args[1 if use_export else 2])
rules = load_rules(args[2 if use_export else 3])
run_server(sock, rules, use_export)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))

View File

@@ -1,12 +1,15 @@
/* Test path override code */
#define _GNU_SOURCE
#include "config-host.h"
#include "iov.c"
#include "cutils.c"
#include "path.c"
#include "trace.c"
#include "util/cutils.c"
#include "util/hexdump.c"
#include "util/iov.c"
#include "util/path.c"
#include "util/qemu-timer-common.c"
#include "trace/control.c"
#include "../trace/generated-events.c"
#ifdef CONFIG_TRACE_SIMPLE
#include "../trace/simple.c"
#include "trace/simple.c"
#endif
#include <stdarg.h>

View File

@@ -340,13 +340,17 @@ static void gd_mouse_set(DisplayChangeListener *dcl,
GdkDeviceManager *mgr;
gint x_root, y_root;
if (qemu_input_is_absolute()) {
return;
}
dpy = gtk_widget_get_display(s->drawing_area);
mgr = gdk_display_get_device_manager(dpy);
gdk_window_get_root_coords(gtk_widget_get_window(s->drawing_area),
x, y, &x_root, &y_root);
gdk_device_warp(gdk_device_manager_get_client_pointer(mgr),
gtk_widget_get_screen(s->drawing_area),
x, y);
x_root, y_root);
}
#else
static void gd_mouse_set(DisplayChangeListener *dcl,
@@ -355,6 +359,10 @@ static void gd_mouse_set(DisplayChangeListener *dcl,
GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
gint x_root, y_root;
if (qemu_input_is_absolute()) {
return;
}
gdk_window_get_root_coords(gtk_widget_get_window(s->drawing_area),
x, y, &x_root, &y_root);
gdk_display_warp_pointer(gtk_widget_get_display(s->drawing_area),
@@ -1438,7 +1446,7 @@ static const DisplayChangeListenerOps dcl_ops = {
.dpy_cursor_define = gd_cursor_define,
};
void gtk_display_init(DisplayState *ds, bool full_screen)
void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover)
{
GtkDisplayState *s = g_malloc0(sizeof(*s));
char *filename;
@@ -1517,6 +1525,9 @@ void gtk_display_init(DisplayState *ds, bool full_screen)
if (full_screen) {
gtk_menu_item_activate(GTK_MENU_ITEM(s->full_screen_item));
}
if (grab_on_hover) {
gtk_menu_item_activate(GTK_MENU_ITEM(s->grab_on_hover_item));
}
register_displaychangelistener(&s->dcl);

View File

@@ -888,7 +888,7 @@ static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
VncDisplay *vd = vs->vd;
VncJob *job;
int y;
int height;
int height, width;
int n = 0;
if (vs->output.offset && !vs->audio_cap && !vs->force_update)
@@ -907,6 +907,7 @@ static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
job = vnc_job_new(vs);
height = MIN(pixman_image_get_height(vd->server), vs->client_height);
width = MIN(pixman_image_get_width(vd->server), vs->client_width);
y = 0;
for (;;) {
@@ -925,8 +926,11 @@ static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
VNC_DIRTY_BPL(vs), x);
bitmap_clear(vs->dirty[y], x, x2 - x);
h = find_and_clear_dirty_height(vs, y, x, x2, height);
n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
(x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
if (x2 > x) {
n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
(x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
}
}
vnc_job_push(job);

45
vl.c
View File

@@ -143,6 +143,9 @@ int vga_interface_type = VGA_NONE;
static int full_screen = 0;
static int no_frame = 0;
int no_quit = 0;
#ifdef CONFIG_GTK
static bool grab_on_hover;
#endif
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
@@ -2276,6 +2279,25 @@ static DisplayType select_display(const char *p)
} else if (strstart(p, "gtk", &opts)) {
#ifdef CONFIG_GTK
display = DT_GTK;
while (*opts) {
const char *nextopt;
if (strstart(opts, ",grab_on_hover=", &nextopt)) {
opts = nextopt;
if (strstart(opts, "on", &nextopt)) {
grab_on_hover = true;
} else if (strstart(opts, "off", &nextopt)) {
grab_on_hover = false;
} else {
goto invalid_gtk_args;
}
} else {
invalid_gtk_args:
fprintf(stderr, "Invalid GTK option string: %s\n", p);
exit(1);
}
opts = nextopt;
}
#else
fprintf(stderr, "GTK support is disabled\n");
exit(1);
@@ -2651,15 +2673,20 @@ static MachineClass *machine_parse(const char *name)
if (mc) {
return mc;
}
printf("Supported machines are:\n");
for (el = machines; el; el = el->next) {
MachineClass *mc = el->data;
QEMUMachine *m = mc->qemu_machine;
if (m->alias) {
printf("%-20s %s (alias of %s)\n", m->alias, m->desc, m->name);
if (name && !is_help_option(name)) {
error_report("Unsupported machine type");
error_printf("Use -machine help to list supported machines!\n");
} else {
printf("Supported machines are:\n");
for (el = machines; el; el = el->next) {
MachineClass *mc = el->data;
QEMUMachine *m = mc->qemu_machine;
if (m->alias) {
printf("%-20s %s (alias of %s)\n", m->alias, m->desc, m->name);
}
printf("%-20s %s%s\n", m->name, m->desc,
m->is_default ? " (default)" : "");
}
printf("%-20s %s%s\n", m->name, m->desc,
m->is_default ? " (default)" : "");
}
g_slist_free(machines);
@@ -4399,7 +4426,7 @@ int main(int argc, char **argv, char **envp)
#endif
#if defined(CONFIG_GTK)
case DT_GTK:
gtk_display_init(ds, full_screen);
gtk_display_init(ds, full_screen, grab_on_hover);
break;
#endif
default: