Compare commits

...

228 Commits

Author SHA1 Message Date
Alexander Graf
6daa5dc051 dictzip: Fix on big endian systems
The dictzip code in SLE11 received some treatment over time to support
running on big endian hosts. Somewhere in the transition to SLE12 this
support got lost. Add it back in again from the SLE11 code base.

Furthermore while at it, fix up the debug prints to not emit warnings.

[AG: BSC#937572]
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-10-08 18:27:41 +02:00
Dr. David Alan Gilbert
b3d605bbbe tests: Unique test path for /string-visitor/output
Newer GLib's want unique test paths, and thus moan at dupes.
(Seen on Fedora 23 which has glib 2.46)

Uniqueify the paths.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-10-08 18:26:42 +02:00
Richard Henderson
cf25e5be2e tcg/aarch64: Fix tcg_out_qemu_{ld, st} for guest_base == 0
In ffc6372851, we swapped the guest
base to the address base register from the address index register.
Except that 31 in the base slot is SP not XZR, so we need to be
more intelligent about which reg gets placed in which slot.

Cc: qemu-stable@nongnu.org (v2.4.0)
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reported-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
(cherry picked from commit 352bcb0a2b)
[AF: Backported to GUEST_BASE and CONFIG_USE_GUEST_BASE]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-10-08 18:26:42 +02:00
Andreas Färber
1c97919295 Revert "Revert seccomp tests that allow it to be used on non-x86 architectures"
This reverts commit ae6e8ef11e.

Our Factory libseccomp is patched to support ppc, ppc64, armv7l and soon
ppc64le.

Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-10-08 18:26:42 +02:00
Alexander Graf
458ee6dac3 AIO: Reduce number of threads for 32bit hosts
On hosts with limited virtual address space (32bit pointers), we can very
easily run out of virtual memory with big thread pools.

Instead, we should limit ourselves to small pools to keep memory footprint
low on those systems.

This patch fixes random VM stalls like

  (process:25114): GLib-ERROR **: gmem.c:103: failed to allocate 1048576 bytes

on 32bit ARM systems for me.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-10-08 18:26:41 +02:00
Andreas Färber
39b6d2beaf qtest: Increase socket timeout
Change from 5 to 15 seconds.

Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-10-08 18:26:41 +02:00
Dinar Valeev
c9fbb5972a configure: Enable PIE for ppc and ppc64 hosts
Signed-off-by: Dinar Valeev <dvaleev@suse.com>
[AF: Rebased for v1.7]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-10-08 18:26:41 +02:00
Bruce Rogers
cd1a94f80e virtfs-proxy-helper: Provide __u64 for broken sys/capability.h
Fixes the build on SLE 11 SP2.

[AF: Extend to ppc64]
2015-10-08 18:26:41 +02:00
Alexander Graf
c42944366a linux-user: lseek: explicitly cast non-set offsets to signed
When doing lseek, SEEK_SET indicates that the offset is an unsigned variable.
Other seek types have parameters that can be negative.

When converting from 32bit to 64bit parameters, we need to take this into
account and enable SEEK_END and SEEK_CUR to be negative, while SEEK_SET stays
absolute positioned which we need to maintain as unsigned.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-10-08 18:26:41 +02:00
Alexander Graf
3de3863153 Make char muxer more robust wrt small FIFOs
Virtio-Console can only process one character at a time. Using it on S390
gave me strage "lags" where I got the character I pressed before when
pressing one. So I typed in "abc" and only received "a", then pressed "d"
but the guest received "b" and so on.

While the stdio driver calls a poll function that just processes on its
queue in case virtio-console can't take multiple characters at once, the
muxer does not have such callbacks, so it can't empty its queue.

To work around that limitation, I introduced a new timer that only gets
active when the guest can not receive any more characters. In that case
it polls again after a while to check if the guest is now receiving input.

This patch fixes input when using -nographic on s390 for me.
2015-10-08 18:26:41 +02:00
Alexander Graf
9ff792a6d5 console: add question-mark escape operator
Some termcaps (found using SLES11SP1) use [? sequences. According to man
console_codes (http://linux.die.net/man/4/console_codes) the question mark
is a nop and should simply be ignored.

This patch does exactly that, rendering screen output readable when
outputting guest serial consoles to the graphical console emulator.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-10-08 18:26:41 +02:00
Alexander Graf
d893ae81b7 Legacy Patch kvm-qemu-preXX-dictzip3.patch 2015-10-08 18:26:40 +02:00
Alexander Graf
6492e67a46 block: Add tar container format
Tar is a very widely used format to store data in. Sometimes people even put
virtual machine images in there.

So it makes sense for qemu to be able to read from tar files. I implemented a
written from scratch reader that also knows about the GNU sparse format, which
is what pigz creates.

This version checks for filenames that end on well-known extensions. The logic
could be changed to search for filenames given on the command line, but that
would require changes to more parts of qemu.

The tar reader in conjunctiuon with dzip gives us the chance to download
tar'ed up virtual machine images (even via http) and instantly make use of
them.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Bruce Rogers <brogers@novell.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
[TH: Use bdrv_open options instead of filename]
Signed-off-by: Tim Hardeck <thardeck@suse.de>
[AF: bdrv_file_open got an Error **errp argument, bdrv_delete -> brd_unref]
[AF: qemu_opts_create_nofail() -> qemu_opts_create(),
     bdrv_file_open() -> bdrv_open(), based on work by brogers]
[AF: error_is_set() dropped for v2.1.0-rc0]
[AF: BlockDriverAIOCB -> BlockAIOCB,
     BlockDriverCompletionFunc -> BlockCompletionFunc,
     qemu_aio_release() -> qemu_aio_unref(),
     drop tar_aio_cancel()]
[AF: common-obj-y -> block-obj-y, drop probe hook (bsc#945778)]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-10-08 18:25:59 +02:00
Alexander Graf
3058cb28a3 block: Add support for DictZip enabled gzip files
DictZip is an extension to the gzip format that allows random seeks in gzip
compressed files by cutting the file into pieces and storing the piece offsets
in the "extra" header of the gzip format.

Thanks to that extension, we can use gzip compressed files as block backend,
though only in read mode.

This makes a lot of sense when stacked with tar files that can then be shipped
to VM users. If a VM image is inside a tar file that is inside a DictZip
enabled gzip file, the user can run the tar.gz file as is without having to
extract the image first.

Tar patch follows.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Bruce Rogers <brogers@novell.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
[TH: Use bdrv_open options instead of filename]
Signed-off-by: Tim Hardeck <thardeck@suse.de>
[AF: Error **errp added for bdrv_file_open, bdrv_delete -> bdrv_unref]
[AF: qemu_opts_create_nofail() -> qemu_opts_create(),
     bdrv_file_open() -> bdrv_open(), based on work by brogers]
[AF: error_is_set() dropped for v2.1.0-rc0]
[AF: BlockDriverAIOCB -> BlockAIOCB,
     BlockDriverCompletionFunc -> BlockCompletionFunc,
     qemu_aio_release() -> qemu_aio_unref(),
     drop dictzip_aio_cancel()]
[AF: common-obj-y -> block-obj-y, drop probe hook (bsc#945778)]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-10-08 18:23:11 +02:00
Alexander Graf
72d795a02f linux-user: use target_ulong
Linux syscalls pass pointers or data length or other information of that sort
to the kernel. This is all stuff you don't want to have sign extended.
Otherwise a host 64bit variable parameter with a size parameter will extend
it to a negative number, breaking lseek for example.

Pass syscall arguments as ulong always.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-08-12 18:22:45 +02:00
Alexander Graf
41e679783a linux-user: add more blk ioctls
Implement a few more ioctls that operate on block devices.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-08-12 18:22:45 +02:00
Andreas Färber
e6f0d75af3 vnc: password-file= and incoming-connections=
TBD (from SUSE Studio team)
2015-08-12 18:22:45 +02:00
Andreas Färber
872dda04d4 slirp: -nooutgoing
TBD (from SUSE Studio team)
2015-08-12 18:22:45 +02:00
Alexander Graf
12eee45e11 linux-user: XXX disable fiemap
agraf: fiemap breaks in libarchive. Disable it for now.
2015-08-12 18:22:45 +02:00
Alexander Graf
11b3d0e151 linux-user: implement FS_IOC_SETFLAGS ioctl
Signed-off-by: Alexander Graf <agraf@suse.de>

---

v1 -> v2

  - use TYPE_LONG instead of TYPE_INT
2015-08-12 18:22:45 +02:00
Alexander Graf
e5e97946c3 linux-user: implement FS_IOC_GETFLAGS ioctl
Signed-off-by: Alexander Graf <agraf@suse.de>

---

v1 -> v2:

  - use TYPE_LONG instead of TYPE_INT
2015-08-12 18:22:45 +02:00
Alexander Graf
a592905fec linux-user: Fake /proc/cpuinfo
Fedora 17 for ARM reads /proc/cpuinfo and fails if it doesn't contain
ARM related contents. This patch implements a quick hack to expose real
/proc/cpuinfo data taken from a real world machine.

The real fix would be to generate at least the flags automatically based
on the selected CPU. Please do not submit this patch upstream until this
has happened.

Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased for v1.6 and v1.7]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-08-12 18:22:44 +02:00
Alexander Graf
996083e51b linux-user: lock tb flushing too
Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased onto exec.c/translate-all.c split for 1.4]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-08-12 18:22:44 +02:00
Alexander Graf
bb2c298342 linux-user: Run multi-threaded code on a single core
Running multi-threaded code can easily expose some of the fundamental
breakages in QEMU's design. It's just not a well supported scenario.

So if we pin the whole process to a single host CPU, we guarantee that
we will never have concurrent memory access actually happen. We can still
get scheduled away at any time, so it's no complete guarantee, but apparently
it reduces the odds well enough to get my test cases to pass.

This gets Java 1.7 working for me again on my test box.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-08-12 18:22:44 +02:00
Alexander Graf
66d948dc1c linux-user: lock tcg
The tcg code generator is not thread safe. Lock its generation between
different threads.

Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased onto exec.c/translate-all.c split for 1.4]
[AF: Rebased for v2.1.0-rc0]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-08-12 18:22:44 +02:00
Alexander Graf
c09e4874d8 linux-user: Ignore broken loop ioctl
During invocations of losetup, we run into an ioctl that doesn't
exist. However, because of that we output an error, which then
screws up the kiwi logic around that call.

So let's silently ignore that bogus ioctl.

Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased for v2.1.0-rc0]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-08-12 18:22:44 +02:00
Alexander Graf
9d108fe888 linux-user: binfmt: support host binaries
When we have a working host binary equivalent for the guest binary we're
trying to run, let's just use that instead as it will be a lot faster.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-08-12 18:22:44 +02:00
Alexander Graf
b3086c4600 linux-user: fix segfault deadlock
When entering the guest we take a lock to ensure that nobody else messes
with our TB chaining while we're doing it. If we get a segfault inside that
code, we manage to work on, but will not unlock the lock.

This patch forces unlocking of that lock in the segv handler. I'm not sure
this is the right approach though. Maybe we should rather make sure we don't
segfault in the code? I would greatly appreciate someone more intelligible
than me to look at this :).

Example code to trigger this is at: http://csgraf.de/tmp/conftest.c

Reported-by: Fabio Erculiani <lxnay@sabayon.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-08-12 18:22:44 +02:00
Alexander Graf
2fc3bebad0 PPC: KVM: Disable mmu notifier check
When using hugetlbfs (which is required for HV mode KVM on 970), we
check for MMU notifiers that on 970 can not be implemented properly.

So disable the check for mmu notifiers on PowerPC guests, making
KVM guests work there, even if possibly racy in some odd circumstances.
2015-08-12 18:22:44 +02:00
Alexander Graf
3e9916744d linux-user: add binfmt wrapper for argv[0] handling
When using qemu's linux-user binaries through binfmt, argv[0] gets lost
along the execution because qemu only gets passed in the full file name
to the executable while argv[0] can be something completely different.

This breaks in some subtile situations, such as the grep and make test
suites.

This patch adds a wrapper binary called qemu-$TARGET-binfmt that can be
used with binfmt's P flag which passes the full path _and_ argv[0] to
the binfmt handler.

The binary would be smart enough to be versatile and only exist in the
system once, creating the qemu binary path names from its own argv[0].
However, this seemed like it didn't fit the make system too well, so
we're currently creating a new binary for each target archictecture.

CC: Reinhard Max <max@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased onto new Makefile infrastructure, twice]
[AF: Updated for aarch64 for v2.0.0-rc1]
[AF: Rebased onto Makefile changes for v2.1.0-rc0]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-08-12 18:22:44 +02:00
Ulrich Hecht
dd09a1efb9 block/vmdk: Support creation of SCSI VMDK images in qemu-img
Signed-off-by: Ulrich Hecht <uli@suse.de>
[AF: Changed BLOCK_FLAG_SCSI from 8 to 16 for v1.2]
[AF: Rebased onto upstream VMDK SCSI support]
[AF: Rebased onto skipping of image creation in v1.7]
[AF: Simplified in preparation for v1.7.1/v2.0]
[AF: Rebased onto QemuOpts conversion for v2.1]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-08-12 18:22:44 +02:00
Alexander Graf
578468f720 qemu-cvs-ioctl_nodirection
the direction given in the ioctl should be correct so we can assume the
communication is uni-directional. The alsa developers did not like this
concept though and declared ioctls IOC_R and IOC_W even though they were
IOC_RW.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2015-08-12 18:22:44 +02:00
Alexander Graf
ea09ea340e qemu-cvs-ioctl_debug
Extends unsupported ioctl debug output.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2015-08-12 18:22:44 +02:00
Ulrich Hecht
33a0ebb46a qemu-cvs-gettimeofday
No clue what this is for.
2015-08-12 18:22:43 +02:00
Alexander Graf
e467d93b8c qemu-cvs-alsa_mmap
Hack to prevent ALSA from using mmap() interface to simplify emulation.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2015-08-12 18:22:43 +02:00
Alexander Graf
706f125ff6 qemu-cvs-alsa_ioctl
Implements ALSA ioctls on PPC hosts.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2015-08-12 18:22:43 +02:00
Alexander Graf
30757b11ba qemu-cvs-alsa_bitfield
Implements TYPE_INTBITFIELD partially. (required for ALSA support)

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2015-08-12 18:22:43 +02:00
Ulrich Hecht
46a229c086 qemu-0.9.0.cvs-binfmt
Fixes binfmt_misc setup script:
- x86_64 is i386-compatible
- m68k signature fixed
- path to QEMU

Signed-off-by: Ulrich Hecht <uli@suse.de>
[AF: Update path for qemu-aarch64 for v2.0.0-rc1]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-08-12 18:22:43 +02:00
Alexander Graf
5a7aa97bf3 XXX work around SA_RESTART race with boehm-gc (ARM only)
[AF: CPUState -> CPUArchState, adapt to reindentation]
[AF: CPUArchState::opaque -> CPUState::opaque]
2015-08-12 18:22:43 +02:00
Alexander Graf
1e556e72ef XXX dont dump core on sigabort 2015-08-12 18:22:43 +02:00
Peter Maydell
5c79ae3615 Update version for v2.4.0 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-08-11 15:30:34 +01:00
Peter Maydell
2d697366a1 Update version for v2.4.0-rc4 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-08-05 17:02:58 +01:00
Peter Maydell
0175409df4 Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio fix for 2.4

Fixes migration in virtio 1 mode.
We still have a known bug with memory hotplug, it doesn't
look like we can fix that in time for 2.4.

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

# gpg: Signature made Wed 05 Aug 2015 15:57:39 BST using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"

* remotes/mst/tags/for_upstream:
  virtio: fix 1.0 virtqueue migration

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-08-05 16:02:00 +01:00
Sascha Silbe
e94867ed5f block: don't register quorum driver if SHA256 support is unavailable
Commit 488981a4 [block: convert quorum blockdrv to use crypto APIs]
broke qemu-iotest 041 on hosts with GnuTLS < 2.10.0. It converted a
compile-time check to a run-time check at device open time. The result
is that we now advertise a feature (the quorum block driver) that will
never work (on those hosts). There's no way (short of parsing
human-readable error messages) for qemu-iotests or any other API
consumer to recognise that the quorum block driver isn't _actually_
available and shouldn't be used or tested.

Move the run-time check to bdrv_quorum_init() to avoid registering the
quorum block driver if we know it cannot work. This way API consumers
can recognise it's unavailable.

Fixes: 488981a4af
Signed-off-by: Sascha Silbe <silbe@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Message-id: 1438699705-21761-1-git-send-email-silbe@linux.vnet.ibm.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-08-05 15:19:32 +01:00
Jason Wang
74aae7b22b virtio: fix 1.0 virtqueue migration
1.0 does not requires physically-contiguous pages layout for a
virtqueue. So we could not infer avail and used from desc. This means
we need to migrate vring.avail and vring.used when host support virtio
1.0. This fixes malfunction of virtio 1.0 device after migration.

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2015-08-05 16:56:34 +03:00
Peter Maydell
2be4f242b5 Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging
X86 queue, 2015-08-04

# gpg: Signature made Tue 04 Aug 2015 16:49:42 BST using RSA key ID 984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF  D1AA 2807 936F 984D C5A6

* remotes/ehabkost/tags/x86-pull-request:
  target-i386: fix IvyBridge xlevel in PC_COMPAT_2_3

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-08-04 16:51:24 +01:00
Radim Krčmář
27751aabd1 target-i386: fix IvyBridge xlevel in PC_COMPAT_2_3
Previous patch changed xlevel and missed the compatibility code.

Fixes: 3046bb5deb ("target-i386: emulate CPUID level of real hardware")
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2015-08-04 12:49:32 -03:00
Peter Maydell
426d0e7b7e Merge remote-tracking branch 'remotes/lalrae/tags/mips-20150804' into staging
MIPS patches 2015-08-04

Changes:
* fix semihosting for microMIPS R6
* fix an abort when booting mips64 kernel with --enable-tcg-debug

# gpg: Signature made Tue 04 Aug 2015 12:32:17 BST using RSA key ID 0B29DA6B
# gpg: Good signature from "Leon Alrae <leon.alrae@imgtec.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: 8DD3 2F98 5495 9D66 35D4  4FC0 5211 8E3C 0B29 DA6B

* remotes/lalrae/tags/mips-20150804:
  target-mips: Copy restrictions from ext/ins to dext/dins
  target-mips: fix semihosting for microMIPS R6

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-08-04 12:57:06 +01:00
Richard Henderson
b7f26e5239 target-mips: Copy restrictions from ext/ins to dext/dins
The checks in dins is required to avoid triggering an assertion
in tcg_gen_deposit_tl.  The check in dext is just for completeness.
Fold the other D cases in via fallthru.

In this case the errant dins appears to be data, not code, as
translation failed to stop after a break insn.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
2015-08-04 11:53:15 +01:00
Leon Alrae
060ebfef1a target-mips: fix semihosting for microMIPS R6
In semihosting mode the SDBBP 1 instructions should trigger UHI syscall,
but in QEMU this does not happen for recently added microMIPS R6.
Consequently bare metal microMIPS R6 programs supporting UHI will not run.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
2015-08-04 11:10:20 +01:00
Peter Maydell
260425ab40 Merge remote-tracking branch 'remotes/sstabellini/tags/cve-2015-5166-tag' into staging
cve-2015-5166

# gpg: Signature made Mon 03 Aug 2015 15:27:44 BST using RSA key ID 70E1AE90
# gpg: Good signature from "Stefano Stabellini <stefano.stabellini@eu.citrix.com>"

* remotes/sstabellini/tags/cve-2015-5166-tag:
  Fix release_drive on unplugged devices (pci_piix3_xen_ide_unplug)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-08-03 18:52:55 +01:00
Peter Maydell
e95edefbd0 Merge remote-tracking branch 'remotes/sstabellini/tags/xen-migration-2.4-tag' into staging
xen-migration-2.4

# gpg: Signature made Mon 03 Aug 2015 17:18:36 BST using RSA key ID 70E1AE90
# gpg: Good signature from "Stefano Stabellini <stefano.stabellini@eu.citrix.com>"

* remotes/sstabellini/tags/xen-migration-2.4-tag:
  migration: Fix regression for xenfv and pc,accel=xen machine.
  migration: Fix global state with Xen.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-08-03 17:33:35 +01:00
Anthony PERARD
8c6dc68f4c migration: Fix regression for xenfv and pc,accel=xen machine.
This fix migration from the same QEMU version and from previous QEMU
version.

>From the global state section, we don't need runstate with Xen. Right now,
the way the Xen toolstack knows when QEMU is ready is when QEMU reach
"running" runstate.

The configuration section and the section footers are not going to be
present in previous version of QEMU with xenfv machine, so we skip them.

The Xen toolstack libxenlight does not specify a particular version of the
'pc' machine, so migration from older version of QEMU used by Xen to newer
one would break due to missing "configuration" section and section footers.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
2015-08-03 16:13:40 +00:00
Anthony PERARD
c69adea462 migration: Fix global state with Xen.
When doing migration via the QMP command xen_save_devices_state, the
current runstate is not store into the global state section. Also the
current runstate is not the one we want on the receiver side.

During migration, the Xen toolstack paused QEMU before save the devices
state. Also, the toolstack expect QEMU to autostart when the migration is
finished.
So this patch store "running" as it's current runstate.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
2015-08-03 16:13:23 +00:00
Andreas Färber
f60c87154a configure: Drop vnc-ws feature from help text
Commit 8e9b0d2 (ui: convert VNC websockets to use crypto APIs) dropped
the --enable-vnc-ws option but forgot to update the help text. Fix this.

Cc: Daniel P. Berrange <berrange@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 1437749257-3313-1-git-send-email-afaerber@suse.de
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-08-03 15:32:17 +01:00
Stefano Stabellini
6cd387833d Fix release_drive on unplugged devices (pci_piix3_xen_ide_unplug)
pci_piix3_xen_ide_unplug should completely unhook the unplugged
IDEDevice from the corresponding BlockBackend, otherwise the next call
to release_drive will try to detach the drive again.

Suggested-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
2015-08-03 14:27:12 +00:00
Peter Maydell
2a3612ccc1 Merge remote-tracking branch 'remotes/stefanha/tags/rtl8139-cplus-tx-input-validation-pull-request' into staging
Pull request

# gpg: Signature made Mon Aug  3 13:08:25 2015 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/rtl8139-cplus-tx-input-validation-pull-request:
  rtl8139: check TCP Data Offset field (CVE-2015-5165)
  rtl8139: skip offload on short TCP header (CVE-2015-5165)
  rtl8139: check IP Total Length field (CVE-2015-5165)
  rtl8139: check IP Header Length field (CVE-2015-5165)
  rtl8139: skip offload on short Ethernet/IP header (CVE-2015-5165)
  rtl8139: drop tautologous if (ip) {...} statement (CVE-2015-5165)
  rtl8139: avoid nested ifs in IP header parsing (CVE-2015-5165)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-08-03 13:09:10 +01:00
Stefan Hajnoczi
8357946b15 rtl8139: check TCP Data Offset field (CVE-2015-5165)
The TCP Data Offset field contains the length of the header.  Make sure
it is valid and does not exceed the IP data length.

Reported-by: 朱东海(启路) <donghai.zdh@alibaba-inc.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-08-03 13:08:10 +01:00
Stefan Hajnoczi
4240be4563 rtl8139: skip offload on short TCP header (CVE-2015-5165)
TCP Large Segment Offload accesses the TCP header in the packet.  If the
packet is too short we must not attempt to access header fields:

  tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen);
  int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr);

Reported-by: 朱东海(启路) <donghai.zdh@alibaba-inc.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-08-03 13:08:07 +01:00
Stefan Hajnoczi
c6296ea88d rtl8139: check IP Total Length field (CVE-2015-5165)
The IP Total Length field includes the IP header and data.  Make sure it
is valid and does not exceed the Ethernet payload size.

Reported-by: 朱东海(启路) <donghai.zdh@alibaba-inc.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-08-03 13:08:06 +01:00
Stefan Hajnoczi
03247d43c5 rtl8139: check IP Header Length field (CVE-2015-5165)
The IP Header Length field was only checked in the IP checksum case, but
is used in other cases too.

Reported-by: 朱东海(启路) <donghai.zdh@alibaba-inc.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-08-03 13:08:03 +01:00
Stefan Hajnoczi
e1c120a9c5 rtl8139: skip offload on short Ethernet/IP header (CVE-2015-5165)
Transmit offload features access Ethernet and IP headers the packet.  If
the packet is too short we must not attempt to access header fields:

  int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12));
  ...
  eth_payload_data = saved_buffer + ETH_HLEN;
  ...
  ip = (ip_header*)eth_payload_data;
  if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {

Reported-by: 朱东海(启路) <donghai.zdh@alibaba-inc.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-08-03 13:08:00 +01:00
Stefan Hajnoczi
d6812d60e7 rtl8139: drop tautologous if (ip) {...} statement (CVE-2015-5165)
The previous patch stopped using the ip pointer as an indicator that the
IP header is present.  When we reach the if (ip) {...} statement we know
ip is always non-NULL.

Remove the if statement to reduce nesting.

Reported-by: 朱东海(启路) <donghai.zdh@alibaba-inc.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-08-03 13:07:54 +01:00
Stefan Hajnoczi
39b8e7dcaf rtl8139: avoid nested ifs in IP header parsing (CVE-2015-5165)
Transmit offload needs to parse packet headers.  If header fields have
unexpected values the offload processing is skipped.

The code currently uses nested ifs because there is relatively little
input validation.  The next patches will add missing input validation
and a goto label is more appropriate to avoid deep if statement nesting.

Reported-by: 朱东海(启路) <donghai.zdh@alibaba-inc.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-08-03 13:06:59 +01:00
Peter Maydell
bd80b5963f Merge remote-tracking branch 'remotes/aurel/tags/pull-tcg-mips-s390-20150803' into staging
TCG MIPS and S390 fixes for 2.4.

# gpg: Signature made Mon Aug  3 09:09:59 2015 BST using RSA key ID 1DDD8C9B
# gpg: Good signature from "Aurelien Jarno <aurelien@aurel32.net>"
# gpg:                 aka "Aurelien Jarno <aurelien@jarno.fr>"
# gpg:                 aka "Aurelien Jarno <aurel32@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: 7746 2642 A9EF 94FD 0F77  196D BA9C 7806 1DDD 8C9B

* remotes/aurel/tags/pull-tcg-mips-s390-20150803:
  tcg/mips: fix add2
  tcg/s390x: Mask TCGMemOp appropriately for indexing
  tcg/mips: Mask TCGMemOp appropriately for indexing
  tcg/mips: fix TLB loading for BE host with 32-bit guests

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-08-03 11:44:07 +01:00
Peter Maydell
ff90f84e74 Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging
# gpg: Signature made Fri Jul 31 23:24:06 2015 BST using RSA key ID AAFC390E
# gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: FAEB 9711 A12C F475 812F  18F2 88A9 064D 1835 61EB
#      Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76  CBD0 7DEF 8106 AAFC 390E

* remotes/jnsnow/tags/ide-pull-request:
  ahci: fix ICC mask definition
  macio: re-add TRIM support

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-08-03 10:44:23 +01:00
Aurelien Jarno
c99d69694a tcg/mips: fix add2
The add2 code in the tcg_out_addsub2 function doesn't take into account
the case where rl == al == bl. In that case we can't compute the carry
after the addition. As it corresponds to a multiplication by 2, the
carry bit is the bit 31.

While this is a corner case, this prevents x86-64 guests to boot on a
MIPS host.

Cc: qemu-stable@nongnu.org
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2015-08-01 09:39:50 +02:00
Aurelien Jarno
3c8691f568 tcg/s390x: Mask TCGMemOp appropriately for indexing
Commit 2b7ec66f fixed TCGMemOp masking following the MO_AMASK addition,
but two cases were forgotten in the TCG S390 backend.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2015-08-01 09:39:37 +02:00
Aurelien Jarno
4214a8cb7c tcg/mips: Mask TCGMemOp appropriately for indexing
Commit 2b7ec66f fixed TCGMemOp masking following the MO_AMASK addition,
but two cases were forgotten in the TCG MIPS backend.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2015-08-01 09:39:33 +02:00
Aurelien Jarno
e72c4fb81d tcg/mips: fix TLB loading for BE host with 32-bit guests
For 32-bit guest, we load a 32-bit address from the TLB, so there is no
need to compensate for the low or high part. This fixes 32-bit guests on
big-endian hosts.

Cc: qemu-stable@nongnu.org
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2015-08-01 09:38:36 +02:00
John Snow
91ced51446 ahci: fix ICC mask definition
There are likely others that could be updated, but we'll
go with a light touch for 2.4 for now.

Without the Unsigned specifier, this shifts bits into the
signed bit, which makes clang unhappy and could cause
unwanted behavior.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 1437501721-24495-1-git-send-email-jsnow@redhat.com
2015-07-31 16:39:20 -04:00
Aurelien Jarno
0e826a061a macio: re-add TRIM support
Commit bd4214fc dropped TRIM support by mistake. Given it is still
advertised to the host when using a drive with discard=on, this cause
the IDE bus to hang when the host issues a TRIM command.

This patch fixes that by re-adding the TRIM code, ported to the new
new DMA implementation.

Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: John Snow <jsnow@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Message-id: 1438198068-32428-1-git-send-email-aurelien@aurel32.net
Signed-off-by: John Snow <jsnow@redhat.com>
2015-07-31 16:38:50 -04:00
Richard Henderson
cb48f67ad8 bsd-user: Fix operand to cpu_x86_exec
Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1438195252-21968-1-git-send-email-rth@twiddle.net
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-30 12:38:49 +01:00
Peter Maydell
7008d580ac Update version for v2.4.0-rc3 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-29 18:50:11 +01:00
Peter Maydell
46739a2d7a Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Pull request

These fixes make dataplane work again after the notify_me optimization was
added.  They also solve QEMUBH memory leaks and fix a bug in dataplane's
cleanup code.

# gpg: Signature made Wed Jul 29 14:50:26 2015 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/block-pull-request:
  AioContext: force event loop iteration using BH
  AioContext: avoid leaking BHs on cleanup
  virtio-blk-dataplane: delete bottom half before the AioContext is freed

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-29 17:08:38 +01:00
Stefan Hajnoczi
ca96ac44dc AioContext: force event loop iteration using BH
The notify_me optimization introduced in commit eabc977973
("AioContext: fix broken ctx->dispatching optimization") skips
event_notifier_set() calls when the event loop thread is not blocked in
ppoll(2).

This optimization causes a deadlock if two aio_context_acquire() calls
race.  notify_me = 0 during the race so the winning thread can enter
ppoll(2) unaware that the other thread is waiting its turn to acquire
the AioContext.

This patch forces ppoll(2) to return by scheduling a BH instead of
calling aio_notify().

The following deadlock with virtio-blk dataplane is fixed:

  qemu ... -object iothread,id=iothread0 \
           -drive if=none,id=drive0,file=test.img,... \
           -device virtio-blk-pci,iothread=iothread0,drive=drive0

This command-line results in a hang early on without this patch.

Thanks to Paolo Bonzini <pbonzini@redhat.com> for investigating this bug
with me.

Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1438101249-25166-4-git-send-email-pbonzini@redhat.com
Message-Id: <1438014819-18125-3-git-send-email-stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-29 10:02:06 +01:00
Stefan Hajnoczi
a076972a4d AioContext: avoid leaking BHs on cleanup
BHs are freed during aio_bh_poll().  This leads to memory leaks if there
is no aio_bh_poll() between qemu_bh_delete() and aio_ctx_finalize().

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1438101249-25166-3-git-send-email-pbonzini@redhat.com
Message-Id: <1438014819-18125-2-git-send-email-stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-29 10:02:06 +01:00
Paolo Bonzini
fed105e275 virtio-blk-dataplane: delete bottom half before the AioContext is freed
Other uses of aio_bh_new are safe as long as all scheduled bottom
halves are run before an iothread is destroyed, which bdrv_drain will
ensure:

- archipelago_finish_aiocb: BH deletes itself

- inject_error: BH deletes itself

- blkverify_aio_bh: BH deletes itself

- abort_aio_request: BH deletes itself

- curl_aio_readv: BH deletes itself

- gluster_finish_aiocb: BH deletes itself

- bdrv_aio_rw_vector: BH deletes itself

- bdrv_co_maybe_schedule_bh: BH deletes itself

- iscsi_schedule_bh, iscsi_co_generic_cb: BH deletes itself

- laio_attach_aio_context: deleted in laio_detach_aio_context,
called through bdrv_detach_aio_context before deleting the iothread

- nfs_co_generic_cb: BH deletes itself

- null_aio_common: BH deletes itself

- qed_aio_complete: BH deletes itself

- rbd_finish_aiocb: BH deletes itself

- dma_blk_cb: BH deletes itself

- virtio_blk_dma_restart_cb: BH deletes itself

- qemu_bh_new: main loop AioContext is never destroyed

- test-aio.c: bh_delete_cb deletes itself, otherwise deleted in
the same function that calls aio_bh_new

Reported-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1438101249-25166-2-git-send-email-pbonzini@redhat.com
Message-Id: <1438086628-13000-1-git-send-email-pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-29 10:02:06 +01:00
Peter Maydell
b83d017d88 Merge remote-tracking branch 'remotes/stefanha/tags/net-pull-request' into staging
Pull request

These two .can_receive() are now reviewed.  The net subsystem queue for 2.4 is now empty.

# gpg: Signature made Tue Jul 28 13:26:03 2015 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/net-pull-request:
  xen: Drop net_rx_ok
  hw/net: handle flow control in mcf_fec driver receiver

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-28 19:02:04 +01:00
Peter Maydell
170f209d78 Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio fixes for 2.4

Mostly virtio 1 spec compliance fixes.
We are unlikely to make it perfectly compliant in
the first release, but it seems worth it to try.

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

# gpg: Signature made Mon Jul 27 21:55:48 2015 BST using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"

* remotes/mst/tags/for_upstream:
  virtio: minor cleanup
  acpi: fix pvpanic device is not shown in ui
  virtio-blk: only clear VIRTIO_F_ANY_LAYOUT for legacy device
  virtio-blk: fail get_features when both scsi and 1.0 were set
  virtio: get_features() can fail
  virtio-pci: fix memory MR cleanup for modern
  virtio: set any_layout in virtio core
  virtio-9p: fix any_layout
  virtio-serial: fix ANY_LAYOUT
  virtio: hide legacy features from modern guests

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-28 17:09:56 +01:00
Peter Maydell
8b89b3a8df Merge remote-tracking branch 'remotes/lalrae/tags/mips-20150728' into staging
MIPS patches 2015-07-28

Changes:
* net/dp8393x fixes
* Vectored Interrupts bug fix
* fix for a bug in machine.c which was provoking a warning on FreeBSD

# gpg: Signature made Tue Jul 28 10:47:19 2015 BST using RSA key ID 0B29DA6B
# gpg: Good signature from "Leon Alrae <leon.alrae@imgtec.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: 8DD3 2F98 5495 9D66 35D4  4FC0 5211 8E3C 0B29 DA6B

* remotes/lalrae/tags/mips-20150728:
  net/dp8393x: do not use memory_region_init_rom_device with NULL
  net/dp8393x: remove check of runt packets
  net/dp8393x: disable user creation
  target-mips: fix offset calculation for Interrupts
  target-mips: fix passing incompatible pointer type in machine.c

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-28 15:25:24 +01:00
Peter Maydell
5e868d2e5e Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* crypto fixes
* megasas SIGSEGV fix
* memory refcount change to fix virtio hot-unplug

# gpg: Signature made Tue Jul 28 08:29:07 2015 BST using RSA key ID 78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream:
  memory: do not add a reference to the owner of aliased regions
  megasas: Add write function to handle write access to PCI BAR 3
  crypto: extend unit tests to cover decryption too
  crypto: fix built-in AES decrypt function

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-28 14:19:16 +01:00
Peter Maydell
9f8c5b69c2 Merge remote-tracking branch 'remotes/cody/tags/jtc-for-upstream-pull-request' into staging
# gpg: Signature made Tue Jul 28 05:22:29 2015 BST using RSA key ID C0DE3057
# gpg: Good signature from "Jeffrey Cody <jcody@redhat.com>"
# gpg:                 aka "Jeffrey Cody <jeff@codyprime.org>"
# gpg:                 aka "Jeffrey Cody <codyprime@gmail.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 9957 4B4D 3474 90E7 9D98  D624 BDBE 7B27 C0DE 3057

* remotes/cody/tags/jtc-for-upstream-pull-request:
  block/ssh: Avoid segfault if inet_connect doesn't set errno.
  sheepdog: serialize requests to overwrapping area

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-28 13:22:57 +01:00
Fam Zheng
7bba83bf80 xen: Drop net_rx_ok
Let net_rx_packet() (which checks the same conditions) drops the packet
if the device is not ready. Drop net_xen_info.can_receive and update the
return value for the buffer full case.

We rely on the qemu_flush_queued_packets() in net_event() to wake up
the peer when the buffer becomes available again.

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-id: 1438077176-378-1-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-28 11:35:54 +01:00
Peter Maydell
776f878451 Merge remote-tracking branch 'remotes/mjt/tags/pull-trivial-patches-2015-07-27' into staging
trivial patches for 2015-07-27

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

* remotes/mjt/tags/pull-trivial-patches-2015-07-27:
  gdbstub: Set current CPU on interruptions
  qapi: add missing @
  Fix Cortex-A9 global timer
  gitignore: Ignore shader generated files
  vmstate: remove unused declaration
  make: Clean build messages
  qemu-common.h: Document cutils.c string functions
  device_tree: Fix a typo
  hw/acpi/ich9: clean up stale comment about KVM not supporting SMM
  hw/acpi/ich9: clear smi_en on reset

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-28 11:28:44 +01:00
Greg Ungerer
ff1d2ac949 hw/net: handle flow control in mcf_fec driver receiver
The network mcf_fec driver emulated receive side method is not dealing
with network queue flow control properly.

Modify the receive side to check if we have enough space in the
descriptors to store the current packet. If not we process none of it
and return 0. When the guest frees up some buffers through its descriptors
we signal the qemu net layer to send more packets.

[Fixed coding style: 4-space indent and curly braces on if statement.
--Stefan]

Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Message-id: 1438045374-10358-1-git-send-email-gerg@uclinux.org
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-28 11:27:53 +01:00
Hervé Poussineau
52579c681c net/dp8393x: do not use memory_region_init_rom_device with NULL
Replace memory_region_init_rom_device() with memory_region_init_ram() and
memory_region_set_readonly().
This fixes a guest-triggerable QEMU crash when guest tries to write to PROM.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
[leon.alrae@imgtec.com: shorten subject length]
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
2015-07-28 09:30:10 +01:00
Hervé Poussineau
30dfa9a46c net/dp8393x: remove check of runt packets
Ethernet requires that messages are at least 64 bytes on the wire. This
limitation does not exist on emulation (no wire message), so remove the
check. Netcard is now able to receive small network packets.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
2015-07-28 09:30:09 +01:00
Hervé Poussineau
f6351288b6 net/dp8393x: disable user creation
Netcard needs an address space to write data to, which can't be specified
on command line.
This fixes a crash when user starts QEMU with "-device dp8393x"

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
2015-07-28 09:29:25 +01:00
Peter Maydell
84a29c7efd Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches for 2.4.0-rc3

# gpg: Signature made Mon Jul 27 16:19:17 2015 BST using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream:
  block: qemu-iotests - add check for multiplication overflow in vpc
  block: vpc - prevent overflow if max_table_entries >= 0x40000000

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-28 09:11:48 +01:00
Yongbok Kim
da52a4dfcc target-mips: fix offset calculation for Interrupts
Correct computation of vector offsets for EXCP_EXT_INTERRUPT.
For instance, if Cause.IV is 0 the vector offset should be 0x180.

Simplify the finding vector number logic for the Vectored Interrupts.

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
[leon.alrae@imgtec.com: cosmetic changes]
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
2015-07-28 08:57:51 +01:00
Leon Alrae
8bcbb834a0 target-mips: fix passing incompatible pointer type in machine.c
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
2015-07-28 08:57:50 +01:00
Richard W.M. Jones
325e390421 block/ssh: Avoid segfault if inet_connect doesn't set errno.
On some (but not all) systems:

  $ qemu-img create -f qcow2 overlay -b ssh://xen/
  Segmentation fault

It turns out this happens when inet_connect returns -1 in the
following code, but errno == 0.

  s->sock = inet_connect(s->hostport, errp);
  if (s->sock < 0) {
      ret = -errno;
      goto err;
  }

In the test case above, no host called "xen" exists, so getaddrinfo fails.

On Fedora 22, getaddrinfo happens to set errno = ENOENT (although it
is *not* documented to do that), so it doesn't segfault.

On RHEL 7, errno is not set by the failing getaddrinfo, so ret =
-errno = 0, so the caller doesn't know there was an error and
continues with a half-initialized BDRVSSHState struct, and everything
goes south from there, eventually resulting in a segfault.

Fix this by setting ret to -EIO (same as block/nbd.c and
block/sheepdog.c).  The real error is saved in the Error** errp
struct, so it is printed correctly:

  $ ./qemu-img create -f qcow2 overlay -b ssh://xen/
  qemu-img: overlay: address resolution failed for xen:22: No address associated with hostname

Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Reported-by: Jun Li
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1147343
Signed-off-by: Jeff Cody <jcody@redhat.com>
2015-07-28 00:19:05 -04:00
Hitoshi Mitake
6a55c82cec sheepdog: serialize requests to overwrapping area
Current sheepdog driver only serializes create requests in oid
unit. This mechanism isn't enough for handling requests to
overwrapping area spanning multiple oids, so it can result bugs like
below:
https://bugs.launchpad.net/sheepdog-project/+bug/1456421

This patch adds a new serialization mechanism for the problem. The
difference from the old one is:
1. serialize entire aiocb if their targetting areas overwrap
2. serialize all requests (read, write, and discard), not only creates

This patch also removes the old mechanism because the new one can be
an alternative.

Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Teruaki Ishizaki <ishizaki.teruaki@lab.ntt.co.jp>
Cc: Vasiliy Tolstov <v.tolstov@selfip.ru>
Signed-off-by: Hitoshi Mitake <mitake.hitoshi@lab.ntt.co.jp>
Tested-by: Vasiliy Tolstov <v.tolstov@selfip.ru>
Signed-off-by: Jeff Cody <jcody@redhat.com>
2015-07-28 00:16:57 -04:00
Paolo Bonzini
52c91dac6b memory: do not add a reference to the owner of aliased regions
Very often the owner of the aliased region is the same as the owner of the alias
region itself.  When this happens, the reference count can never go back to 0 and
the owner is leaked.  This is for example breaking hot-unplug of virtio-pci
devices (the device cannot be plugged back again with the same id).

Another common use for alias is to transform the system I/O address space
into an MMIO regions; in this case the aliased region never dies, so there
is no problem.  Otherwise the owner is always the same for aliasing
and aliased region.

I checked all calls to memory_region_init_alias introduced after commit
dfde4e6 (memory: add ref/unref calls, 2013-05-06) and they do not need the
reference in order to keep the owner of the aliased region alive.

Reported-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-27 23:05:49 +02:00
Salva Peiró
55875fc4ca megasas: Add write function to handle write access to PCI BAR 3
This patch fixes a QEMU SEGFAULT when a write operation is performed on
the memory region of the PCI BAR 3 (base address space).
When a writeb(0xe0000000) is performed the .write function is invoked to
handle the write access, however, since the .write is not initialised,
the call to 0, causes QEMU to SEGFAULT.

Signed-off-by: Salva Peiró <speirofr@gmail.com>
Acked-by: Hannes Reinecke <hare@suse.com>
Message-Id: <1437987112-24744-1-git-send-email-speirofr@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-27 23:05:49 +02:00
Michael S. Tsirkin
c147b5153e virtio: minor cleanup
There's no need for blk to set ANY_LAYOUT, it's
done by virtio core as necessary.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2015-07-27 23:55:27 +03:00
Gal Hammer
8ef3ea253b acpi: fix pvpanic device is not shown in ui
Commit 2332333c added a _STA method that hides the device. The fact
that the device is not shown in the gui make it harder to install its
Windows' device.

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

Signed-off-by: Gal Hammer <ghammer@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
2015-07-27 23:55:27 +03:00
Jan Kiszka
226d007dbd gdbstub: Set current CPU on interruptions
gdb expects that the thread ID for c and g-class operations is set to
the CPU we provide when reporting VM stop conditions. If the stub is
still tuned to a different CPU, the wrong information is delivered to
the gdb frontend.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-07-27 22:46:16 +03:00
Marc-André Lureau
801db5ecda qapi: add missing @
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-07-27 22:44:47 +03:00
Johannes Schlatow
786f9ce203 Fix Cortex-A9 global timer
The auto increment bit of the timer control register was wrongly
defined.

See Cortex-A9 MPcore Technical Reference Manual, Section 4.4.2.

Signed-off-by: Johannes Schlatow <schlatow@ida.ing.tu-bs.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-07-27 22:44:47 +03:00
Michal Privoznik
7e71e111e0 gitignore: Ignore shader generated files
As of d98bc0b65 there are two files that are automatically generated:
ui/shader/texture-blit-frag.h and /ui/shader/texture-blit-vert.h. None
of them is wanted to be tracked by git. Put them into the ignore file
then.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-07-27 22:44:47 +03:00
Marc-André Lureau
7155f2ca9d vmstate: remove unused declaration
Since 38e0735e, register_device_unmigratable() has been removed

Signed-off-by: Marc-André Lureau <marcandre.lureau@gmail.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-07-27 22:44:47 +03:00
Stefan Weil
f6288b9c88 make: Clean build messages
We want to have uniform build messages, so fix some messages
which did not follow the standard pattern.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-07-27 22:44:47 +03:00
Peter Maydell
ab60366308 qemu-common.h: Document cutils.c string functions
Add documentation comments for various utility string functions
which we have implemented in util/cutils.c:
 pstrcpy()
 strpadcpy()
 pstrcat()
 strstart()
 stristart()
 qemu_strnlen()
 qemu_strsep()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-07-27 22:44:47 +03:00
Kamalesh Babulal
cc47a16bcb device_tree: Fix a typo
Fix spelling of 'allocting' -> 'allocating'.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-07-27 22:44:47 +03:00
Laszlo Ersek
f3c30aeaa7 hw/acpi/ich9: clean up stale comment about KVM not supporting SMM
Commit fba72476c6 ("ich9: add smm_enabled field and arguments") detached
SMM availability from kvm_enabled(). However, the comment in pm_reset()
was not updated; let's do it now.

Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-trivial@nongnu.org
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-07-27 22:44:47 +03:00
Laszlo Ersek
be66680e83 hw/acpi/ich9: clear smi_en on reset
Otherwise on reboot firmware might think (due to APMC_EN remaining set
from the previous boot) that SMI support is absent.

Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-trivial@nongnu.org
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2015-07-27 22:44:47 +03:00
Peter Maydell
f8787f8723 Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20150727' into staging
Fix buglets for 2.4

# gpg: Signature made Mon Jul 27 15:26:48 2015 BST using RSA key ID 4DD0279B
# gpg: Good signature from "Richard Henderson <rth7680@gmail.com>"
# gpg:                 aka "Richard Henderson <rth@redhat.com>"
# gpg:                 aka "Richard Henderson <rth@twiddle.net>"

* remotes/rth/tags/pull-tcg-20150727:
  tcg: mark temps as mem_coherent = 0 for mov with a constant
  tcg: correctly mark dead inputs for mov with a constant

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-27 19:37:09 +01:00
Paolo Bonzini
edec47cfef main-loop: fix qemu_notify_event for aio_notify optimization
aio_notify can be optimized away, and in fact almost always will.  However,
qemu_notify_event is used in places where this is incorrect---most notably,
when handling SIGTERM.  When aio_notify is optimized away, it is possible that
QEMU enters a blocking ppoll immediately afterwards and stays there, without
reaching main_loop_should_exit().

Fix this by using a bottom half.  The bottom half can be optimized too, but
scheduling it is enough for the ppoll not to block.  The hang is thus avoided.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1437738175-23624-1-git-send-email-pbonzini@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-27 17:12:19 +01:00
Jeff Cody
77c102c26e block: qemu-iotests - add check for multiplication overflow in vpc
This checks that VPC is able to successfully fail (without segfault)
on an image file with a max_table_entries that exceeds 0x40000000.

This table entry is within the valid range for VPC (although too large
for this sample image).

Cc: qemu-stable@nongnu.org
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-07-27 17:19:07 +02:00
Jeff Cody
b15deac795 block: vpc - prevent overflow if max_table_entries >= 0x40000000
When we allocate the pagetable based on max_table_entries, we multiply
the max table entry value by 4 to accomodate a table of 32-bit integers.
However, max_table_entries is a uint32_t, and the VPC driver accepts
ranges for that entry over 0x40000000.  So during this allocation:

s->pagetable = qemu_try_blockalign(bs->file, s->max_table_entries * 4);

The size arg overflows, allocating significantly less memory than
expected.

Since qemu_try_blockalign() size argument is size_t, cast the
multiplication correctly to prevent overflow.

The value of "max_table_entries * 4" is used elsewhere in the code as
well, so store the correct value for use in all those cases.

We also check the Max Tables Entries value, to make sure that it is <
SIZE_MAX / 4, so we know the pagetable size will fit in size_t.

Cc: qemu-stable@nongnu.org
Reported-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-07-27 17:19:06 +02:00
Peter Maydell
3737129917 configure: Work around broken static pkg-config info for Ubuntu gnutls
Unfortunately Ubuntu's pkg-config information for gnutls is broken
for the static linking case, and outputs --libs options which the
compiler does not recognize. Work around this problem by testing
that the --cflags/--libs output will at least allow compilation
before enabling gnutls support.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 1437758888-22486-1-git-send-email-peter.maydell@linaro.org
2015-07-27 16:15:32 +01:00
Jason Wang
c9b11f971c virtio-blk: only clear VIRTIO_F_ANY_LAYOUT for legacy device
Chapter 6.3 of spec said

"
Transitional devices MUST offer, and if offered by the device
transitional drivers MUST accept the following:

VIRTIO_F_ANY_LAYOUT (27)
"

So this patch only clear VIRTIO_F_LAYOUT for legacy device.

Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: qemu-block@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-27 18:11:53 +03:00
Jason Wang
efb8206ca7 virtio-blk: fail get_features when both scsi and 1.0 were set
SCSI passthrough was no longer supported in virtio 1.0, so this patch
fail the get_features() when both 1.0 and scsi is set. And also only
advertise VIRTIO_BLK_F_SCSI for legacy virtio-blk device.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-27 18:11:53 +03:00
Jason Wang
9d5b731dd2 virtio: get_features() can fail
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-27 18:11:53 +03:00
Michael S. Tsirkin
27462695cd virtio-pci: fix memory MR cleanup for modern
Each memory_region_add_subregion must be paired with
memory_region_del_subregion.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-27 18:11:53 +03:00
Aurelien Jarno
bbeb82395e tcg: mark temps as mem_coherent = 0 for mov with a constant
When a constant has to be loaded in a mov op, we fail to set
mem_coherent = 0. This patch fixes that.

Cc: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Message-Id: <1437994568-7825-3-git-send-email-aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2015-07-27 07:25:40 -07:00
Aurelien Jarno
7df69deadf tcg: correctly mark dead inputs for mov with a constant
When tcg_reg_alloc_mov propagate a constant, we failed to correctly mark
a temp as dead if the liveness analysis hints so. This fixes the
following assert when configure with --enable-debug-tcg:

  qemu-x86_64: tcg/tcg.c:1827: tcg_reg_alloc_bb_end: Assertion `ts->val_type == TEMP_VAL_DEAD' failed.

Cc: Richard Henderson <rth@twiddle.net>
Reported-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Message-Id: <1437994568-7825-2-git-send-email-aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2015-07-27 07:25:40 -07:00
Peter Maydell
122e7dab8a Merge remote-tracking branch 'remotes/stefanha/tags/net-pull-request' into staging
Pull request

Here are NIC fixes from Fam Zheng that prevent rx hangs (caused by NIC models
where .can_receive() stops rx but qemu_flush_queued_packets() isn't called).

# gpg: Signature made Mon Jul 27 14:51:48 2015 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/net-pull-request:
  axienet: Flush queued packets when rx is done
  dp8393x: Flush packets when link comes up
  stellaris_enet: Flush queued packets when read done
  mipsnet: Flush queued packets when receiving is enabled
  milkymist-minimac2: Flush queued packets when link comes up
  mcf_fec: Drop mcf_fec_can_receive
  etsec: Flush queue when rx buffer is consumed
  etsec: Move etsec_can_receive into etsec_receive
  usbnet: Drop usbnet_can_receive
  eepro100: Drop nic_can_receive
  pcnet: Drop pcnet_can_receive
  xgmac: Drop packets with eth_can_rx is false.
  hw/net: fix mcf_fec driver receiver
  hw/net: add simple phy support to mcf_fec driver
  hw/net: add ANLPAR bit definitions to generic mii
  hw/net: create common collection of MII definitions

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-27 14:53:42 +01:00
Fam Zheng
f9f7492ea4 axienet: Flush queued packets when rx is done
eth_can_rx checks s->rxsize and returns false if it is non-zero. Because
of the .can_receive semantics change, this will make the incoming queue
disabled by peer, until it is explicitly flushed. So we should flush it
when s->rxsize is becoming zero.

Squash eth_can_rx semantics into etx_rx and drop .can_receive()
callback, also add flush when rx buffer becomes available again after a
packet gets queued.

The other conditions, "!axienet_rx_resetting(s) &&
axienet_rx_enabled(s)" are OK because enet_write already calls
qemu_flush_queued_packets when the register bits are changed.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1436955553-22791-13-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:18 +01:00
Fam Zheng
4594f93a73 dp8393x: Flush packets when link comes up
.can_receive callback changes semantics that once return 0, backend will
try sending again until explicitly flushed, change the device to meet
that.

dp8393x_can_receive checks SONIC_CR_RXEN bit in SONIC_CR register and
SONIC_ISR_RBE bit in SONIC_ISR register, try flushing the queue when
either bit is being updated.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Message-id: 1436955553-22791-12-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:18 +01:00
Fam Zheng
1ef4a6069f stellaris_enet: Flush queued packets when read done
If s->np reaches 31, the queue will be disabled by peer when it sees
stellaris_enet_can_receive() returns false, until we explicitly flushes
it which notifies the peer. Do this when guest is done reading all
existing data.

Move the semantics to stellaris_enet_receive, by returning 0 when the
buffer is full, so that new packets will be queued.  In
stellaris_enet_read, flush and restart the queue when guest has done
reading.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Message-id: 1436955553-22791-11-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:18 +01:00
Fam Zheng
1dd58ae058 mipsnet: Flush queued packets when receiving is enabled
Drop .can_receive and move the semantics to mipsnet_receive, by
returning 0.

After 0 is returned, we must flush the queue explicitly to restart it:
Call qemu_flush_queued_packets when s->busy or s->rx_count is being
updated.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Message-id: 1436955553-22791-10-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:18 +01:00
Fam Zheng
3b7031e960 milkymist-minimac2: Flush queued packets when link comes up
Drop .can_receive and move the semantics into minimac2_rx, by returning
0.

That is once minimac2_rx returns 0, incoming packets will be queued
until the queue is explicitly flushed. We do this when s->regs[R_STATE0]
or s->regs[R_STATE1] is changed in minimac2_write.

Also drop the unused trace point.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1436955553-22791-9-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:18 +01:00
Fam Zheng
e813f0d881 mcf_fec: Drop mcf_fec_can_receive
The semantics of .can_receive requires us to flush the queue explicitly
when s->rx_enabled becomes true after it returns 0, but the packet being
queued is not meaningful since the guest hasn't activated the card.
Let's just drop the packet in this case.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Message-id: 1436955553-22791-8-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:18 +01:00
Fam Zheng
575bafd1f3 etsec: Flush queue when rx buffer is consumed
The BH will be scheduled when etsec->rx_buffer_len is becoming 0, which
is the condition of queuing.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1436955553-22791-7-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:18 +01:00
Fam Zheng
b6cb6610c2 etsec: Move etsec_can_receive into etsec_receive
When etsec_reset returns 0, peer would queue the packet as if
.can_receive returns false. Drop etsec_can_receive and let etsec_receive
carry the semantics.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Message-id: 1436955553-22791-6-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:18 +01:00
Fam Zheng
913440249e usbnet: Drop usbnet_can_receive
usbnet_receive already drops packet if rndis_state is not
RNDIS_DATA_INITIALIZED, and queues packet if in buffer is not available.
The only difference is s->dev.config but that is similar to rndis_state.

Drop usbnet_can_receive and move these checks to usbnet_receive, so that
we don't need to explicitly flush the queue when s->dev.config changes
value.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Message-id: 1436955553-22791-5-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:18 +01:00
Fam Zheng
363db4b249 eepro100: Drop nic_can_receive
nic_receive already checks the conditions and drop packets if false.
Due to the new semantics since 6e99c63 ("net/socket: Drop
net_socket_can_send"), having .can_receive returning 0 requires us to
explicitly flush the queued packets when the conditions are becoming
true, but queuing the packets when guest driver is not ready doesn't
make much sense.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Message-id: 1436955553-22791-4-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:18 +01:00
Fam Zheng
b0ba0b9b6b pcnet: Drop pcnet_can_receive
pcnet_receive already checks the conditions and drop packets if false.
Due to the new semantics since 6e99c63 ("net/socket: Drop
net_socket_can_send"), having .can_receive returning 0 requires us to
explicitly flush the queued packets when the conditions are becoming
true, but queuing the packets when guest driver is not ready doesn't
make much sense.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Message-id: 1436955553-22791-3-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:18 +01:00
Fam Zheng
8c8c460c5f xgmac: Drop packets with eth_can_rx is false.
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Message-id: 1436955553-22791-2-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:18 +01:00
Greg Ungerer
491a1f494e hw/net: fix mcf_fec driver receiver
The network mcf_fec driver emulated receive side method is returning a
result of 0 causing the network layer to disable receive for this emulated
device. This results in the guest only ever receiving one packet.

Fix the recieve side processing to return the number of bytes that we
passed back through to the guest.

Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1435296436-12152-5-git-send-email-gerg@uclinux.org
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:04 +01:00
Greg Ungerer
299f7bec5a hw/net: add simple phy support to mcf_fec driver
The Linux fec driver needs at least basic phy support to probe and work.
The current qemu mcf_fec emulation has no support for the reading or
writing of the MDIO lines to access an attached phy.

This code adds a very simple set of register results for a fixed phy
setup - very similar to that used on an m5208evb board. This is enough
to probe and identify an emulated attached phy.

Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1435296436-12152-4-git-send-email-gerg@uclinux.org
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:04 +01:00
Greg Ungerer
3634869b27 hw/net: add ANLPAR bit definitions to generic mii
Add a base set of bit definitions for the standard MII phy "Auto-Negotiation
Link Partner Ability Register" (ANLPAR).

The original definitions moved into mii.h from the allwinner_emac driver
did not define these.

Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1435296436-12152-3-git-send-email-gerg@uclinux.org
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:04 +01:00
Greg Ungerer
3e230569bf hw/net: create common collection of MII definitions
Create a common set of definitions of address and register values for
ethernet MII phys. A few of the current ethernet drivers have at least
a partial set of these definitions. Others just use hard coded raw
constant numbers.

This initial set is copied directly from the allwinner_emac code.

Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1435296436-12152-2-git-send-email-gerg@uclinux.org
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-27 14:12:04 +01:00
Peter Maydell
e40db4c6d3 Merge remote-tracking branch 'remotes/jnsnow/tags/cve-2015-5154-pull-request' into staging
# gpg: Signature made Mon Jul 27 13:01:10 2015 BST using RSA key ID AAFC390E
# gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: FAEB 9711 A12C F475 812F  18F2 88A9 064D 1835 61EB
#      Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76  CBD0 7DEF 8106 AAFC 390E

* remotes/jnsnow/tags/cve-2015-5154-pull-request:
  ide: Clear DRQ after handling all expected accesses
  ide/atapi: Fix START STOP UNIT command completion
  ide: Check array bounds before writing to io_buffer (CVE-2015-5154)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-27 13:10:00 +01:00
Daniel P. Berrange
019c2ab862 crypto: extend unit tests to cover decryption too
The current unit test only verifies the encryption API,
resulting in us missing a recently introduced bug in the
decryption API from commit d3462e3. It was fortunately
later discovered & fixed by commit bd09594, thanks to the
QEMU I/O tests for qcow2 encryption, but we should really
detect this directly in the crypto unit tests. Also remove
an accidental debug message and simplify some asserts.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-Id: <1437468902-23230-1-git-send-email-berrange@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-27 12:22:01 +02:00
Daniel P. Berrange
6775e2c429 crypto: fix built-in AES decrypt function
The qcrypto_cipher_decrypt_aes method was using the wrong
key material, and passing the wrong mode. This caused it
to incorrectly decrypt ciphertext.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-Id: <1437740634-6261-1-git-send-email-berrange@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-27 12:22:01 +02:00
Michael S. Tsirkin
09999a5f7f virtio: set any_layout in virtio core
Exceptions:
    - virtio-blk
    - compat machine types

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2015-07-27 11:24:48 +03:00
Michael S. Tsirkin
cd4bfbb20d virtio-9p: fix any_layout
virtio pci allows any device to have a modern interface,
this in turn requires ANY_LAYOUT support.
Fix up ANY_LAYOUT for virtio-9p.

Reported-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
2015-07-27 11:24:48 +03:00
Michael S. Tsirkin
7882080388 virtio-serial: fix ANY_LAYOUT
Don't assume a specific layout for control messages.
Required by virtio 1.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
2015-07-27 11:24:48 +03:00
Michael S. Tsirkin
5f456073aa virtio: hide legacy features from modern guests
NOTIFY_ON_EMPTY, ANY_LAYOUT and BAD are only valid on the legacy
interface.

Hide them from modern guests.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2015-07-27 09:08:50 +03:00
Kevin Wolf
cb72cba830 ide: Clear DRQ after handling all expected accesses
This is additional hardening against an end_transfer_func that fails to
clear the DRQ status bit. The bit must be unset as soon as the PIO
transfer has completed, so it's better to do this in a central place
instead of duplicating the code in all commands (and forgetting it in
some).

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
2015-07-26 23:42:53 -04:00
Kevin Wolf
03441c3a4a ide/atapi: Fix START STOP UNIT command completion
The command must be completed on all code paths. START STOP UNIT with
pwrcnd set should succeed without doing anything.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
2015-07-26 23:42:53 -04:00
Kevin Wolf
d2ff858545 ide: Check array bounds before writing to io_buffer (CVE-2015-5154)
If the end_transfer_func of a command is called because enough data has
been read or written for the current PIO transfer, and it fails to
correctly call the command completion functions, the DRQ bit in the
status register and s->end_transfer_func may remain set. This allows the
guest to access further bytes in s->io_buffer beyond s->data_end, and
eventually overflowing the io_buffer.

One case where this currently happens is emulation of the ATAPI command
START STOP UNIT.

This patch fixes the problem by adding explicit array bounds checks
before accessing the buffer instead of relying on end_transfer_func to
function correctly.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
2015-07-26 23:42:53 -04:00
Peter Maydell
f793d97e45 Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* qemu-char fixes
* SCSI fixes (including CVE-2015-5158)
* RCU fixes
* Framebuffer logic to set DIRTY_MEMORY_VGA
* Fix compiler warning for --disable-vnc
* qemu-doc fixes
* x86 TCG pasto fix

# gpg: Signature made Fri Jul 24 12:57:52 2015 BST using RSA key ID 78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream:
  target-i386/FPU: a misprint in helper_fistll_ST0
  qemu-doc: fix typos
  framebuffer: set DIRTY_MEMORY_VGA on RAM that is used for the framebuffer
  memory: count number of active VGA logging clients
  vl: Fix compiler warning for builds without VNC
  scsi: Handle no media case for scsi_get_configuration
  rcu: actually register threads that have RCU read-side critical sections
  scsi: fix buffer overflow in scsi_req_parse_cdb (CVE-2015-5158)
  vnc: fix memory leak
  qemu-char: Fix missed data on unix socket
  qemu-char: handle EINTR for TCP character devices
  exec.c: Use atomic_rcu_read() to access dispatch in memory_region_section_get_iotlb()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-24 13:07:10 +01:00
Dmitry Poletaev
178846bdd9 target-i386/FPU: a misprint in helper_fistll_ST0
There is a cut-and-paste mistake in the patch
https://lists.gnu.org/archive/html/qemu-devel/2014-11/msg01657.html .
It cause errors in guest work.  Here is the bugfix.

Signed-off-by: Dmitry Poletaev <poletaev-qemu@yandex.ru>
Reported-by: Kirill Batuzov <batuzovk@ispras.ru>
Message-Id: <2692911436348920@web2m.yandex.ru>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-24 13:57:45 +02:00
Gonglei
d274e07c6d qemu-doc: fix typos
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Message-Id: <1435917057-9396-1-git-send-email-arei.gonglei@huawei.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-24 13:57:45 +02:00
Paolo Bonzini
c1076c3e13 framebuffer: set DIRTY_MEMORY_VGA on RAM that is used for the framebuffer
The MemoryRegionSection contains enough information to access the
RAM region underlying the framebuffer, and can be cached inside the
display device.

By doing this, the new framebuffer_update_memory_section function can
enable dirty memory logging on the relevant RAM region.  The function
must be called whenever the stride or base of the framebuffer changes;
a simple way to cover these cases is to call it on every full frame
invalidation, which is a rare case.

framebuffer_update_display now works entirely on a MemoryRegionSection,
without going through cpu_physical_memory_map/unmap.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-24 13:57:45 +02:00
Paolo Bonzini
deb809edb8 memory: count number of active VGA logging clients
For a board that has multiple framebuffer devices, both of them
might want to use DIRTY_MEMORY_VGA on the same memory region.
The lack of reference counting in memory_region_set_log makes
this very awkward to implement.

Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-24 13:57:45 +02:00
Stefan Weil
fb43096959 vl: Fix compiler warning for builds without VNC
This regression was caused by commit 70b94331.

  CC    vl.o
vl.c: In function ‘select_display’:
vl.c:2064:12: error: unused variable ‘err’ [-Werror=unused-variable]
     Error *err = NULL;
            ^

Reported-by: Claudio Fontana <claudio.fontana@huawei.com>
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Message-Id: <1437587610-26433-1-git-send-email-sw@weilnetz.de>
Reviewed-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-24 13:57:45 +02:00
Matthew Rosato
7d99f4c1b5 scsi: Handle no media case for scsi_get_configuration
Currently, scsi_get_configuration always returns a current
profile (DVD or CD), even when there is actually no media present.
By comparison, ide/atapi uses a default profile of 0 (MMC_PROFILE_NONE)
for this case and checks for tray_open, so let's do the same for scsi.

This fixes a problem I'm seeing with Fedora 22 guests where systemd
cdrom_id fails to unmount after a QEMU-initiated eject against a
scsi cdrom device because it believes the media is still present
(but unreadable).

Signed-off-by: Matthew Rosato <mjrosato@linux.vnet.ibm.com>
Message-Id: <1436986352-10695-1-git-send-email-mjrosato@linux.vnet.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-24 13:57:45 +02:00
Paolo Bonzini
ab28bd2312 rcu: actually register threads that have RCU read-side critical sections
Otherwise, grace periods are detected too early!

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-24 13:57:45 +02:00
Paolo Bonzini
c170aad8b0 scsi: fix buffer overflow in scsi_req_parse_cdb (CVE-2015-5158)
This is a guest-triggerable buffer overflow present in QEMU 2.2.0
and newer.  scsi_cdb_length returns -1 as an error value, but the
caller does not check it.

Luckily, the massive overflow means that QEMU will just SIGSEGV,
making the impact much smaller.

Reported-by: Zhu Donghai (朱东海) <donghai.zdh@alibaba-inc.com>
Fixes: 1894df0281
Reviewed-by: Fam Zheng <famz@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-24 13:57:44 +02:00
Gonglei
60928458e5 vnc: fix memory leak
If vnc's password is configured, it will leak memory
which cipher variable pointed on every vnc connection.

Cc: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Message-Id: <1437556133-11268-1-git-send-email-arei.gonglei@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-24 13:57:44 +02:00
Peter Maydell
30fdfae49d Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20150723' into staging
Last minute fixes for 2.4.

# gpg: Signature made Fri Jul 24 04:42:31 2015 BST using RSA key ID 4DD0279B
# gpg: Good signature from "Richard Henderson <rth7680@gmail.com>"
# gpg:                 aka "Richard Henderson <rth@redhat.com>"
# gpg:                 aka "Richard Henderson <rth@twiddle.net>"

* remotes/rth/tags/pull-tcg-20150723:
  tcg/optimize: fix tcg_opt_gen_movi
  tcg/aarch64: use 32-bit offset for 32-bit softmmu emulation
  tcg/aarch64: use 32-bit offset for 32-bit user-mode emulation
  tcg/aarch64: add ext argument to tcg_out_insn_3310
  tcg/i386: Extend addresses for 32-bit guests

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-24 11:11:30 +01:00
Peter Maydell
f75b709853 Merge remote-tracking branch 'remotes/awilliam/tags/vfio-fixes-20150723.0' into staging
VFIO fixes for v2.4.0-rc3
- Fix Realtek NIC quirk (Alex Williamson)
- Restore bootindex functionality (Alex Williamson)

# gpg: Signature made Thu Jul 23 19:51:23 2015 BST using RSA key ID 3BB08B22
# gpg: Good signature from "Alex Williamson <alex.williamson@redhat.com>"
# gpg:                 aka "Alex Williamson <alex@shazbot.org>"
# gpg:                 aka "Alex Williamson <alwillia@redhat.com>"
# gpg:                 aka "Alex Williamson <alex.l.williamson@gmail.com>"

* remotes/awilliam/tags/vfio-fixes-20150723.0:
  vfio/pci: Fix bootindex
  vfio/pci: Fix RTL8168 NIC quirks

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-24 09:17:44 +01:00
Aurelien Jarno
961521261a tcg/optimize: fix tcg_opt_gen_movi
Due to a copy&paste, the new op value is tested against mov_i32 instead
of movi_i32. The test is therefore always false. Fix that.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Message-Id: <1436544211-2769-1-git-send-email-aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2015-07-23 20:37:12 -07:00
Richard Henderson
80adb8fcad tcg/aarch64: use 32-bit offset for 32-bit softmmu emulation
Similar to the same fix for user-mode, except this instance
occurs on the softmmu path.  Again, the tlb addend must be
the base register, while the guest address is the index.

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2015-07-23 20:19:44 -07:00
Paolo Bonzini
ffc6372851 tcg/aarch64: use 32-bit offset for 32-bit user-mode emulation
Thanks to the previous patch, it is now easy for tcg_out_qemu_ld and
tcg_out_qemu_st to use a 32-bit zero extended offset.  However, the
guest base register x28 must be the base and addr_reg must be the
index.

Reported-by: Leon Alrae <leon.alrae@imgtec.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <1436974021-28978-3-git-send-email-pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2015-07-23 15:09:12 -07:00
Paolo Bonzini
6c0f0c0f12 tcg/aarch64: add ext argument to tcg_out_insn_3310
The new argument lets you pick uxtw or uxtx mode for the offset
register.  For now, all callers pass TCG_TYPE_I64 so that uxtx
is generated.  The bits for uxtx are removed from I3312_TO_I3310.

Reported-by: Leon Alrae <leon.alrae@imgtec.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <1436974021-28978-2-git-send-email-pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2015-07-23 15:09:04 -07:00
Richard Henderson
ee8ba9e4d8 tcg/i386: Extend addresses for 32-bit guests
Removing the ??? comment explaining why it (mostly) worked.

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Message-Id: <1437081950-7206-2-git-send-email-rth@twiddle.net>
2015-07-23 15:09:04 -07:00
Peter Maydell
12e21eb088 Merge remote-tracking branch 'remotes/ehabkost/tags/numa-pull-request' into staging
NUMA queue, 2015-07-22

# gpg: Signature made Wed Jul 22 19:11:04 2015 BST using RSA key ID 984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF  D1AA 2807 936F 984D C5A6

* remotes/ehabkost/tags/numa-pull-request:
  hostmem: Fix qemu_opt_get_bool() crash in host_memory_backend_init()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-23 12:54:53 +01:00
Nils Carlson
4bf1cb03fb qemu-char: Fix missed data on unix socket
Commit 812c1057 introduced HUP detection on unix and tcp sockets prior
to a read in tcp_chr_read. This unfortunately broke CloudStack 4.2
which relied on the old behaviour where data on a socket was readable
even if a HUP was present.

A working solution is to properly check the return values from recv,
handling a closed socket once there is no more data to read.

Also enable polling for G_IO_NVAL to ensure the callback is called
for all possible events as these should now be possible to handle
with the improved error detection.

Signed-off-by: Nils Carlson <pyssling@ludd.ltu.se>
Message-Id: <1437338396-22336-1-git-send-email-pyssling@ludd.ltu.se>
[Do not handle EINTR; use socket_error(). - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-23 07:37:38 +02:00
Paolo Bonzini
9172f428af qemu-char: handle EINTR for TCP character devices
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-23 07:37:38 +02:00
Peter Maydell
0b8e2c1002 exec.c: Use atomic_rcu_read() to access dispatch in memory_region_section_get_iotlb()
When accessing the dispatch pointer in an AddressSpace within an RCU
critical section we should always use atomic_rcu_read(). Fix an
access within memory_region_section_get_iotlb() which was incorrectly
doing a direct pointer access.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <1437391637-31576-1-git-send-email-peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-23 07:37:38 +02:00
Alex Williamson
759b484c5d vfio/pci: Fix bootindex
bootindex was incorrectly changed to a device Property during the
platform code split, resulting in it no longer working.  Remove it.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Cc: qemu-stable@nongnu.org # v2.3+
2015-07-22 14:56:01 -06:00
Alex Williamson
69970fcef9 vfio/pci: Fix RTL8168 NIC quirks
The RTL8168 quirk correctly describes using bit 31 as a signal to
mark a latch/completion, but the code mistakenly uses bit 28.  This
causes the Realtek driver to spin on this register for quite a while,
20k cycles on Windows 7 v7.092 driver.  Then it gets frustrated and
tries to set the bit itself and spins for another 20k cycles.  For
some this still results in a working driver, for others not.  About
the only thing the code really does in its current form is protect
the guest from sneaking in writes to the real hardware MSI-X table.
The fix is obviously to use bit 31 as we document that we should.

The other problem doesn't seem to affect current drivers as nobody
seems to use these window registers for writes to the MSI-X table, but
we need to use the stored data when a write is triggered, not the
value of the current write, which only provides the offset.

Note that only the Windows drivers from Realtek seem to use these
registers, the Microsoft drivers provided with Windows 8.1 do not
access them, nor do Linux in-kernel drivers.

Link: https://bugs.launchpad.net/qemu/+bug/1384892
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Cc: qemu-stable@nongnu.org # v2.1+
2015-07-22 14:56:01 -06:00
Eduardo Habkost
6b2699672d hostmem: Fix qemu_opt_get_bool() crash in host_memory_backend_init()
This fixes the following crash, introduced by commit
49d2e648e8:

  $ gdb --args qemu-system-x86_64 -machine pc,mem-merge=off -object memory-backend-ram,id=ram-node0,size=1024
  [...]
  Program received signal SIGABRT, Aborted.
  (gdb) bt
  #0  0x00007ffff253b8c7 in raise () at /lib64/libc.so.6
  #1  0x00007ffff253d52a in abort () at /lib64/libc.so.6
  #2  0x00007ffff253446d in __assert_fail_base () at /lib64/libc.so.6
  #3  0x00007ffff2534522 in  () at /lib64/libc.so.6
  #4  0x00005555558bb80a in qemu_opt_get_bool_helper (opts=0x55555621b650, name=name@entry=0x5555558ec922 "mem-merge", defval=defval@entry=true, del=del@entry=false) at qemu/util/qemu-option.c:388
  #5  0x00005555558bbb5a in qemu_opt_get_bool (opts=<optimized out>, name=name@entry=0x5555558ec922 "mem-merge", defval=defval@entry=true) at qemu/util/qemu-option.c:398
  #6  0x0000555555720a24 in host_memory_backend_init (obj=0x5555562ac970) at qemu/backends/hostmem.c:226

Instead of using qemu_opt_get_bool(), that didn't work with
qemu_machine_opts for a long time, we can use the corresponding
MachineState fields.

Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2015-07-22 15:09:25 -03:00
Peter Maydell
b69b30532e Update version for v2.4.0-rc2 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-22 18:17:19 +01:00
Peter Maydell
3edf6b3f1e Merge remote-tracking branch 'remotes/elmarco/tags/for-upstream' into staging
qxl: build fix for 2.4

# gpg: Signature made Wed Jul 22 15:55:00 2015 BST using DSA key ID F43F0992
# gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>"
# gpg:                 aka "Marc-Andre Lureau <marcandre.lureau@gmail.com>"
# gpg:                 aka "Marc-Andre Lureau <marc-andre.lureau@nokia.com>"
# gpg:                 aka "Marc-André Lureau <marc-andre.lureau@nokia.com>"
# gpg:                 aka "Marc-André Lureau (elmarco) <marcandre.lureau@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: 7346 2483 9404 4E20 ABFF  7D48 D864 9487 F43F 0992

* remotes/elmarco/tags/for-upstream:
  qxl: Fix new function name for spice-server library

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-22 16:22:49 +01:00
Frediano Ziglio
a52b2cbf21 qxl: Fix new function name for spice-server library
The new spice-server function to limit the number of monitors (0.12.6)
changed while development from spice_qxl_set_monitors_config_limit to
spice_qxl_max_monitors (accepted upstream).
By mistake I post patch with former name.
This patch fix the function name.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
Acked-by: Martin Kletzander <mkletzan@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2015-07-22 16:38:42 +02:00
Peter Maydell
dc94bd9166 Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
# gpg: Signature made Wed Jul 22 12:43:35 2015 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/block-pull-request:
  AioContext: optimize clearing the EventNotifier
  AioContext: fix broken placement of event_notifier_test_and_clear
  AioContext: fix broken ctx->dispatching optimization
  aio-win32: reorganize polling loop
  tests: remove irrelevant assertions from test-aio
  qemu-timer: initialize "timers_done_ev" to set
  mirror: Speed up bitmap initial scanning

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-22 12:52:34 +01:00
Paolo Bonzini
05e514b1d4 AioContext: optimize clearing the EventNotifier
It is pretty rare for aio_notify to actually set the EventNotifier.  It
can happen with worker threads such as thread-pool.c's, but otherwise it
should never be set thanks to the ctx->notify_me optimization.  The
previous patch, unfortunately, added an unconditional call to
event_notifier_test_and_clear; now add a userspace fast path that
avoids the call.

Note that it is not possible to do the same with event_notifier_set;
it would break, as proved (again) by the included formal model.

This patch survived over 3000 reboots on aarch64 KVM.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
Message-id: 1437487673-23740-7-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-22 12:41:40 +01:00
Paolo Bonzini
21a03d17f2 AioContext: fix broken placement of event_notifier_test_and_clear
event_notifier_test_and_clear must be called before processing events.
Otherwise, an aio_poll could "eat" the notification before the main
I/O thread invokes ppoll().  The main I/O thread then never wakes up.
This is an example of what could happen:

   i/o thread       vcpu thread                     worker thread
   ---------------------------------------------------------------------
   lock_iothread
   notify_me = 1
   ...
   unlock_iothread
                                                     bh->scheduled = 1
                                                     event_notifier_set
                    lock_iothread
                    notify_me = 3
                    ppoll
                    notify_me = 1
                    aio_dispatch
                     aio_bh_poll
                      thread_pool_completion_bh
                                                     bh->scheduled = 1
                                                     event_notifier_set
                     node->io_read(node->opaque)
                      event_notifier_test_and_clear
   ppoll
   *** hang ***

"Tracing" with qemu_clock_get_ns shows pretty much the same behavior as
in the previous bug, so there are no new tricks here---just stare more
at the code until it is apparent.

One could also use a formal model, of course.  The included one shows
this with three processes: notifier corresponds to a QEMU thread pool
worker, temporary_waiter to a VCPU thread that invokes aio_poll(),
waiter to the main I/O thread.  I would be happy to say that the
formal model found the bug for me, but actually I wrote it after the
fact.

This patch is a bit of a big hammer.  The next one optimizes it,
with help (this time for real rather than a posteriori :)) from
another, similar formal model.

Reported-by: Richard W. M. Jones <rjones@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
Message-id: 1437487673-23740-6-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-22 12:41:40 +01:00
Paolo Bonzini
eabc977973 AioContext: fix broken ctx->dispatching optimization
This patch rewrites the ctx->dispatching optimization, which was the cause
of some mysterious hangs that could be reproduced on aarch64 KVM only.
The hangs were indirectly caused by aio_poll() and in particular by
flash memory updates's call to blk_write(), which invokes aio_poll().
Fun stuff: they had an extremely short race window, so much that
adding all kind of tracing to either the kernel or QEMU made it
go away (a single printf made it half as reproducible).

On the plus side, the failure mode (a hang until the next keypress)
made it very easy to examine the state of the process with a debugger.
And there was a very nice reproducer from Laszlo, which failed pretty
often (more than half of the time) on any version of QEMU with a non-debug
kernel; it also failed fast, while still in the firmware.  So, it could
have been worse.

For some unknown reason they happened only with virtio-scsi, but
that's not important.  It's more interesting that they disappeared with
io=native, making thread-pool.c a likely suspect for where the bug arose.
thread-pool.c is also one of the few places which use bottom halves
across threads, by the way.

I hope that no other similar bugs exist, but just in case :) I am
going to describe how the successful debugging went...  Since the
likely culprit was the ctx->dispatching optimization, which mostly
affects bottom halves, the first observation was that there are two
qemu_bh_schedule() invocations in the thread pool: the one in the aio
worker and the one in thread_pool_completion_bh.  The latter always
causes the optimization to trigger, the former may or may not.  In
order to restrict the possibilities, I introduced new functions
qemu_bh_schedule_slow() and qemu_bh_schedule_fast():

     /* qemu_bh_schedule_slow: */
     ctx = bh->ctx;
     bh->idle = 0;
     if (atomic_xchg(&bh->scheduled, 1) == 0) {
         event_notifier_set(&ctx->notifier);
     }

     /* qemu_bh_schedule_fast: */
     ctx = bh->ctx;
     bh->idle = 0;
     assert(ctx->dispatching);
     atomic_xchg(&bh->scheduled, 1);

Notice how the atomic_xchg is still in qemu_bh_schedule_slow().  This
was already debated a few months ago, so I assumed it to be correct.
In retrospect this was a very good idea, as you'll see later.

Changing thread_pool_completion_bh() to qemu_bh_schedule_fast() didn't
trigger the assertion (as expected).  Changing the worker's invocation
to qemu_bh_schedule_slow() didn't hide the bug (another assumption
which luckily held).  This already limited heavily the amount of
interaction between the threads, hinting that the problematic events
must have triggered around thread_pool_completion_bh().

As mentioned early, invoking a debugger to examine the state of a
hung process was pretty easy; the iothread was always waiting on a
poll(..., -1) system call.  Infinite timeouts are much rarer on x86,
and this could be the reason why the bug was never observed there.
With the buggy sequence more or less resolved to an interaction between
thread_pool_completion_bh() and poll(..., -1), my "tracing" strategy was
to just add a few qemu_clock_get_ns(QEMU_CLOCK_REALTIME) calls, hoping
that the ordering of aio_ctx_prepare(), aio_ctx_dispatch, poll() and
qemu_bh_schedule_fast() would provide some hint.  The output was:

    (gdb) p last_prepare
    $3 = 103885451
    (gdb) p last_dispatch
    $4 = 103876492
    (gdb) p last_poll
    $5 = 115909333
    (gdb) p last_schedule
    $6 = 115925212

Notice how the last call to qemu_poll_ns() came after aio_ctx_dispatch().
This makes little sense unless there is an aio_poll() call involved,
and indeed with a slightly different instrumentation you can see that
there is one:

    (gdb) p last_prepare
    $3 = 107569679
    (gdb) p last_dispatch
    $4 = 107561600
    (gdb) p last_aio_poll
    $5 = 110671400
    (gdb) p last_schedule
    $6 = 110698917

So the scenario becomes clearer:

   iothread                   VCPU thread
--------------------------------------------------------------------------
   aio_ctx_prepare
   aio_ctx_check
   qemu_poll_ns(timeout=-1)
                              aio_poll
                                aio_dispatch
                                  thread_pool_completion_bh
                                    qemu_bh_schedule()

At this point bh->scheduled = 1 and the iothread has not been woken up.
The solution must be close, but this alone should not be a problem,
because the bottom half is only rescheduled to account for rare situations
(see commit 3c80ca1, thread-pool: avoid deadlock in nested aio_poll()
calls, 2014-07-15).

Introducing a third thread---a thread pool worker thread, which
also does qemu_bh_schedule()---does bring out the problematic case.
The third thread must be awakened *after* the callback is complete and
thread_pool_completion_bh has redone the whole loop, explaining the
short race window.  And then this is what happens:

                                                      thread pool worker
--------------------------------------------------------------------------
                                                      <I/O completes>
                                                      qemu_bh_schedule()

Tada, bh->scheduled is already 1, so qemu_bh_schedule() does nothing
and the iothread is never woken up.  This is where the bh->scheduled
optimization comes into play---it is correct, but removing it would
have masked the bug.

So, what is the bug?

Well, the question asked by the ctx->dispatching optimization ("is any
active aio_poll dispatching?") was wrong.  The right question to ask
instead is "is any active aio_poll *not* dispatching", i.e. in the prepare
or poll phases?  In that case, the aio_poll is sleeping or might go to
sleep anytime soon, and the EventNotifier must be invoked to wake
it up.

In any other case (including if there is *no* active aio_poll at all!)
we can just wait for the next prepare phase to pick up the event (e.g. a
bottom half); the prepare phase will avoid the blocking and service the
bottom half.

Expressing the invariant with a logic formula, the broken one looked like:

   !(exists(thread): in_dispatching(thread)) => !optimize

or equivalently:

   !(exists(thread):
          in_aio_poll(thread) && in_dispatching(thread)) => !optimize

In the correct one, the negation is in a slightly different place:

   (exists(thread):
         in_aio_poll(thread) && !in_dispatching(thread)) => !optimize

or equivalently:

   (exists(thread): in_prepare_or_poll(thread)) => !optimize

Even if the difference boils down to moving an exclamation mark :)
the implementation is quite different.  However, I think the new
one is simpler to understand.

In the old implementation, the "exists" was implemented with a boolean
value.  This didn't really support well the case of multiple concurrent
event loops, but I thought that this was okay: aio_poll holds the
AioContext lock so there cannot be concurrent aio_poll invocations, and
I was just considering nested event loops.  However, aio_poll _could_
indeed be concurrent with the GSource.  This is why I came up with the
wrong invariant.

In the new implementation, "exists" is computed simply by counting how many
threads are in the prepare or poll phases.  There are some interesting
points to consider, but the gist of the idea remains:

1) AioContext can be used through GSource as well; as mentioned in the
patch, bit 0 of the counter is reserved for the GSource.

2) the counter need not be updated for a non-blocking aio_poll, because
it won't sleep forever anyway.  This is just a matter of checking
the "blocking" variable.  This requires some changes to the win32
implementation, but is otherwise not too complicated.

3) as mentioned above, the new implementation will not call aio_notify
when there is *no* active aio_poll at all.  The tests have to be
adjusted for this change.  The calls to aio_notify in async.c are fine;
they only want to kick aio_poll out of a blocking wait, but need not
do anything if aio_poll is not running.

4) nested aio_poll: these just work with the new implementation; when
a nested event loop is invoked, the outer event loop is never in the
prepare or poll phases.  The outer event loop thus has already decremented
the counter.

Reported-by: Richard W. M. Jones <rjones@redhat.com>
Reported-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
Message-id: 1437487673-23740-5-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-22 12:41:40 +01:00
Paolo Bonzini
6493c975af aio-win32: reorganize polling loop
Preparatory bugfixes and tweaks to the loop before the next patch:

- disable dispatch optimization during aio_prepare.  This fixes a bug.

- do not modify "blocking" until after the first WaitForMultipleObjects
call.  This is needed in the next patch.

- change the loop to do...while.  This makes it obvious that the loop
is always entered at least once.  In the next patch this is important
because the first iteration undoes the ctx->notify_me increment that
happened before entering the loop.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
Message-id: 1437487673-23740-4-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-22 12:41:40 +01:00
Paolo Bonzini
12d69ac03b tests: remove irrelevant assertions from test-aio
In these tests, the purpose of the initial calls to aio_poll and
g_main_context_iteration is simply to put the AioContext in a
known state; the return value of the function does not really
matter.  The next patch will change those return values; change
the assertions to a while loop which expresses the intention
better.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
Message-id: 1437487673-23740-3-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-22 12:41:40 +01:00
Paolo Bonzini
e4efd8a488 qemu-timer: initialize "timers_done_ev" to set
The normal value for the event is to be set.  If we do not do
this, pause_all_vcpus (through qemu_clock_enable) hangs unless
timerlist_run_timers has been run at least once for the timerlist.
This can happen with the following patches, that make aio_notify do
nothing most of the time.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
Message-id: 1437487673-23740-2-git-send-email-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-22 12:41:32 +01:00
Fam Zheng
9990069758 mirror: Speed up bitmap initial scanning
Limiting to sectors_per_chunk for each bdrv_is_allocated_above is slow,
because the underlying protocol driver would issue much more queries
than necessary. We should coalesce the query.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: <1436413678-7114-4-git-send-email-famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-22 11:14:21 +01:00
Peter Maydell
b9c4630799 Merge remote-tracking branch 'remotes/mdroth/tags/qga-pull-2015-07-21-tag' into staging
tag for qga-pull-2015-07-21

Small fix to correct schema versioning annotations for recently-added
GuestDiskBusType enum values. Not the end of the world, but ideally
this inconsistency would be corrected prior to 2.4 release.

# gpg: Signature made Tue Jul 21 20:43:24 2015 BST using RSA key ID F108B584
# gpg: Good signature from "Michael Roth <flukshun@gmail.com>"
# gpg:                 aka "Michael Roth <mdroth@utexas.edu>"
# gpg:                 aka "Michael Roth <mdroth@linux.vnet.ibm.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: CEAC C9E1 5534 EBAB B82D  3FA0 3353 C9CE F108 B584

* remotes/mdroth/tags/qga-pull-2015-07-21-tag:
  qga: fixed versions for guest bus types in qapi-schema

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-21 20:56:20 +01:00
Olga Krishtal
5f8343d067 qga: fixed versions for guest bus types in qapi-schema
Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Eric Blake <eblake@redhat.com>
CC: Michael Roth <mdroth@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
*added semi-colon to better delineate 2.2 vs. 2.4 versioning
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-07-21 14:36:06 -05:00
Peter Maydell
774ee4772b Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20150721' into staging
target-arm queue:
 * don't sync CNTVCT with kernel all the time (fixes VM time weirdnesses)
 * fix a warning compiling disas/arm-a64 with -Wextra

# gpg: Signature made Tue Jul 21 12:15:33 2015 BST using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-target-arm-20150721:
  disas/arm-a64: Add missing compiler attribute GCC_FMT_ATTR
  target-arm: kvm: Differentiate registers based on write-back levels

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-21 12:21:08 +01:00
Stefan Weil
57b73090e0 disas/arm-a64: Add missing compiler attribute GCC_FMT_ATTR
Type fprintf_function which fits here was defined with this attribute.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1437208027-14584-1-git-send-email-sw@weilnetz.de
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-21 11:18:45 +01:00
Christoffer Dall
4b7a6bf402 target-arm: kvm: Differentiate registers based on write-back levels
Some registers like the CNTVCT register should only be written to the
kernel as part of machine initialization or on vmload operations, but
never during runtime, as this can potentially make time go backwards or
create inconsistent time observations between VCPUs.

Introduce a list of registers that should not be written back at runtime
and check this list on syncing the register state to the KVM state.

Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Message-id: 1437046488-10773-1-git-send-email-christoffer.dall@linaro.org
[PMM: tweaked a few comments, added the new argument to the stub
 write_list_to_kvmstate() in target-arm/kvm-stub.c]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-21 11:18:45 +01:00
Peter Maydell
a1bc040dab Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging
# gpg: Signature made Mon Jul 20 19:27:04 2015 BST using RSA key ID AAFC390E
# gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: FAEB 9711 A12C F475 812F  18F2 88A9 064D 1835 61EB
#      Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76  CBD0 7DEF 8106 AAFC 390E

* remotes/jnsnow/tags/ide-pull-request:
  tests: Fix broken targets check-report-qtest-*
  ahci: Force ICC bits in PxCMD to zero
  qtest/ide: add another short PRDT test flavor

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-21 10:04:32 +01:00
Stefan Weil
47c719964a tests: Fix broken targets check-report-qtest-*
They need QTEST_QEMU_IMG. Without it, the tests raise an assertion:

$ make -C bin check-report-qtest-i386.xml
make: Entering directory 'bin'
GTESTER check-report-qtest-i386.xml
blkdebug: Suspended request 'A'
blkdebug: Resuming request 'A'
ahci-test: tests/libqos/libqos.c:162:
 mkimg: Assertion `qemu_img_path' failed.
main-loop: WARNING: I/O thread spun for 1000 iterations

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 1437231284-17455-1-git-send-email-sw@weilnetz.de
Signed-off-by: John Snow <jsnow@redhat.com>
2015-07-20 14:26:41 -04:00
Peter Maydell
bd03a38fdf Merge remote-tracking branch 'remotes/stefanha/tags/net-pull-request' into staging
# gpg: Signature made Mon Jul 20 18:25:14 2015 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/net-pull-request:
  net: Flush queued packets when guest resumes
  lan9118: Drop lan9118_can_receive
  etraxfs_eth: Drop eth_can_receive
  musicpal: Drop eth_can_receive
  net/vmxnet3: Fix RX TCP/UDP checksum on partially summed packets
  net/vmxnet3: Refactor 'vmxnet_rx_pkt_attach_data'
  socket: pass correct size in net_socket_send()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-20 18:26:53 +01:00
Fam Zheng
625de449fc net: Flush queued packets when guest resumes
Since commit 6e99c63 "net/socket: Drop net_socket_can_send" and friends,
net queues need to be explicitly flushed after qemu_can_send_packet()
returns false, because the netdev side will disable the polling of fd.

This fixes the case of "cont" after "stop" (or migration).

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-id: 1436232067-29144-1-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-20 18:11:24 +01:00
Fam Zheng
b49b8c572f lan9118: Drop lan9118_can_receive
True is the default.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Message-id: 1435734647-8371-4-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-20 17:47:24 +01:00
Fam Zheng
da69028261 etraxfs_eth: Drop eth_can_receive
True is the default.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Message-id: 1435734647-8371-3-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-20 17:47:24 +01:00
Fam Zheng
f63eab8bec musicpal: Drop eth_can_receive
True is the default.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Message-id: 1435734647-8371-2-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-20 17:47:24 +01:00
Dana Rubin
80da311d81 net/vmxnet3: Fix RX TCP/UDP checksum on partially summed packets
Convert partially summed packets to be fully checksummed.

In case csum offloaded packet, vmxnet3 implementation always passes an
RxCompDesc with the "Checksum calculated and found correct" notification
to the OS. This emulates the observed ESXi behavior.

Therefore, if packet has the NEEDS_CSUM bit set, we must calculate and
place a fully computed checksum into the tcp/udp header. Otherwise, the
OS driver will receive a checksum-correct indication but with the actual
tcp/udp checksum field having just the pseudo header csum value.

If host OS performs forwarding, it will forward an incorrectly
checksummed packet.

Signed-off-by: Dana Rubin <dana.rubin@ravellosystems.com>
Signed-off-by: Shmulik Ladkani <shmulik.ladkani@ravellosystems.com>
Message-id: 1436864116-19154-3-git-send-email-shmulik.ladkani@ravellosystems.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-20 17:39:05 +01:00
Shmulik Ladkani
fcf0cdc362 net/vmxnet3: Refactor 'vmxnet_rx_pkt_attach_data'
Separate RX packet protocol parsing out of 'vmxnet_rx_pkt_attach_data'.

Signed-off-by: Shmulik Ladkani <shmulik.ladkani@ravellosystems.com>
Message-id: 1436864116-19154-2-git-send-email-shmulik.ladkani@ravellosystems.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-20 17:39:05 +01:00
Jason Wang
091f1f5296 socket: pass correct size in net_socket_send()
We should pass the size of packet instead of the remaining to
qemu_send_packet_async().

Fixes: 6e99c631f1
       ("net/socket: Drop net_socket_can_send")

Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-id: 1436259656-24263-1-git-send-email-jasowang@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2015-07-20 17:39:05 +01:00
Stefan Fritsch
09b61db7c1 ahci: Force ICC bits in PxCMD to zero
The AHCI spec requires that the HBA sets the ICC bits to zero after the
ICC change is done. Since we don't do any ICC change, force the bits to
zero all the time.

This fixes delays with some OSs (e.g. OpenBSD) waiting for the ICC bits
to change to 0.

Signed-off-by: Stefan Fritsch <sf@sfritsch.de>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: E1ZFpg7-00027N-HW@eru.sfritsch.de
Signed-off-by: John Snow <jsnow@redhat.com>
2015-07-20 12:21:18 -04:00
Stefan Hajnoczi
5873281023 qtest/ide: add another short PRDT test flavor
The existing short PRDT test case does not transfer any data because the
first PRD is less than 1 sector.

This patch adds another short PRDT test case where the first sector can
be read but the PRDT is still smaller than the requested number of
sectors.  This exercises a different code path in ide_dma_cb().

Cc: John Snow <jsnow@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 1435770571-9906-1-git-send-email-stefanha@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
2015-07-20 12:21:18 -04:00
Stefan Hajnoczi
13566fe3e5 timer: rename NSEC_PER_SEC due to Mac OS X header clash
Commit e0cf11f31c ("timer: Use a single
definition of NSEC_PER_SEC for the whole codebase") renamed
NANOSECONDS_PER_SECOND to NSEC_PER_SEC.

On Mac OS X there is a <dispatch/time.h> system header which also
defines NSEC_PER_SEC.  This causes compiler warnings.

Let's use the old name instead.  It's longer but it doesn't clash.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1436364609-7929-1-git-send-email-stefanha@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-20 17:01:00 +01:00
Peter Maydell
dcc8a3ab63 Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches for 2.4.0-rc2

# gpg: Signature made Mon Jul 20 15:48:56 2015 BST using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream:
  crypto: Fix aes_decrypt_wrapper()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-20 16:01:31 +01:00
Peter Maydell
f73ca73634 Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio, vhost, pc fixes for 2.4

The only notable thing here is vhost-user multiqueue
revert. We'll work on making it stable in 2.5,
reverting now means we won't have to maintain
bug for bug compability forever.

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

# gpg: Signature made Mon Jul 20 12:24:00 2015 BST using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"

* remotes/mst/tags/for_upstream:
  virtio-net: remove virtio queues if the guest doesn't support multiqueue
  virtio-net: Flush incoming queues when DRIVER_OK is being set
  pci_add_capability: remove duplicate comments
  virtio-net: unbreak any layout
  Revert "vhost-user: add multi queue support"
  ich9: fix skipped vmstate_memhp_state subsection

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-20 13:25:28 +01:00
Kevin Wolf
bd09594603 crypto: Fix aes_decrypt_wrapper()
Commit d3462e3 broke qcow2's encryption functionality by using encrypt
instead of decrypt in the wrapper function it introduces. This was found
by qemu-iotests case 134.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
2015-07-20 13:35:45 +02:00
Wen Congyang
f9d6dbf0bf virtio-net: remove virtio queues if the guest doesn't support multiqueue
commit da51a335 adds all queues in .realize(). But if the
guest doesn't support multiqueue, we forget to remove them. And
we cannot handle the ctrl vq corretly. The guest will hang.

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
2015-07-20 14:19:42 +03:00
Fam Zheng
38705bb57b virtio-net: Flush incoming queues when DRIVER_OK is being set
This patch fixes network hang after "stop" then "cont", while network
packets keep arriving.

Tested both manually (tap, host pinging guest) and with Jason's qtest
series (plus his "[PATCH 2.4] socket: pass correct size in
net_socket_send()" fix).

As virtio_net_set_status is called when guest driver is setting status
byte and when vm state is changing, it is a good opportunity to flush
queued packets.

This is necessary because during vm stop the backend (e.g. tap) would
stop rx processing after .can_receive returns false, until the queue is
explicitly flushed or purged.

The other interesting condition in .can_receive, virtio_queue_ready(),
is handled by virtio_net_handle_rx() when guest kicks; the 3rd condition
is invalid queue index which doesn't need flushing.

Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2015-07-20 14:19:41 +03:00
Chen Hanxiao
9a2a66238e pci_add_capability: remove duplicate comments
Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2015-07-20 14:19:41 +03:00
Jason Wang
feb93f3617 virtio-net: unbreak any layout
Commit 032a74a1c0
("virtio-net: byteswap virtio-net header") breaks any layout by
requiring out_sg[0].iov_len >= n->guest_hdr_len. Fixing this by
copying header to temporary buffer if swap is needed, and then use
this buffer as part of out_sg.

Fixes 032a74a1c0
("virtio-net: byteswap virtio-net header")
Cc: qemu-stable@nongnu.org
Cc: clg@fr.ibm.com
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2015-07-20 14:19:41 +03:00
Michael S. Tsirkin
d345ed2da3 Revert "vhost-user: add multi queue support"
This reverts commit 830d70db69.

The interface isn't fully backwards-compatible, which is bad.
Let's redo this properly after 2.4.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2015-07-20 14:19:40 +03:00
Paulo Alcantara
75d663611e ich9: fix skipped vmstate_memhp_state subsection
By declaring another .subsections array for vmstate_tco_io_state made
vmstate_memhp_state not registered anymore. There must be only one
.subsections array for all subsections.

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Amit Shah <amit.shah@redhat.com>
Reported-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
2015-07-20 14:19:40 +03:00
Peter Maydell
71358470ee Merge remote-tracking branch 'remotes/amit-virtio-rng/tags/vrng-2.4' into staging
Fire timer only when required.  Brings down wakeups by a big number.

# gpg: Signature made Fri Jul 17 14:41:40 2015 BST using RSA key ID 854083B6
# gpg: Good signature from "Amit Shah <amit@amitshah.net>"
# gpg:                 aka "Amit Shah <amit@kernel.org>"
# gpg:                 aka "Amit Shah <amitshah@gmx.net>"

* remotes/amit-virtio-rng/tags/vrng-2.4:
  virtio-rng: trigger timer only when guest requests for entropy

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-17 15:22:45 +01:00
Pankaj Gupta
621a20e081 virtio-rng: trigger timer only when guest requests for entropy
This patch triggers timer only when guest requests for
entropy. As soon as first request from guest for entropy
comes we set the timer. Timer bumps up the quota value
when it gets triggered.

Signed-off-by: Pankaj Gupta <pagupta@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Message-Id: <1436962608-9961-2-git-send-email-pagupta@redhat.com>

[Re-worded patch subject, removed extra whitespace -- Amit]

Signed-off-by: Amit Shah <amit.shah@redhat.com>
2015-07-17 19:05:16 +05:30
Peter Maydell
5b5e8cdd7d Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-20150717-1' into staging
usb: fixes for 2.4 (ccid, xhci and usb-host)

# gpg: Signature made Fri Jul 17 12:21:42 2015 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-usb-20150717-1:
  Revert "xhci: set timer to retry xfers"
  usb-ccid: add missing wakeup calls
  usb-ccid: fix 61b4887b41
  Re-attach usb device to kernel while usb_host_open fails

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-17 12:39:12 +01:00
Gerd Hoffmann
92fdfa4bef Revert "xhci: set timer to retry xfers"
This reverts commit 4e8cfbe114.

We should not poll via timer, and with ccid being fixed
to properly notify us about pending transfers we don't have to.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-07-17 13:20:53 +02:00
Gerd Hoffmann
86d7e214c2 usb-ccid: add missing wakeup calls
Properly notify the host adapter that we have
data pending, so it doesn't has to poll us.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-07-17 13:20:53 +02:00
Gerd Hoffmann
cfda2cef3d usb-ccid: fix 61b4887b41
QOMification dropped the parent device lookup, fix it.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-07-17 13:19:59 +02:00
Peter Maydell
fd1a9ef9c2 Merge remote-tracking branch 'remotes/kraxel/tags/pull-input-20150717-1' into staging
input: fixes for 2.4

# gpg: Signature made Fri Jul 17 07:45:17 2015 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-input-20150717-1:
  hid: clarify hid_keyboard_process_keycode
  virtio-input: move sys/ioctl.h include
  virtio-input: fix segfault in virtio_input_hid_properties

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-17 10:52:12 +01:00
Peter Maydell
b4329bf41c Update version for v2.4.0-rc1 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-16 20:32:20 +01:00
Peter Maydell
b92304ee81 Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* MIPS-KVM fixes.
* Coverity fixes.
* Nettle function prototype fixes.
* Memory API refcount fix.

# gpg: Signature made Thu Jul 16 19:01:27 2015 BST using RSA key ID 78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream:
  crypto: avoid undefined behavior in nettle calls
  crypto: fix build with nettle >= 3.0.0
  memory: fix refcount leak in memory_region_present
  RDMA: Fix error exits
  arm/xlnx-zynqmp: fix memory leak
  ppc/spapr_drc: fix memory leak
  mips/kvm: Sign extend registers written to KVM
  mips/kvm: Fix Big endian 32-bit register access

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-16 19:18:15 +01:00
Radim Krčmář
d3462e378f crypto: avoid undefined behavior in nettle calls
Calling a function pointer that was cast from an incompatible function
results in undefined behavior.  'void *' isn't compatible with 'struct
XXX *', so we can't cast to nettle_cipher_func, but have to provide a
wrapper.  (Conversion from 'void *' to 'struct XXX *' might require
computation, which won't be done if we drop argument's true type, and
pointers can have different sizes so passing arguments on stack would
bug.)

Having two different prototypes based on nettle version doesn't make
this solution any nicer.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Message-Id: <1437062641-12684-3-git-send-email-rkrcmar@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-16 20:00:21 +02:00
Radim Krčmář
becaeb726a crypto: fix build with nettle >= 3.0.0
In nettle 3, cbc_encrypt() accepts 'nettle_cipher_func' instead of
'nettle_crypt_func' and these two differ in 'const' qualifier of the
first argument.  The build fails with:

  In file included from crypto/cipher.c:71:0:
  ./crypto/cipher-nettle.c: In function ‘qcrypto_cipher_encrypt’:
  ./crypto/cipher-nettle.c:154:38: error: passing argument 2 of
  ‘nettle_cbc_encrypt’ from incompatible pointer type
           cbc_encrypt(ctx->ctx_encrypt, ctx->alg_encrypt,
                                               ^
  In file included from ./crypto/cipher-nettle.c:24:0,
                   from crypto/cipher.c:71:
  /usr/include/nettle/cbc.h:48:1: note: expected
  ‘void (*)(const void *, size_t, uint8_t *, const uint8_t *)
  but argument is of type
  ‘void (*)(      void *, size_t, uint8_t *, const uint8_t *)

To allow both versions, we switch to the new definition and #if typedef
it for old versions.

Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Message-Id: <1436548682-9315-2-git-send-email-rkrcmar@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-16 20:00:20 +02:00
Paolo Bonzini
c6742b14fe memory: fix refcount leak in memory_region_present
memory_region_present() leaks a reference to a MemoryRegion in the
case "mr == container".  While fixing it, avoid reference counting
altogether for memory_region_present(), by using RCU only.

The return value could in principle be already invalid immediately
after memory_region_present returns, but presumably the caller knows
that and it's using memory_region_present to probe for devices that
are unpluggable, or something like that.  The RCU critical section
is needed anyway, because it protects as->current_map.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-16 20:00:20 +02:00
Dr. David Alan Gilbert
24b41d66c8 RDMA: Fix error exits
The error checks I added used 'break' after the error, but I'm
in a switch inside the while loop, so they need to be 'goto out'.

Spotted by coverity; entries 1311368 and 1311369

Fixes: afcddefd

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-Id: <1436555332-19076-1-git-send-email-dgilbert@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-16 20:00:20 +02:00
Gonglei
5348c62cab arm/xlnx-zynqmp: fix memory leak
fix CID 1311372.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Message-Id: <1436489490-236-4-git-send-email-arei.gonglei@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-16 20:00:20 +02:00
Gonglei
586d2142a9 ppc/spapr_drc: fix memory leak
fix CID 1311373.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Message-Id: <1436489490-236-3-git-send-email-arei.gonglei@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-16 20:00:20 +02:00
James Hogan
02dae26ac4 mips/kvm: Sign extend registers written to KVM
In case we're running on a 64-bit host, be sure to sign extend the
general purpose registers and hi/lo/pc before writing them to KVM, so as
to take advantage of MIPS32/MIPS64 compatibility.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Leon Alrae <leon.alrae@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: kvm@vger.kernel.org
Cc: qemu-stable@nongnu.org
Message-Id: <1429871214-23514-3-git-send-email-james.hogan@imgtec.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-16 20:00:20 +02:00
James Hogan
f8b3e48b2d mips/kvm: Fix Big endian 32-bit register access
Fix access to 32-bit registers on big endian targets. The pointer passed
to the kernel must be for the actual 32-bit value, not a temporary
64-bit value, otherwise on big endian systems the kernel will only
interpret the upper half.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Leon Alrae <leon.alrae@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: kvm@vger.kernel.org
Cc: qemu-stable@nongnu.org
Message-Id: <1429871214-23514-2-git-send-email-james.hogan@imgtec.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2015-07-16 20:00:20 +02:00
Peter Maydell
67ff64e082 Merge remote-tracking branch 'remotes/spice/tags/pull-spice-20150716-1' into staging
qxl: allow to specify head limit to qxl driver

# gpg: Signature made Thu Jul 16 16:31:40 2015 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/spice/tags/pull-spice-20150716-1:
  qxl: allow to specify head limit to qxl driver

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2015-07-16 16:55:00 +01:00
6110ce59af Re-attach usb device to kernel while usb_host_open fails
Signed-off-by: Lin Ma <lma@suse.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-07-16 17:39:13 +02:00
Frediano Ziglio
567161fdd4 qxl: allow to specify head limit to qxl driver
This patch allow to limit number of heads using qxl driver. By default
qxl driver is not limited on any kind on head use so can decide to use
as much heads.

libvirt has this as a video card parameter (actually set to 1 but not
used). This parameter will allow to limit setting a use can do (which
could be confusing).

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-07-16 17:31:05 +02:00
198 changed files with 7587 additions and 1153 deletions

2
.gitignore vendored
View File

@@ -17,6 +17,8 @@
/trace/generated-tcg-tracers.h
/trace/generated-ust-provider.h
/trace/generated-ust.c
/ui/shader/texture-blit-frag.h
/ui/shader/texture-blit-vert.h
/libcacard/trace/generated-tracers.c
*-timestamp
/*-softmmu

View File

@@ -135,7 +135,7 @@ endif
else \
mv $@.tmp $@; \
cp -p $@ $@.old; \
fi, " GEN $@");
fi, " GEN $@");
defconfig:
rm -f config-all-devices.mak $(SUBDIR_DEVICES_MAK)

View File

@@ -36,6 +36,10 @@ endif
PROGS=$(QEMU_PROG) $(QEMU_PROGW)
STPFILES=
ifdef CONFIG_LINUX_USER
PROGS+=$(QEMU_PROG)-binfmt
endif
config-target.h: config-target.h-timestamp
config-target.h-timestamp: config-target.mak
@@ -110,6 +114,8 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
obj-y += linux-user/
obj-y += gdbstub.o thunk.o user-exec.o
obj-binfmt-y += linux-user/
endif #CONFIG_LINUX_USER
#########################################################
@@ -158,7 +164,11 @@ endif # CONFIG_SOFTMMU
# Workaround for http://gcc.gnu.org/PR55489, see configure.
%/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS)
ifdef CONFIG_LINUX_USER
dummy := $(call unnest-vars,,obj-y obj-binfmt-y)
else
dummy := $(call unnest-vars,,obj-y)
endif
all-obj-y := $(obj-y)
target-obj-y :=
@@ -187,6 +197,9 @@ ifdef CONFIG_DARWIN
$(call quiet-command,SetFile -a C $@," SETFILE $(TARGET_DIR)$@")
endif
$(QEMU_PROG)-binfmt: $(obj-binfmt-y)
$(call LINK,$^)
gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
$(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@")

View File

@@ -1 +1 @@
2.3.90
2.4.0

View File

@@ -233,26 +233,23 @@ static void add_pollfd(AioHandler *node)
bool aio_poll(AioContext *ctx, bool blocking)
{
AioHandler *node;
bool was_dispatching;
int i, ret;
bool progress;
int64_t timeout;
aio_context_acquire(ctx);
was_dispatching = ctx->dispatching;
progress = false;
/* aio_notify can avoid the expensive event_notifier_set if
* everything (file descriptors, bottom halves, timers) will
* be re-evaluated before the next blocking poll(). This is
* already true when aio_poll is called with blocking == false;
* if blocking == true, it is only true after poll() returns.
*
* If we're in a nested event loop, ctx->dispatching might be true.
* In that case we can restore it just before returning, but we
* have to clear it now.
* if blocking == true, it is only true after poll() returns,
* so disable the optimization now.
*/
aio_set_dispatching(ctx, !blocking);
if (blocking) {
atomic_add(&ctx->notify_me, 2);
}
ctx->walking_handlers++;
@@ -272,10 +269,15 @@ bool aio_poll(AioContext *ctx, bool blocking)
aio_context_release(ctx);
}
ret = qemu_poll_ns((GPollFD *)pollfds, npfd, timeout);
if (blocking) {
atomic_sub(&ctx->notify_me, 2);
}
if (timeout) {
aio_context_acquire(ctx);
}
aio_notify_accept(ctx);
/* if we have any readable fds, dispatch event */
if (ret > 0) {
for (i = 0; i < npfd; i++) {
@@ -287,12 +289,10 @@ bool aio_poll(AioContext *ctx, bool blocking)
ctx->walking_handlers--;
/* Run dispatch even if there were no readable fds to run timers */
aio_set_dispatching(ctx, true);
if (aio_dispatch(ctx)) {
progress = true;
}
aio_set_dispatching(ctx, was_dispatching);
aio_context_release(ctx);
return progress;

View File

@@ -279,30 +279,25 @@ bool aio_poll(AioContext *ctx, bool blocking)
{
AioHandler *node;
HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
bool was_dispatching, progress, have_select_revents, first;
bool progress, have_select_revents, first;
int count;
int timeout;
aio_context_acquire(ctx);
have_select_revents = aio_prepare(ctx);
if (have_select_revents) {
blocking = false;
}
was_dispatching = ctx->dispatching;
progress = false;
/* aio_notify can avoid the expensive event_notifier_set if
* everything (file descriptors, bottom halves, timers) will
* be re-evaluated before the next blocking poll(). This is
* already true when aio_poll is called with blocking == false;
* if blocking == true, it is only true after poll() returns.
*
* If we're in a nested event loop, ctx->dispatching might be true.
* In that case we can restore it just before returning, but we
* have to clear it now.
* if blocking == true, it is only true after poll() returns,
* so disable the optimization now.
*/
aio_set_dispatching(ctx, !blocking);
if (blocking) {
atomic_add(&ctx->notify_me, 2);
}
have_select_revents = aio_prepare(ctx);
ctx->walking_handlers++;
@@ -317,26 +312,36 @@ bool aio_poll(AioContext *ctx, bool blocking)
ctx->walking_handlers--;
first = true;
/* wait until next event */
while (count > 0) {
/* ctx->notifier is always registered. */
assert(count > 0);
/* Multiple iterations, all of them non-blocking except the first,
* may be necessary to process all pending events. After the first
* WaitForMultipleObjects call ctx->notify_me will be decremented.
*/
do {
HANDLE event;
int ret;
timeout = blocking
timeout = blocking && !have_select_revents
? qemu_timeout_ns_to_ms(aio_compute_timeout(ctx)) : 0;
if (timeout) {
aio_context_release(ctx);
}
ret = WaitForMultipleObjects(count, events, FALSE, timeout);
if (blocking) {
assert(first);
atomic_sub(&ctx->notify_me, 2);
}
if (timeout) {
aio_context_acquire(ctx);
}
aio_set_dispatching(ctx, true);
if (first && aio_bh_poll(ctx)) {
progress = true;
if (first) {
aio_notify_accept(ctx);
progress |= aio_bh_poll(ctx);
first = false;
}
first = false;
/* if we have any signaled events, dispatch event */
event = NULL;
@@ -351,11 +356,10 @@ bool aio_poll(AioContext *ctx, bool blocking)
blocking = false;
progress |= aio_dispatch_handlers(ctx, event);
}
} while (count > 0);
progress |= timerlistgroup_run_timers(&ctx->tlg);
aio_set_dispatching(ctx, was_dispatching);
aio_context_release(ctx);
return progress;
}

64
async.c
View File

@@ -79,8 +79,10 @@ int aio_bh_poll(AioContext *ctx)
* aio_notify again if necessary.
*/
if (!bh->deleted && atomic_xchg(&bh->scheduled, 0)) {
if (!bh->idle)
/* Idle BHs and the notify BH don't count as progress */
if (!bh->idle && bh != ctx->notify_dummy_bh) {
ret = 1;
}
bh->idle = 0;
bh->cb(bh->opaque);
}
@@ -184,6 +186,8 @@ aio_ctx_prepare(GSource *source, gint *timeout)
{
AioContext *ctx = (AioContext *) source;
atomic_or(&ctx->notify_me, 1);
/* We assume there is no timeout already supplied */
*timeout = qemu_timeout_ns_to_ms(aio_compute_timeout(ctx));
@@ -200,6 +204,9 @@ aio_ctx_check(GSource *source)
AioContext *ctx = (AioContext *) source;
QEMUBH *bh;
atomic_and(&ctx->notify_me, ~1);
aio_notify_accept(ctx);
for (bh = ctx->first_bh; bh; bh = bh->next) {
if (!bh->deleted && bh->scheduled) {
return true;
@@ -225,7 +232,21 @@ aio_ctx_finalize(GSource *source)
{
AioContext *ctx = (AioContext *) source;
qemu_bh_delete(ctx->notify_dummy_bh);
thread_pool_free(ctx->thread_pool);
qemu_mutex_lock(&ctx->bh_lock);
while (ctx->first_bh) {
QEMUBH *next = ctx->first_bh->next;
/* qemu_bh_delete() must have been called on BHs in this AioContext */
assert(ctx->first_bh->deleted);
g_free(ctx->first_bh);
ctx->first_bh = next;
}
qemu_mutex_unlock(&ctx->bh_lock);
aio_set_event_notifier(ctx, &ctx->notifier, NULL);
event_notifier_cleanup(&ctx->notifier);
rfifolock_destroy(&ctx->lock);
@@ -254,24 +275,22 @@ ThreadPool *aio_get_thread_pool(AioContext *ctx)
return ctx->thread_pool;
}
void aio_set_dispatching(AioContext *ctx, bool dispatching)
void aio_notify(AioContext *ctx)
{
ctx->dispatching = dispatching;
if (!dispatching) {
/* Write ctx->dispatching before reading e.g. bh->scheduled.
* Optimization: this is only needed when we're entering the "unsafe"
* phase where other threads must call event_notifier_set.
*/
smp_mb();
/* Write e.g. bh->scheduled before reading ctx->notify_me. Pairs
* with atomic_or in aio_ctx_prepare or atomic_add in aio_poll.
*/
smp_mb();
if (ctx->notify_me) {
event_notifier_set(&ctx->notifier);
atomic_mb_set(&ctx->notified, true);
}
}
void aio_notify(AioContext *ctx)
void aio_notify_accept(AioContext *ctx)
{
/* Write e.g. bh->scheduled before reading ctx->dispatching. */
smp_mb();
if (!ctx->dispatching) {
event_notifier_set(&ctx->notifier);
if (atomic_xchg(&ctx->notified, false)) {
event_notifier_test_and_clear(&ctx->notifier);
}
}
@@ -282,8 +301,19 @@ static void aio_timerlist_notify(void *opaque)
static void aio_rfifolock_cb(void *opaque)
{
AioContext *ctx = opaque;
/* Kick owner thread in case they are blocked in aio_poll() */
aio_notify(opaque);
qemu_bh_schedule(ctx->notify_dummy_bh);
}
static void notify_dummy_bh(void *opaque)
{
/* Do nothing, we were invoked just to force the event loop to iterate */
}
static void event_notifier_dummy_cb(EventNotifier *e)
{
}
AioContext *aio_context_new(Error **errp)
@@ -300,12 +330,14 @@ AioContext *aio_context_new(Error **errp)
g_source_set_can_recurse(&ctx->source, true);
aio_set_event_notifier(ctx, &ctx->notifier,
(EventNotifierHandler *)
event_notifier_test_and_clear);
event_notifier_dummy_cb);
ctx->thread_pool = NULL;
qemu_mutex_init(&ctx->bh_lock);
rfifolock_init(&ctx->lock, aio_rfifolock_cb, ctx);
timerlistgroup_init(&ctx->tlg, aio_timerlist_notify, ctx);
ctx->notify_dummy_bh = aio_bh_new(ctx, notify_dummy_bh, NULL);
return ctx;
}

View File

@@ -10,6 +10,7 @@
* See the COPYING file in the top-level directory.
*/
#include "sysemu/hostmem.h"
#include "hw/boards.h"
#include "qapi/visitor.h"
#include "qapi-types.h"
#include "qapi-visit.h"
@@ -222,11 +223,10 @@ static void host_memory_backend_set_prealloc(Object *obj, bool value,
static void host_memory_backend_init(Object *obj)
{
HostMemoryBackend *backend = MEMORY_BACKEND(obj);
MachineState *machine = MACHINE(qdev_get_machine());
backend->merge = qemu_opt_get_bool(qemu_get_machine_opts(),
"mem-merge", true);
backend->dump = qemu_opt_get_bool(qemu_get_machine_opts(),
"dump-guest-core", true);
backend->merge = machine_mem_merge(machine);
backend->dump = machine_dump_guest_core(machine);
backend->prealloc = mem_prealloc;
object_property_add_bool(obj, "merge",

View File

@@ -3871,6 +3871,9 @@ void bdrv_img_create(const char *filename, const char *fmt,
if (!quiet) {
printf("Formatting '%s', fmt=%s", filename, fmt);
qemu_opts_print(opts, " ");
if (qemu_opt_get_bool(opts, BLOCK_OPT_SCSI, false)) {
printf(", SCSI");
}
puts("");
}

View File

@@ -20,6 +20,8 @@ block-obj-$(CONFIG_RBD) += rbd.o
block-obj-$(CONFIG_GLUSTERFS) += gluster.o
block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o
block-obj-$(CONFIG_LIBSSH2) += ssh.o
block-obj-y += dictzip.o
block-obj-y += tar.o
block-obj-y += accounting.o
block-obj-y += write-threshold.o

584
block/dictzip.c Normal file
View File

@@ -0,0 +1,584 @@
/*
* DictZip Block driver for dictzip enabled gzip files
*
* Use the "dictzip" tool from the "dictd" package to create gzip files that
* contain the extra DictZip headers.
*
* dictzip(1) is a compression program which creates compressed files in the
* gzip format (see RFC 1952). However, unlike gzip(1), dictzip(1) compresses
* the file in pieces and stores an index to the pieces in the gzip header.
* This allows random access to the file at the granularity of the compressed
* pieces (currently about 64kB) while maintaining good compression ratios
* (within 5% of the expected ratio for dictionary data).
* dictd(8) uses files stored in this format.
*
* For details on DictZip see http://dict.org/.
*
* Copyright (c) 2009 Alexander Graf <agraf@suse.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu-common.h"
#include "block/block_int.h"
#include <zlib.h>
// #define DEBUG
#ifdef DEBUG
#define dprintf(fmt, ...) do { printf("dzip: " fmt, ## __VA_ARGS__); } while (0)
#else
#define dprintf(fmt, ...) do { } while (0)
#endif
#define SECTOR_SIZE 512
#define Z_STREAM_COUNT 4
#define CACHE_COUNT 20
/* magic values */
#define GZ_MAGIC1 0x1f
#define GZ_MAGIC2 0x8b
#define DZ_MAGIC1 'R'
#define DZ_MAGIC2 'A'
#define GZ_FEXTRA 0x04 /* Optional field (random access index) */
#define GZ_FNAME 0x08 /* Original name */
#define GZ_COMMENT 0x10 /* Zero-terminated, human-readable comment */
#define GZ_FHCRC 0x02 /* Header CRC16 */
/* offsets */
#define GZ_ID 0 /* GZ_MAGIC (16bit) */
#define GZ_FLG 3 /* FLaGs (see above) */
#define GZ_XLEN 10 /* eXtra LENgth (16bit) */
#define GZ_SI 12 /* Subfield ID (16bit) */
#define GZ_VERSION 16 /* Version for subfield format */
#define GZ_CHUNKSIZE 18 /* Chunk size (16bit) */
#define GZ_CHUNKCNT 20 /* Number of chunks (16bit) */
#define GZ_RNDDATA 22 /* Random access data (16bit) */
#define GZ_99_CHUNKSIZE 18 /* Chunk size (32bit) */
#define GZ_99_CHUNKCNT 22 /* Number of chunks (32bit) */
#define GZ_99_FILESIZE 26 /* Size of unpacked file (64bit) */
#define GZ_99_RNDDATA 34 /* Random access data (32bit) */
struct BDRVDictZipState;
typedef struct DictZipAIOCB {
BlockAIOCB common;
struct BDRVDictZipState *s;
QEMUIOVector *qiov; /* QIOV of the original request */
QEMUIOVector *qiov_gz; /* QIOV of the gz subrequest */
QEMUBH *bh; /* BH for cache */
z_stream *zStream; /* stream to use for decoding */
int zStream_id; /* stream id of the above pointer */
size_t start; /* offset into the uncompressed file */
size_t len; /* uncompressed bytes to read */
uint8_t *gzipped; /* the gzipped data */
uint8_t *buf; /* cached result */
size_t gz_len; /* amount of gzip data */
size_t gz_start; /* uncompressed starting point of gzip data */
uint64_t offset; /* offset for "start" into the uncompressed chunk */
int chunks_len; /* amount of uncompressed data in all gzip data */
} DictZipAIOCB;
typedef struct dict_cache {
size_t start;
size_t len;
uint8_t *buf;
} DictCache;
typedef struct BDRVDictZipState {
BlockDriverState *hd;
z_stream zStream[Z_STREAM_COUNT];
DictCache cache[CACHE_COUNT];
int cache_index;
uint8_t stream_in_use;
uint64_t chunk_len;
uint32_t chunk_cnt;
uint16_t *chunks;
uint32_t *chunks32;
uint64_t *offsets;
int64_t file_len;
} BDRVDictZipState;
static int start_zStream(z_stream *zStream)
{
zStream->zalloc = NULL;
zStream->zfree = NULL;
zStream->opaque = NULL;
zStream->next_in = 0;
zStream->avail_in = 0;
zStream->next_out = NULL;
zStream->avail_out = 0;
return inflateInit2( zStream, -15 );
}
static QemuOptsList runtime_opts = {
.name = "dzip",
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
.desc = {
{
.name = "filename",
.type = QEMU_OPT_STRING,
.help = "URL to the dictzip file",
},
{ /* end of list */ }
},
};
static int dictzip_open(BlockDriverState *bs, QDict *options, int flags, Error **errp)
{
BDRVDictZipState *s = bs->opaque;
const char *err = "Unknown (read error?)";
uint8_t magic[2];
char buf[100];
uint8_t header_flags;
uint16_t chunk_len16;
uint16_t chunk_cnt16;
uint32_t chunk_len32;
uint16_t header_ver;
uint16_t tmp_short;
uint64_t offset;
int chunks_len;
int headerLength = GZ_XLEN - 1;
int rnd_offs;
int ret;
int i;
QemuOpts *opts;
Error *local_err = NULL;
const char *filename;
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
}
filename = qemu_opt_get(opts, "filename");
if (!strncmp(filename, "dzip://", 7))
filename += 7;
else if (!strncmp(filename, "dzip:", 5))
filename += 5;
ret = bdrv_open(&s->hd, filename, NULL, NULL, flags | BDRV_O_PROTOCOL, NULL, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
qemu_opts_del(opts);
return ret;
}
/* initialize zlib streams */
for (i = 0; i < Z_STREAM_COUNT; i++) {
if (start_zStream( &s->zStream[i] ) != Z_OK) {
err = s->zStream[i].msg;
goto fail;
}
}
/* gzip header */
if (bdrv_pread(s->hd, GZ_ID, &magic, sizeof(magic)) != sizeof(magic))
goto fail;
if (!((magic[0] == GZ_MAGIC1) && (magic[1] == GZ_MAGIC2))) {
err = "No gzip file";
goto fail;
}
/* dzip header */
if (bdrv_pread(s->hd, GZ_FLG, &header_flags, 1) != 1)
goto fail;
if (!(header_flags & GZ_FEXTRA)) {
err = "Not a dictzip file (wrong flags)";
goto fail;
}
/* extra length */
if (bdrv_pread(s->hd, GZ_XLEN, &tmp_short, 2) != 2)
goto fail;
headerLength += le16_to_cpu(tmp_short) + 2;
/* DictZip magic */
if (bdrv_pread(s->hd, GZ_SI, &magic, 2) != 2)
goto fail;
if (magic[0] != DZ_MAGIC1 || magic[1] != DZ_MAGIC2) {
err = "Not a dictzip file (missing extra magic)";
goto fail;
}
/* DictZip version */
if (bdrv_pread(s->hd, GZ_VERSION, &header_ver, 2) != 2)
goto fail;
header_ver = le16_to_cpu(header_ver);
switch (header_ver) {
case 1: /* Normal DictZip */
/* number of chunks */
if (bdrv_pread(s->hd, GZ_CHUNKSIZE, &chunk_len16, 2) != 2)
goto fail;
s->chunk_len = le16_to_cpu(chunk_len16);
/* chunk count */
if (bdrv_pread(s->hd, GZ_CHUNKCNT, &chunk_cnt16, 2) != 2)
goto fail;
s->chunk_cnt = le16_to_cpu(chunk_cnt16);
chunks_len = sizeof(short) * s->chunk_cnt;
rnd_offs = GZ_RNDDATA;
break;
case 99: /* Special Alex pigz version */
/* number of chunks */
if (bdrv_pread(s->hd, GZ_99_CHUNKSIZE, &chunk_len32, 4) != 4)
goto fail;
dprintf("chunk len [%#x] = %d\n", GZ_99_CHUNKSIZE, chunk_len32);
s->chunk_len = le32_to_cpu(chunk_len32);
/* chunk count */
if (bdrv_pread(s->hd, GZ_99_CHUNKCNT, &s->chunk_cnt, 4) != 4)
goto fail;
s->chunk_cnt = le32_to_cpu(s->chunk_cnt);
dprintf("chunk len | count = %"PRId64" | %d\n", s->chunk_len, s->chunk_cnt);
/* file size */
if (bdrv_pread(s->hd, GZ_99_FILESIZE, &s->file_len, 8) != 8)
goto fail;
s->file_len = le64_to_cpu(s->file_len);
chunks_len = sizeof(int) * s->chunk_cnt;
rnd_offs = GZ_99_RNDDATA;
break;
default:
err = "Invalid DictZip version";
goto fail;
}
/* random access data */
s->chunks = g_malloc(chunks_len);
if (header_ver == 99)
s->chunks32 = (uint32_t *)s->chunks;
if (bdrv_pread(s->hd, rnd_offs, s->chunks, chunks_len) != chunks_len)
goto fail;
/* orig filename */
if (header_flags & GZ_FNAME) {
if (bdrv_pread(s->hd, headerLength + 1, buf, sizeof(buf)) != sizeof(buf))
goto fail;
buf[sizeof(buf) - 1] = '\0';
headerLength += strlen(buf) + 1;
if (strlen(buf) == sizeof(buf))
goto fail;
dprintf("filename: %s\n", buf);
}
/* comment field */
if (header_flags & GZ_COMMENT) {
if (bdrv_pread(s->hd, headerLength, buf, sizeof(buf)) != sizeof(buf))
goto fail;
buf[sizeof(buf) - 1] = '\0';
headerLength += strlen(buf) + 1;
if (strlen(buf) == sizeof(buf))
goto fail;
dprintf("comment: %s\n", buf);
}
if (header_flags & GZ_FHCRC)
headerLength += 2;
/* uncompressed file length*/
if (!s->file_len) {
uint32_t file_len;
if (bdrv_pread(s->hd, bdrv_getlength(s->hd) - 4, &file_len, 4) != 4)
goto fail;
s->file_len = le32_to_cpu(file_len);
}
/* compute offsets */
s->offsets = g_malloc(sizeof( *s->offsets ) * s->chunk_cnt);
for (offset = headerLength + 1, i = 0; i < s->chunk_cnt; i++) {
s->offsets[i] = offset;
switch (header_ver) {
case 1:
offset += le16_to_cpu(s->chunks[i]);
break;
case 99:
offset += le32_to_cpu(s->chunks32[i]);
break;
}
dprintf("chunk %#"PRIx64" - %#"PRIx64" = offset %#"PRIx64" -> %#"PRIx64"\n", i * s->chunk_len, (i+1) * s->chunk_len, s->offsets[i], offset);
}
qemu_opts_del(opts);
return 0;
fail:
fprintf(stderr, "DictZip: Error opening file: %s\n", err);
bdrv_unref(s->hd);
if (s->chunks)
g_free(s->chunks);
qemu_opts_del(opts);
return -EINVAL;
}
/* This callback gets invoked when we have the result in cache already */
static void dictzip_cache_cb(void *opaque)
{
DictZipAIOCB *acb = (DictZipAIOCB *)opaque;
qemu_iovec_from_buf(acb->qiov, 0, acb->buf, acb->len);
acb->common.cb(acb->common.opaque, 0);
qemu_bh_delete(acb->bh);
qemu_aio_unref(acb);
}
/* This callback gets invoked by the underlying block reader when we have
* all compressed data. We uncompress in here. */
static void dictzip_read_cb(void *opaque, int ret)
{
DictZipAIOCB *acb = (DictZipAIOCB *)opaque;
struct BDRVDictZipState *s = acb->s;
uint8_t *buf;
DictCache *cache;
int r, i;
buf = g_malloc(acb->chunks_len);
/* try to find zlib stream for decoding */
do {
for (i = 0; i < Z_STREAM_COUNT; i++) {
if (!(s->stream_in_use & (1 << i))) {
s->stream_in_use |= (1 << i);
acb->zStream_id = i;
acb->zStream = &s->zStream[i];
break;
}
}
} while(!acb->zStream);
/* sure, we could handle more streams, but this callback should be single
threaded and when it's not, we really want to know! */
assert(i == 0);
/* uncompress the chunk */
acb->zStream->next_in = acb->gzipped;
acb->zStream->avail_in = acb->gz_len;
acb->zStream->next_out = buf;
acb->zStream->avail_out = acb->chunks_len;
r = inflate( acb->zStream, Z_PARTIAL_FLUSH );
if ( (r != Z_OK) && (r != Z_STREAM_END) )
fprintf(stderr, "Error inflating: [%d] %s\n", r, acb->zStream->msg);
if ( r == Z_STREAM_END )
inflateReset(acb->zStream);
dprintf("inflating [%d] left: %d | %d bytes\n", r, acb->zStream->avail_in, acb->zStream->avail_out);
s->stream_in_use &= ~(1 << acb->zStream_id);
/* nofity the caller */
qemu_iovec_from_buf(acb->qiov, 0, buf + acb->offset, acb->len);
acb->common.cb(acb->common.opaque, 0);
/* fill the cache */
cache = &s->cache[s->cache_index];
s->cache_index++;
if (s->cache_index == CACHE_COUNT)
s->cache_index = 0;
cache->len = 0;
if (cache->buf)
g_free(cache->buf);
cache->start = acb->gz_start;
cache->buf = buf;
cache->len = acb->chunks_len;
/* free occupied ressources */
g_free(acb->qiov_gz);
qemu_aio_unref(acb);
}
static const AIOCBInfo dictzip_aiocb_info = {
.aiocb_size = sizeof(DictZipAIOCB),
};
/* This is where we get a request from a caller to read something */
static BlockAIOCB *dictzip_aio_readv(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockCompletionFunc *cb, void *opaque)
{
BDRVDictZipState *s = bs->opaque;
DictZipAIOCB *acb;
QEMUIOVector *qiov_gz;
struct iovec *iov;
uint8_t *buf;
size_t start = sector_num * SECTOR_SIZE;
size_t len = nb_sectors * SECTOR_SIZE;
size_t end = start + len;
size_t gz_start;
size_t gz_len;
int64_t gz_sector_num;
int gz_nb_sectors;
int first_chunk, last_chunk;
int first_offset;
int i;
acb = qemu_aio_get(&dictzip_aiocb_info, bs, cb, opaque);
if (!acb)
return NULL;
/* Search Cache */
for (i = 0; i < CACHE_COUNT; i++) {
if (!s->cache[i].len)
continue;
if ((start >= s->cache[i].start) &&
(end <= (s->cache[i].start + s->cache[i].len))) {
acb->buf = s->cache[i].buf + (start - s->cache[i].start);
acb->len = len;
acb->qiov = qiov;
acb->bh = qemu_bh_new(dictzip_cache_cb, acb);
qemu_bh_schedule(acb->bh);
return &acb->common;
}
}
/* No cache, so let's decode */
/* We need to read these chunks */
first_chunk = start / s->chunk_len;
first_offset = start - first_chunk * s->chunk_len;
last_chunk = end / s->chunk_len;
gz_start = s->offsets[first_chunk];
gz_len = 0;
for (i = first_chunk; i <= last_chunk; i++) {
if (s->chunks32)
gz_len += le32_to_cpu(s->chunks32[i]);
else
gz_len += le16_to_cpu(s->chunks[i]);
}
gz_sector_num = gz_start / SECTOR_SIZE;
gz_nb_sectors = (gz_len / SECTOR_SIZE);
/* account for tail and heads */
while ((gz_start + gz_len) > ((gz_sector_num + gz_nb_sectors) * SECTOR_SIZE))
gz_nb_sectors++;
/* Allocate qiov, iov and buf in one chunk so we only need to free qiov */
qiov_gz = g_malloc0(sizeof(QEMUIOVector) + sizeof(struct iovec) +
(gz_nb_sectors * SECTOR_SIZE));
iov = (struct iovec *)(((char *)qiov_gz) + sizeof(QEMUIOVector));
buf = ((uint8_t *)iov) + sizeof(struct iovec *);
/* Kick off the read by the backing file, so we can start decompressing */
iov->iov_base = (void *)buf;
iov->iov_len = gz_nb_sectors * 512;
qemu_iovec_init_external(qiov_gz, iov, 1);
dprintf("read %zd - %zd => %zd - %zd\n", start, end, gz_start, gz_start + gz_len);
acb->s = s;
acb->qiov = qiov;
acb->qiov_gz = qiov_gz;
acb->start = start;
acb->len = len;
acb->gzipped = buf + (gz_start % SECTOR_SIZE);
acb->gz_len = gz_len;
acb->gz_start = first_chunk * s->chunk_len;
acb->offset = first_offset;
acb->chunks_len = (last_chunk - first_chunk + 1) * s->chunk_len;
return bdrv_aio_readv(s->hd, gz_sector_num, qiov_gz, gz_nb_sectors,
dictzip_read_cb, acb);
}
static void dictzip_close(BlockDriverState *bs)
{
BDRVDictZipState *s = bs->opaque;
int i;
for (i = 0; i < CACHE_COUNT; i++) {
if (!s->cache[i].len)
continue;
g_free(s->cache[i].buf);
}
for (i = 0; i < Z_STREAM_COUNT; i++) {
inflateEnd(&s->zStream[i]);
}
if (s->chunks)
g_free(s->chunks);
if (s->offsets)
g_free(s->offsets);
dprintf("Close\n");
}
static int64_t dictzip_getlength(BlockDriverState *bs)
{
BDRVDictZipState *s = bs->opaque;
dprintf("getlength -> %ld\n", s->file_len);
return s->file_len;
}
static BlockDriver bdrv_dictzip = {
.format_name = "dzip",
.protocol_name = "dzip",
.instance_size = sizeof(BDRVDictZipState),
.bdrv_file_open = dictzip_open,
.bdrv_close = dictzip_close,
.bdrv_getlength = dictzip_getlength,
.bdrv_aio_readv = dictzip_aio_readv,
};
static void dictzip_block_init(void)
{
bdrv_register(&bdrv_dictzip);
}
block_init(dictzip_block_init);

View File

@@ -388,7 +388,7 @@ static void coroutine_fn mirror_run(void *opaque)
MirrorBlockJob *s = opaque;
MirrorExitData *data;
BlockDriverState *bs = s->common.bs;
int64_t sector_num, end, sectors_per_chunk, length;
int64_t sector_num, end, length;
uint64_t last_pause_ns;
BlockDriverInfo bdi;
char backing_filename[2]; /* we only need 2 characters because we are only
@@ -442,7 +442,6 @@ static void coroutine_fn mirror_run(void *opaque)
goto immediate_exit;
}
sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
mirror_free_init(s);
last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
@@ -450,7 +449,9 @@ static void coroutine_fn mirror_run(void *opaque)
/* First part, loop on the sectors and initialize the dirty bitmap. */
BlockDriverState *base = s->base;
for (sector_num = 0; sector_num < end; ) {
int64_t next = (sector_num | (sectors_per_chunk - 1)) + 1;
/* Just to make sure we are not exceeding int limit. */
int nb_sectors = MIN(INT_MAX >> BDRV_SECTOR_BITS,
end - sector_num);
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
if (now - last_pause_ns > SLICE_TIME) {
@@ -462,8 +463,7 @@ static void coroutine_fn mirror_run(void *opaque)
goto immediate_exit;
}
ret = bdrv_is_allocated_above(bs, base,
sector_num, next - sector_num, &n);
ret = bdrv_is_allocated_above(bs, base, sector_num, nb_sectors, &n);
if (ret < 0) {
goto immediate_exit;
@@ -472,10 +472,8 @@ static void coroutine_fn mirror_run(void *opaque)
assert(n > 0);
if (ret == 1) {
bdrv_set_dirty_bitmap(s->dirty_bitmap, sector_num, n);
sector_num = next;
} else {
sector_num += n;
}
sector_num += n;
}
}

View File

@@ -865,12 +865,6 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
int i;
int ret = 0;
if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA256)) {
error_setg(errp,
"SHA256 hash support is required for quorum device");
return -EINVAL;
}
qdict_flatten(options);
/* count how many different children are present */
@@ -1061,6 +1055,10 @@ static BlockDriver bdrv_quorum = {
static void bdrv_quorum_init(void)
{
if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA256)) {
/* SHA256 hash support is required for quorum device */
return;
}
bdrv_register(&bdrv_quorum);
}

View File

@@ -318,6 +318,10 @@ enum AIOCBState {
AIOCB_DISCARD_OBJ,
};
#define AIOCBOverwrapping(x, y) \
(!(x->max_affect_data_idx < y->min_affect_data_idx \
|| y->max_affect_data_idx < x->min_affect_data_idx))
struct SheepdogAIOCB {
BlockAIOCB common;
@@ -334,6 +338,11 @@ struct SheepdogAIOCB {
bool cancelable;
int nr_pending;
uint32_t min_affect_data_idx;
uint32_t max_affect_data_idx;
QLIST_ENTRY(SheepdogAIOCB) aiocb_siblings;
};
typedef struct BDRVSheepdogState {
@@ -362,8 +371,10 @@ typedef struct BDRVSheepdogState {
/* Every aio request must be linked to either of these queues. */
QLIST_HEAD(inflight_aio_head, AIOReq) inflight_aio_head;
QLIST_HEAD(pending_aio_head, AIOReq) pending_aio_head;
QLIST_HEAD(failed_aio_head, AIOReq) failed_aio_head;
CoQueue overwrapping_queue;
QLIST_HEAD(inflight_aiocb_head, SheepdogAIOCB) inflight_aiocb_head;
} BDRVSheepdogState;
static const char * sd_strerror(int err)
@@ -498,13 +509,7 @@ static void sd_aio_cancel(BlockAIOCB *blockacb)
AIOReq *aioreq, *next;
if (sd_acb_cancelable(acb)) {
/* Remove outstanding requests from pending and failed queues. */
QLIST_FOREACH_SAFE(aioreq, &s->pending_aio_head, aio_siblings,
next) {
if (aioreq->aiocb == acb) {
free_aio_req(s, aioreq);
}
}
/* Remove outstanding requests from failed queue. */
QLIST_FOREACH_SAFE(aioreq, &s->failed_aio_head, aio_siblings,
next) {
if (aioreq->aiocb == acb) {
@@ -529,6 +534,10 @@ static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov,
int64_t sector_num, int nb_sectors)
{
SheepdogAIOCB *acb;
uint32_t object_size;
BDRVSheepdogState *s = bs->opaque;
object_size = (UINT32_C(1) << s->inode.block_size_shift);
acb = qemu_aio_get(&sd_aiocb_info, bs, NULL, NULL);
@@ -542,6 +551,11 @@ static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov,
acb->coroutine = qemu_coroutine_self();
acb->ret = 0;
acb->nr_pending = 0;
acb->min_affect_data_idx = acb->sector_num * BDRV_SECTOR_SIZE / object_size;
acb->max_affect_data_idx = (acb->sector_num * BDRV_SECTOR_SIZE +
acb->nb_sectors * BDRV_SECTOR_SIZE) / object_size;
return acb;
}
@@ -703,38 +717,6 @@ static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag);
static int get_sheep_fd(BDRVSheepdogState *s, Error **errp);
static void co_write_request(void *opaque);
static AIOReq *find_pending_req(BDRVSheepdogState *s, uint64_t oid)
{
AIOReq *aio_req;
QLIST_FOREACH(aio_req, &s->pending_aio_head, aio_siblings) {
if (aio_req->oid == oid) {
return aio_req;
}
}
return NULL;
}
/*
* This function searchs pending requests to the object `oid', and
* sends them.
*/
static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid)
{
AIOReq *aio_req;
SheepdogAIOCB *acb;
while ((aio_req = find_pending_req(s, oid)) != NULL) {
acb = aio_req->aiocb;
/* move aio_req from pending list to inflight one */
QLIST_REMOVE(aio_req, aio_siblings);
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
acb->aiocb_type);
}
}
static coroutine_fn void reconnect_to_sdog(void *opaque)
{
BDRVSheepdogState *s = opaque;
@@ -840,12 +822,6 @@ static void coroutine_fn aio_read_response(void *opaque)
s->max_dirty_data_idx = MAX(idx, s->max_dirty_data_idx);
s->min_dirty_data_idx = MIN(idx, s->min_dirty_data_idx);
}
/*
* Some requests may be blocked because simultaneous
* create requests are not allowed, so we search the
* pending requests here.
*/
send_pending_req(s, aio_req->oid);
}
break;
case AIOCB_READ_UDATA:
@@ -1341,30 +1317,6 @@ out:
return ret;
}
/* Return true if the specified request is linked to the pending list. */
static bool check_simultaneous_create(BDRVSheepdogState *s, AIOReq *aio_req)
{
AIOReq *areq;
QLIST_FOREACH(areq, &s->inflight_aio_head, aio_siblings) {
if (areq != aio_req && areq->oid == aio_req->oid) {
/*
* Sheepdog cannot handle simultaneous create requests to the same
* object, so we cannot send the request until the previous request
* finishes.
*/
DPRINTF("simultaneous create to %" PRIx64 "\n", aio_req->oid);
aio_req->flags = 0;
aio_req->base_oid = 0;
aio_req->create = false;
QLIST_REMOVE(aio_req, aio_siblings);
QLIST_INSERT_HEAD(&s->pending_aio_head, aio_req, aio_siblings);
return true;
}
}
return false;
}
static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req)
{
SheepdogAIOCB *acb = aio_req->aiocb;
@@ -1379,10 +1331,6 @@ static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req)
goto out;
}
if (check_simultaneous_create(s, aio_req)) {
return;
}
if (s->inode.data_vdi_id[idx]) {
aio_req->base_oid = vid_to_data_oid(s->inode.data_vdi_id[idx], idx);
aio_req->flags |= SD_FLAG_CMD_COW;
@@ -1458,8 +1406,8 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
filename = qemu_opt_get(opts, "filename");
QLIST_INIT(&s->inflight_aio_head);
QLIST_INIT(&s->pending_aio_head);
QLIST_INIT(&s->failed_aio_head);
QLIST_INIT(&s->inflight_aiocb_head);
s->fd = -1;
memset(vdi, 0, sizeof(vdi));
@@ -1524,6 +1472,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
bs->total_sectors = s->inode.vdi_size / BDRV_SECTOR_SIZE;
pstrcpy(s->name, sizeof(s->name), vdi);
qemu_co_mutex_init(&s->lock);
qemu_co_queue_init(&s->overwrapping_queue);
qemu_opts_del(opts);
g_free(buf);
return 0;
@@ -2195,12 +2144,6 @@ static int coroutine_fn sd_co_rw_vector(void *p)
old_oid, done);
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
if (create) {
if (check_simultaneous_create(s, aio_req)) {
goto done;
}
}
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
acb->aiocb_type);
done:
@@ -2215,6 +2158,20 @@ out:
return 1;
}
static bool check_overwrapping_aiocb(BDRVSheepdogState *s, SheepdogAIOCB *aiocb)
{
SheepdogAIOCB *cb;
QLIST_FOREACH(cb, &s->inflight_aiocb_head, aiocb_siblings) {
if (AIOCBOverwrapping(aiocb, cb)) {
return true;
}
}
QLIST_INSERT_HEAD(&s->inflight_aiocb_head, aiocb, aiocb_siblings);
return false;
}
static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov)
{
@@ -2234,14 +2191,25 @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
acb->aio_done_func = sd_write_done;
acb->aiocb_type = AIOCB_WRITE_UDATA;
retry:
if (check_overwrapping_aiocb(s, acb)) {
qemu_co_queue_wait(&s->overwrapping_queue);
goto retry;
}
ret = sd_co_rw_vector(acb);
if (ret <= 0) {
QLIST_REMOVE(acb, aiocb_siblings);
qemu_co_queue_restart_all(&s->overwrapping_queue);
qemu_aio_unref(acb);
return ret;
}
qemu_coroutine_yield();
QLIST_REMOVE(acb, aiocb_siblings);
qemu_co_queue_restart_all(&s->overwrapping_queue);
return acb->ret;
}
@@ -2250,19 +2218,30 @@ static coroutine_fn int sd_co_readv(BlockDriverState *bs, int64_t sector_num,
{
SheepdogAIOCB *acb;
int ret;
BDRVSheepdogState *s = bs->opaque;
acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors);
acb->aiocb_type = AIOCB_READ_UDATA;
acb->aio_done_func = sd_finish_aiocb;
retry:
if (check_overwrapping_aiocb(s, acb)) {
qemu_co_queue_wait(&s->overwrapping_queue);
goto retry;
}
ret = sd_co_rw_vector(acb);
if (ret <= 0) {
QLIST_REMOVE(acb, aiocb_siblings);
qemu_co_queue_restart_all(&s->overwrapping_queue);
qemu_aio_unref(acb);
return ret;
}
qemu_coroutine_yield();
QLIST_REMOVE(acb, aiocb_siblings);
qemu_co_queue_restart_all(&s->overwrapping_queue);
return acb->ret;
}
@@ -2610,14 +2589,25 @@ static coroutine_fn int sd_co_discard(BlockDriverState *bs, int64_t sector_num,
acb->aiocb_type = AIOCB_DISCARD_OBJ;
acb->aio_done_func = sd_finish_aiocb;
retry:
if (check_overwrapping_aiocb(s, acb)) {
qemu_co_queue_wait(&s->overwrapping_queue);
goto retry;
}
ret = sd_co_rw_vector(acb);
if (ret <= 0) {
QLIST_REMOVE(acb, aiocb_siblings);
qemu_co_queue_restart_all(&s->overwrapping_queue);
qemu_aio_unref(acb);
return ret;
}
qemu_coroutine_yield();
QLIST_REMOVE(acb, aiocb_siblings);
qemu_co_queue_restart_all(&s->overwrapping_queue);
return acb->ret;
}

View File

@@ -563,7 +563,7 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
/* Open the socket and connect. */
s->sock = inet_connect(s->hostport, errp);
if (s->sock < 0) {
ret = -errno;
ret = -EIO;
goto err;
}

377
block/tar.c Normal file
View File

@@ -0,0 +1,377 @@
/*
* Tar block driver
*
* Copyright (c) 2009 Alexander Graf <agraf@suse.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu-common.h"
#include "block/block_int.h"
// #define DEBUG
#ifdef DEBUG
#define dprintf(fmt, ...) do { printf("tar: " fmt, ## __VA_ARGS__); } while (0)
#else
#define dprintf(fmt, ...) do { } while (0)
#endif
#define SECTOR_SIZE 512
#define POSIX_TAR_MAGIC "ustar"
#define OFFS_LENGTH 0x7c
#define OFFS_TYPE 0x9c
#define OFFS_MAGIC 0x101
#define OFFS_S_SP 0x182
#define OFFS_S_EXT 0x1e2
#define OFFS_S_LENGTH 0x1e3
#define OFFS_SX_EXT 0x1f8
typedef struct SparseCache {
uint64_t start;
uint64_t end;
} SparseCache;
typedef struct BDRVTarState {
BlockDriverState *hd;
size_t file_sec;
uint64_t file_len;
SparseCache *sparse;
int sparse_num;
uint64_t last_end;
char longfile[2048];
} BDRVTarState;
static int str_ends(char *str, const char *end)
{
int end_len = strlen(end);
int str_len = strlen(str);
if (str_len < end_len)
return 0;
return !strncmp(str + str_len - end_len, end, end_len);
}
static int is_target_file(BlockDriverState *bs, char *filename,
char *header)
{
int retval = 0;
if (str_ends(filename, ".raw"))
retval = 1;
if (str_ends(filename, ".qcow"))
retval = 1;
if (str_ends(filename, ".qcow2"))
retval = 1;
if (str_ends(filename, ".vmdk"))
retval = 1;
if (retval &&
(header[OFFS_TYPE] != '0') &&
(header[OFFS_TYPE] != 'S')) {
retval = 0;
}
dprintf("does filename %s match? %s\n", filename, retval ? "yes" : "no");
/* make sure we're not using this name again */
filename[0] = '\0';
return retval;
}
static uint64_t tar2u64(char *ptr)
{
uint64_t retval;
char oldend = ptr[12];
ptr[12] = '\0';
if (*ptr & 0x80) {
/* XXX we only support files up to 64 bit length */
retval = be64_to_cpu(*(uint64_t *)(ptr+4));
dprintf("Convert %lx -> %#lx\n", *(uint64_t*)(ptr+4), retval);
} else {
retval = strtol(ptr, NULL, 8);
dprintf("Convert %s -> %#lx\n", ptr, retval);
}
ptr[12] = oldend;
return retval;
}
static void tar_sparse(BDRVTarState *s, uint64_t offs, uint64_t len)
{
SparseCache *sparse;
if (!len)
return;
if (!(offs - s->last_end)) {
s->last_end += len;
return;
}
if (s->last_end > offs)
return;
dprintf("Last chunk until %lx new chunk at %lx\n", s->last_end, offs);
s->sparse = g_realloc(s->sparse, (s->sparse_num + 1) * sizeof(SparseCache));
sparse = &s->sparse[s->sparse_num];
sparse->start = s->last_end;
sparse->end = offs;
s->last_end = offs + len;
s->sparse_num++;
dprintf("Sparse at %lx end=%lx\n", sparse->start,
sparse->end);
}
static QemuOptsList runtime_opts = {
.name = "tar",
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
.desc = {
{
.name = "filename",
.type = QEMU_OPT_STRING,
.help = "URL to the tar file",
},
{ /* end of list */ }
},
};
static int tar_open(BlockDriverState *bs, QDict *options, int flags, Error **errp)
{
BDRVTarState *s = bs->opaque;
char header[SECTOR_SIZE];
char *real_file = header;
char *magic;
size_t header_offs = 0;
int ret;
QemuOpts *opts;
Error *local_err = NULL;
const char *filename;
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
}
filename = qemu_opt_get(opts, "filename");
if (!strncmp(filename, "tar://", 6))
filename += 6;
else if (!strncmp(filename, "tar:", 4))
filename += 4;
ret = bdrv_open(&s->hd, filename, NULL, NULL, flags | BDRV_O_PROTOCOL, NULL, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
qemu_opts_del(opts);
return ret;
}
/* Search the file for an image */
do {
/* tar header */
if (bdrv_pread(s->hd, header_offs, header, SECTOR_SIZE) != SECTOR_SIZE)
goto fail;
if ((header_offs > 1) && !header[0]) {
fprintf(stderr, "Tar: No image file found in archive\n");
goto fail;
}
magic = &header[OFFS_MAGIC];
if (strncmp(magic, POSIX_TAR_MAGIC, 5)) {
fprintf(stderr, "Tar: Invalid magic: %s\n", magic);
goto fail;
}
dprintf("file type: %c\n", header[OFFS_TYPE]);
/* file length*/
s->file_len = (tar2u64(&header[OFFS_LENGTH]) + (SECTOR_SIZE - 1)) &
~(SECTOR_SIZE - 1);
s->file_sec = (header_offs / SECTOR_SIZE) + 1;
header_offs += s->file_len + SECTOR_SIZE;
if (header[OFFS_TYPE] == 'L') {
bdrv_pread(s->hd, header_offs - s->file_len, s->longfile,
sizeof(s->longfile));
s->longfile[sizeof(s->longfile)-1] = '\0';
real_file = header;
} else if (s->longfile[0]) {
real_file = s->longfile;
} else {
real_file = header;
}
} while(!is_target_file(bs, real_file, header));
/* We found an image! */
if (header[OFFS_TYPE] == 'S') {
uint8_t isextended;
int i;
for (i = OFFS_S_SP; i < (OFFS_S_SP + (4 * 24)); i += 24)
tar_sparse(s, tar2u64(&header[i]), tar2u64(&header[i+12]));
s->file_len = tar2u64(&header[OFFS_S_LENGTH]);
isextended = header[OFFS_S_EXT];
while (isextended) {
if (bdrv_pread(s->hd, s->file_sec * SECTOR_SIZE, header,
SECTOR_SIZE) != SECTOR_SIZE)
goto fail;
for (i = 0; i < (21 * 24); i += 24)
tar_sparse(s, tar2u64(&header[i]), tar2u64(&header[i+12]));
isextended = header[OFFS_SX_EXT];
s->file_sec++;
}
tar_sparse(s, s->file_len, 1);
}
qemu_opts_del(opts);
return 0;
fail:
fprintf(stderr, "Tar: Error opening file\n");
bdrv_unref(s->hd);
qemu_opts_del(opts);
return -EINVAL;
}
typedef struct TarAIOCB {
BlockAIOCB common;
QEMUBH *bh;
} TarAIOCB;
/* This callback gets invoked when we have pure sparseness */
static void tar_sparse_cb(void *opaque)
{
TarAIOCB *acb = (TarAIOCB *)opaque;
acb->common.cb(acb->common.opaque, 0);
qemu_bh_delete(acb->bh);
qemu_aio_unref(acb);
}
static AIOCBInfo tar_aiocb_info = {
.aiocb_size = sizeof(TarAIOCB),
};
/* This is where we get a request from a caller to read something */
static BlockAIOCB *tar_aio_readv(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockCompletionFunc *cb, void *opaque)
{
BDRVTarState *s = bs->opaque;
SparseCache *sparse;
int64_t sec_file = sector_num + s->file_sec;
int64_t start = sector_num * SECTOR_SIZE;
int64_t end = start + (nb_sectors * SECTOR_SIZE);
int i;
TarAIOCB *acb;
for (i = 0; i < s->sparse_num; i++) {
sparse = &s->sparse[i];
if (sparse->start > end) {
/* We expect the cache to be start increasing */
break;
} else if ((sparse->start < start) && (sparse->end <= start)) {
/* sparse before our offset */
sec_file -= (sparse->end - sparse->start) / SECTOR_SIZE;
} else if ((sparse->start <= start) && (sparse->end >= end)) {
/* all our sectors are sparse */
char *buf = g_malloc0(nb_sectors * SECTOR_SIZE);
acb = qemu_aio_get(&tar_aiocb_info, bs, cb, opaque);
qemu_iovec_from_buf(qiov, 0, buf, nb_sectors * SECTOR_SIZE);
g_free(buf);
acb->bh = qemu_bh_new(tar_sparse_cb, acb);
qemu_bh_schedule(acb->bh);
return &acb->common;
} else if (((sparse->start >= start) && (sparse->start < end)) ||
((sparse->end >= start) && (sparse->end < end))) {
/* we're semi-sparse (worst case) */
/* let's go synchronous and read all sectors individually */
char *buf = g_malloc(nb_sectors * SECTOR_SIZE);
uint64_t offs;
for (offs = 0; offs < (nb_sectors * SECTOR_SIZE);
offs += SECTOR_SIZE) {
bdrv_pread(bs, (sector_num * SECTOR_SIZE) + offs,
buf + offs, SECTOR_SIZE);
}
qemu_iovec_from_buf(qiov, 0, buf, nb_sectors * SECTOR_SIZE);
acb = qemu_aio_get(&tar_aiocb_info, bs, cb, opaque);
acb->bh = qemu_bh_new(tar_sparse_cb, acb);
qemu_bh_schedule(acb->bh);
return &acb->common;
}
}
return bdrv_aio_readv(s->hd, sec_file, qiov, nb_sectors,
cb, opaque);
}
static void tar_close(BlockDriverState *bs)
{
dprintf("Close\n");
}
static int64_t tar_getlength(BlockDriverState *bs)
{
BDRVTarState *s = bs->opaque;
dprintf("getlength -> %ld\n", s->file_len);
return s->file_len;
}
static BlockDriver bdrv_tar = {
.format_name = "tar",
.protocol_name = "tar",
.instance_size = sizeof(BDRVTarState),
.bdrv_file_open = tar_open,
.bdrv_close = tar_close,
.bdrv_getlength = tar_getlength,
.bdrv_aio_readv = tar_aio_readv,
};
static void tar_block_init(void)
{
bdrv_register(&bdrv_tar);
}
block_init(tar_block_init);

View File

@@ -1845,9 +1845,12 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false)) {
zeroed_grain = true;
}
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_SCSI, false)) {
flags |= BLOCK_FLAG_SCSI;
}
if (!adapter_type) {
adapter_type = g_strdup("ide");
adapter_type = g_strdup(flags & BLOCK_FLAG_SCSI ? "lsilogic" : "ide");
} else if (strcmp(adapter_type, "ide") &&
strcmp(adapter_type, "buslogic") &&
strcmp(adapter_type, "lsilogic") &&
@@ -2262,6 +2265,11 @@ static QemuOptsList vmdk_create_opts = {
.help = "Enable efficient zero writes "
"using the zeroed-grain GTE feature"
},
{
.name = BLOCK_OPT_SCSI,
.type = QEMU_OPT_BOOL,
.help = "SCSI image"
},
{ /* end of list */ }
}
};

View File

@@ -168,6 +168,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
uint8_t buf[HEADER_SIZE];
uint32_t checksum;
uint64_t computed_size;
uint64_t pagetable_size;
int disk_type = VHD_DYNAMIC;
int ret;
@@ -269,7 +270,17 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
s->pagetable = qemu_try_blockalign(bs->file, s->max_table_entries * 4);
if (s->max_table_entries > SIZE_MAX / 4 ||
s->max_table_entries > (int) INT_MAX / 4) {
error_setg(errp, "Max Table Entries too large (%" PRId32 ")",
s->max_table_entries);
ret = -EINVAL;
goto fail;
}
pagetable_size = (uint64_t) s->max_table_entries * 4;
s->pagetable = qemu_try_blockalign(bs->file, pagetable_size);
if (s->pagetable == NULL) {
ret = -ENOMEM;
goto fail;
@@ -277,14 +288,13 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);
ret = bdrv_pread(bs->file, s->bat_offset, s->pagetable,
s->max_table_entries * 4);
ret = bdrv_pread(bs->file, s->bat_offset, s->pagetable, pagetable_size);
if (ret < 0) {
goto fail;
}
s->free_data_block_offset =
(s->bat_offset + (s->max_table_entries * 4) + 511) & ~511;
ROUND_UP(s->bat_offset + pagetable_size, 512);
for (i = 0; i < s->max_table_entries; i++) {
be32_to_cpus(&s->pagetable[i]);

View File

@@ -173,7 +173,7 @@ void cpu_loop(CPUX86State *env)
//target_siginfo_t info;
for(;;) {
trapnr = cpu_x86_exec(env);
trapnr = cpu_x86_exec(cs);
switch(trapnr) {
case 0x80:
/* syscall from int $0x80 */

34
configure vendored
View File

@@ -1337,7 +1337,6 @@ disabled with --disable-FEATURE, default is enabled if available:
vnc-sasl SASL encryption for VNC server
vnc-jpeg JPEG lossy compression for VNC server
vnc-png PNG compression for VNC server
vnc-ws Websockets support for VNC server
cocoa Cocoa UI (Mac OS X only)
virtfs VirtFS
xen xen backend driver support
@@ -1531,7 +1530,7 @@ fi
if test "$pie" = ""; then
case "$cpu-$targetos" in
i386-Linux|x86_64-Linux|x32-Linux|i386-OpenBSD|x86_64-OpenBSD)
i386-Linux|x86_64-Linux|x32-Linux|ppc*-Linux|i386-OpenBSD|x86_64-OpenBSD)
;;
*)
pie="no"
@@ -1828,14 +1827,19 @@ fi
# libseccomp check
if test "$seccomp" != "no" ; then
if test "$cpu" = "i386" || test "$cpu" = "x86_64" &&
$pkg_config --atleast-version=2.1.1 libseccomp; then
if $pkg_config --atleast-version=2.2.0 libseccomp ||
(test "$cpu" = "i386" || test "$cpu" = "x86_64" &&
$pkg_config --atleast-version=2.1.1 libseccomp); then
libs_softmmu="$libs_softmmu `$pkg_config --libs libseccomp`"
QEMU_CFLAGS="$QEMU_CFLAGS `$pkg_config --cflags libseccomp`"
seccomp="yes"
else
if test "$seccomp" = "yes"; then
if test "$cpu" = "i386" || test "$cpu" = "x86_64"; then
feature_not_found "libseccomp" "Install libseccomp devel >= 2.1.1"
else
feature_not_found "libseccomp" "Install libseccomp devel >= 2.2.0"
fi
fi
seccomp="no"
fi
@@ -2116,10 +2120,26 @@ fi
##########################################
# GNUTLS probe
gnutls_works() {
# Unfortunately some distros have bad pkg-config information for gnutls
# such that it claims to exist but you get a compiler error if you try
# to use the options returned by --libs. Specifically, Ubuntu for --static
# builds doesn't work:
# https://bugs.launchpad.net/ubuntu/+source/gnutls26/+bug/1478035
#
# So sanity check the cflags/libs before assuming gnutls can be used.
if ! $pkg_config --exists "gnutls"; then
return 1
fi
write_c_skeleton
compile_prog "$($pkg_config --cflags gnutls)" "$($pkg_config --libs gnutls)"
}
gnutls_gcrypt=no
gnutls_nettle=no
if test "$gnutls" != "no"; then
if $pkg_config --exists "gnutls"; then
if gnutls_works; then
gnutls_cflags=`$pkg_config --cflags gnutls`
gnutls_libs=`$pkg_config --libs gnutls`
libs_softmmu="$gnutls_libs $libs_softmmu"
@@ -2183,6 +2203,7 @@ if test "$gnutls_nettle" != "no"; then
if $pkg_config --exists "nettle"; then
nettle_cflags=`$pkg_config --cflags nettle`
nettle_libs=`$pkg_config --libs nettle`
nettle_version=`$pkg_config --modversion nettle`
libs_softmmu="$nettle_libs $libs_softmmu"
libs_tools="$nettle_libs $libs_tools"
QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
@@ -4490,7 +4511,7 @@ echo "GTK support $gtk"
echo "GNUTLS support $gnutls"
echo "GNUTLS hash $gnutls_hash"
echo "GNUTLS gcrypt $gnutls_gcrypt"
echo "GNUTLS nettle $gnutls_nettle"
echo "GNUTLS nettle $gnutls_nettle ${gnutls_nettle+($nettle_version)}"
echo "VTE support $vte"
echo "curses support $curses"
echo "curl support $curl"
@@ -4858,6 +4879,7 @@ if test "$gnutls_gcrypt" = "yes" ; then
fi
if test "$gnutls_nettle" = "yes" ; then
echo "CONFIG_GNUTLS_NETTLE=y" >> $config_host_mak
echo "CONFIG_NETTLE_VERSION_MAJOR=${nettle_version%%.*}" >> $config_host_mak
fi
if test "$vte" = "yes" ; then
echo "CONFIG_VTE=y" >> $config_host_mak

6
cpus.c
View File

@@ -954,6 +954,8 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
CPUState *cpu = arg;
int r;
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_thread_get_self(cpu->thread);
cpu->thread_id = qemu_get_thread_id();
@@ -995,6 +997,8 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
sigset_t waitset;
int r;
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_thread_get_self(cpu->thread);
cpu->thread_id = qemu_get_thread_id();
@@ -1034,6 +1038,8 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_tcg_init_cpu_signals();
qemu_thread_get_self(cpu->thread);

View File

@@ -117,7 +117,7 @@ static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher,
uint8_t *outptr = out;
while (len) {
if (len > AES_BLOCK_SIZE) {
AES_decrypt(inptr, outptr, &ctxt->state.aes.encrypt_key);
AES_decrypt(inptr, outptr, &ctxt->state.aes.decrypt_key);
inptr += AES_BLOCK_SIZE;
outptr += AES_BLOCK_SIZE;
len -= AES_BLOCK_SIZE;
@@ -126,15 +126,15 @@ static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher,
memcpy(tmp1, inptr, len);
/* Fill with 0 to avoid valgrind uninitialized reads */
memset(tmp1 + len, 0, sizeof(tmp1) - len);
AES_decrypt(tmp1, tmp2, &ctxt->state.aes.encrypt_key);
AES_decrypt(tmp1, tmp2, &ctxt->state.aes.decrypt_key);
memcpy(outptr, tmp2, len);
len = 0;
}
}
} else {
AES_cbc_encrypt(in, out, len,
&ctxt->state.aes.encrypt_key,
ctxt->state.aes.iv, 1);
&ctxt->state.aes.decrypt_key,
ctxt->state.aes.iv, 0);
}
return 0;

View File

@@ -23,12 +23,51 @@
#include <nettle/des.h>
#include <nettle/cbc.h>
#if CONFIG_NETTLE_VERSION_MAJOR < 3
typedef nettle_crypt_func nettle_cipher_func;
typedef void * cipher_ctx_t;
typedef unsigned cipher_length_t;
#else
typedef const void * cipher_ctx_t;
typedef size_t cipher_length_t;
#endif
static nettle_cipher_func aes_encrypt_wrapper;
static nettle_cipher_func aes_decrypt_wrapper;
static nettle_cipher_func des_encrypt_wrapper;
static nettle_cipher_func des_decrypt_wrapper;
static void aes_encrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length,
uint8_t *dst, const uint8_t *src)
{
aes_encrypt(ctx, length, dst, src);
}
static void aes_decrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length,
uint8_t *dst, const uint8_t *src)
{
aes_decrypt(ctx, length, dst, src);
}
static void des_encrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length,
uint8_t *dst, const uint8_t *src)
{
des_encrypt(ctx, length, dst, src);
}
static void des_decrypt_wrapper(cipher_ctx_t ctx, cipher_length_t length,
uint8_t *dst, const uint8_t *src)
{
des_decrypt(ctx, length, dst, src);
}
typedef struct QCryptoCipherNettle QCryptoCipherNettle;
struct QCryptoCipherNettle {
void *ctx_encrypt;
void *ctx_decrypt;
nettle_crypt_func *alg_encrypt;
nettle_crypt_func *alg_decrypt;
nettle_cipher_func *alg_encrypt;
nettle_cipher_func *alg_decrypt;
uint8_t *iv;
size_t niv;
};
@@ -83,8 +122,8 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
des_set_key(ctx->ctx_encrypt, rfbkey);
g_free(rfbkey);
ctx->alg_encrypt = (nettle_crypt_func *)des_encrypt;
ctx->alg_decrypt = (nettle_crypt_func *)des_decrypt;
ctx->alg_encrypt = des_encrypt_wrapper;
ctx->alg_decrypt = des_decrypt_wrapper;
ctx->niv = DES_BLOCK_SIZE;
break;
@@ -98,8 +137,8 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
aes_set_encrypt_key(ctx->ctx_encrypt, nkey, key);
aes_set_decrypt_key(ctx->ctx_decrypt, nkey, key);
ctx->alg_encrypt = (nettle_crypt_func *)aes_encrypt;
ctx->alg_decrypt = (nettle_crypt_func *)aes_decrypt;
ctx->alg_encrypt = aes_encrypt_wrapper;
ctx->alg_decrypt = aes_decrypt_wrapper;
ctx->niv = AES_BLOCK_SIZE;
break;

View File

@@ -241,7 +241,7 @@ uint32_t qemu_fdt_alloc_phandle(void *fdt)
/*
* We need to find out if the user gave us special instruction at
* which phandle id to start allocting phandles.
* which phandle id to start allocating phandles.
*/
if (!phandle) {
phandle = machine_phandle_start(current_machine);

View File

@@ -42,7 +42,7 @@ public:
stream_ = stream;
}
void SetPrintf(int (*printf_fn)(FILE *, const char *, ...)) {
void SetPrintf(fprintf_function printf_fn) {
printf_ = printf_fn;
}
@@ -53,7 +53,7 @@ protected:
}
private:
int (*printf_)(FILE *, const char *, ...);
fprintf_function printf_;
FILE *stream_;
};

View File

@@ -1,5 +1,5 @@
/*
* This model describes the interaction between aio_set_dispatching()
* This model describes the interaction between ctx->notify_me
* and aio_notify().
*
* Author: Paolo Bonzini <pbonzini@redhat.com>
@@ -14,57 +14,53 @@
* spin -a docs/aio_notify.promela
* gcc -O2 pan.c
* ./a.out -a
*
* To verify it (with a bug planted in the model):
* spin -a -DBUG docs/aio_notify.promela
* gcc -O2 pan.c
* ./a.out -a
*/
#define MAX 4
#define LAST (1 << (MAX - 1))
#define FINAL ((LAST << 1) - 1)
bool dispatching;
bool notify_me;
bool event;
int req, done;
int req;
int done;
active proctype waiter()
{
int fetch, blocking;
int fetch;
do
:: done != FINAL -> {
// Computing "blocking" is separate from execution of the
// "bottom half"
blocking = (req == 0);
do
:: true -> {
notify_me++;
if
#ifndef BUG
:: (req > 0) -> skip;
#endif
:: else ->
// Wait for a nudge from the other side
do
:: event == 1 -> { event = 0; break; }
od;
fi;
notify_me--;
// This is our "bottom half"
atomic { fetch = req; req = 0; }
done = done | fetch;
// Wait for a nudge from the other side
do
:: event == 1 -> { event = 0; break; }
:: !blocking -> break;
od;
dispatching = 1;
// If you are simulating this model, you may want to add
// something like this here:
//
// int foo; foo++; foo++; foo++;
//
// This only wastes some time and makes it more likely
// that the notifier process hits the "fast path".
dispatching = 0;
}
:: else -> break;
od
}
active proctype notifier()
{
int next = 1;
int sets = 0;
do
:: next <= LAST -> {
@@ -74,8 +70,8 @@ active proctype notifier()
// aio_notify
if
:: dispatching == 0 -> sets++; event = 1;
:: else -> skip;
:: notify_me == 1 -> event = 1;
:: else -> printf("Skipped event_notifier_set\n"); skip;
fi;
// Test both synchronous and asynchronous delivery
@@ -86,19 +82,12 @@ active proctype notifier()
:: 1 -> skip;
fi;
}
:: else -> break;
od;
printf("Skipped %d event_notifier_set\n", MAX - sets);
}
#define p (done == FINAL)
never {
do
:: 1 // after an arbitrarily long prefix
:: p -> break // p becomes true
od;
do
:: !p -> accept: break // it then must remains true forever after
od
never { /* [] done < FINAL */
accept_init:
do
:: done < FINAL -> skip;
od;
}

View File

@@ -0,0 +1,152 @@
/*
* This model describes the interaction between ctx->notified
* and ctx->notifier.
*
* Author: Paolo Bonzini <pbonzini@redhat.com>
*
* This file is in the public domain. If you really want a license,
* the WTFPL will do.
*
* To verify the buggy version:
* spin -a -DBUG1 docs/aio_notify_bug.promela
* gcc -O2 pan.c
* ./a.out -a -f
* (or -DBUG2)
*
* To verify the fixed version:
* spin -a docs/aio_notify_bug.promela
* gcc -O2 pan.c
* ./a.out -a -f
*
* Add -DCHECK_REQ to test an alternative invariant and the
* "notify_me" optimization.
*/
int notify_me;
bool notified;
bool event;
bool req;
bool notifier_done;
#ifdef CHECK_REQ
#define USE_NOTIFY_ME 1
#else
#define USE_NOTIFY_ME 0
#endif
#ifdef BUG
#error Please define BUG1 or BUG2 instead.
#endif
active proctype notifier()
{
do
:: true -> {
req = 1;
if
:: !USE_NOTIFY_ME || notify_me ->
#if defined BUG1
/* CHECK_REQ does not detect this bug! */
notified = 1;
event = 1;
#elif defined BUG2
if
:: !notified -> event = 1;
:: else -> skip;
fi;
notified = 1;
#else
event = 1;
notified = 1;
#endif
:: else -> skip;
fi
}
:: true -> break;
od;
notifier_done = 1;
}
#define AIO_POLL \
notify_me++; \
if \
:: !req -> { \
if \
:: event -> skip; \
fi; \
} \
:: else -> skip; \
fi; \
notify_me--; \
\
atomic { old = notified; notified = 0; } \
if \
:: old -> event = 0; \
:: else -> skip; \
fi; \
\
req = 0;
active proctype waiter()
{
bool old;
do
:: true -> AIO_POLL;
od;
}
/* Same as waiter(), but disappears after a while. */
active proctype temporary_waiter()
{
bool old;
do
:: true -> AIO_POLL;
:: true -> break;
od;
}
#ifdef CHECK_REQ
never {
do
:: req -> goto accept_if_req_not_eventually_false;
:: true -> skip;
od;
accept_if_req_not_eventually_false:
if
:: req -> goto accept_if_req_not_eventually_false;
fi;
assert(0);
}
#else
/* There must be infinitely many transitions of event as long
* as the notifier does not exit.
*
* If event stayed always true, the waiters would be busy looping.
* If event stayed always false, the waiters would be sleeping
* forever.
*/
never {
do
:: !event -> goto accept_if_event_not_eventually_true;
:: event -> goto accept_if_event_not_eventually_false;
:: true -> skip;
od;
accept_if_event_not_eventually_true:
if
:: !event && notifier_done -> do :: true -> skip; od;
:: !event && !notifier_done -> goto accept_if_event_not_eventually_true;
fi;
assert(0);
accept_if_event_not_eventually_false:
if
:: event -> goto accept_if_event_not_eventually_false;
fi;
assert(0);
}
#endif

140
docs/aio_notify_bug.promela Normal file
View File

@@ -0,0 +1,140 @@
/*
* This model describes a bug in aio_notify. If ctx->notifier is
* cleared too late, a wakeup could be lost.
*
* Author: Paolo Bonzini <pbonzini@redhat.com>
*
* This file is in the public domain. If you really want a license,
* the WTFPL will do.
*
* To verify the buggy version:
* spin -a -DBUG docs/aio_notify_bug.promela
* gcc -O2 pan.c
* ./a.out -a -f
*
* To verify the fixed version:
* spin -a docs/aio_notify_bug.promela
* gcc -O2 pan.c
* ./a.out -a -f
*
* Add -DCHECK_REQ to test an alternative invariant and the
* "notify_me" optimization.
*/
int notify_me;
bool event;
bool req;
bool notifier_done;
#ifdef CHECK_REQ
#define USE_NOTIFY_ME 1
#else
#define USE_NOTIFY_ME 0
#endif
active proctype notifier()
{
do
:: true -> {
req = 1;
if
:: !USE_NOTIFY_ME || notify_me -> event = 1;
:: else -> skip;
fi
}
:: true -> break;
od;
notifier_done = 1;
}
#ifdef BUG
#define AIO_POLL \
notify_me++; \
if \
:: !req -> { \
if \
:: event -> skip; \
fi; \
} \
:: else -> skip; \
fi; \
notify_me--; \
\
req = 0; \
event = 0;
#else
#define AIO_POLL \
notify_me++; \
if \
:: !req -> { \
if \
:: event -> skip; \
fi; \
} \
:: else -> skip; \
fi; \
notify_me--; \
\
event = 0; \
req = 0;
#endif
active proctype waiter()
{
do
:: true -> AIO_POLL;
od;
}
/* Same as waiter(), but disappears after a while. */
active proctype temporary_waiter()
{
do
:: true -> AIO_POLL;
:: true -> break;
od;
}
#ifdef CHECK_REQ
never {
do
:: req -> goto accept_if_req_not_eventually_false;
:: true -> skip;
od;
accept_if_req_not_eventually_false:
if
:: req -> goto accept_if_req_not_eventually_false;
fi;
assert(0);
}
#else
/* There must be infinitely many transitions of event as long
* as the notifier does not exit.
*
* If event stayed always true, the waiters would be busy looping.
* If event stayed always false, the waiters would be sleeping
* forever.
*/
never {
do
:: !event -> goto accept_if_event_not_eventually_true;
:: event -> goto accept_if_event_not_eventually_false;
:: true -> skip;
od;
accept_if_event_not_eventually_true:
if
:: !event && notifier_done -> do :: true -> skip; od;
:: !event && !notifier_done -> goto accept_if_event_not_eventually_true;
fi;
assert(0);
accept_if_event_not_eventually_false:
if
:: event -> goto accept_if_event_not_eventually_false;
fi;
assert(0);
}
#endif

View File

@@ -127,11 +127,6 @@ in the ancillary data:
If Master is unable to send the full message or receives a wrong reply it will
close the connection. An optional reconnection mechanism can be implemented.
Multi queue support
-------------------
The protocol supports multiple queues by setting all index fields in the sent
messages to a properly calculated value.
Message types
-------------

7
exec.c
View File

@@ -954,7 +954,10 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
iotlb |= PHYS_SECTION_ROM;
}
} else {
iotlb = section - section->address_space->dispatch->map.sections;
AddressSpaceDispatch *d;
d = atomic_rcu_read(&section->address_space->dispatch);
iotlb = section - d->map.sections;
iotlb += xlat;
}
@@ -1180,11 +1183,13 @@ static void *file_ram_alloc(RAMBlock *block,
goto error;
}
#ifndef TARGET_PPC
if (kvm_enabled() && !kvm_has_sync_mmu()) {
error_setg(errp,
"host lacks kvm mmu notifiers, -mem-path unsupported");
goto error;
}
#endif
/* Make name safe to use with mkstemp by replacing '/' with '_'. */
sanitized_name = g_strdup(memory_region_name(block->mr));

View File

@@ -9,6 +9,13 @@
* the COPYING file in the top-level directory.
*/
/* work around a broken sys/capability.h */
#if defined(__i386__)
typedef unsigned long long __u64;
#endif
#if defined(__powerpc64__)
#include <asm/types.h>
#endif
#include <sys/resource.h>
#include <getopt.h>
#include <syslog.h>

View File

@@ -1285,6 +1285,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
ret = GDB_SIGNAL_UNKNOWN;
break;
}
gdb_set_stop_cpu(cpu);
snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(cpu));
send_packet:

View File

@@ -21,7 +21,8 @@
#include "virtio-9p-coth.h"
#include "hw/virtio/virtio-access.h"
static uint64_t virtio_9p_get_features(VirtIODevice *vdev, uint64_t features)
static uint64_t virtio_9p_get_features(VirtIODevice *vdev, uint64_t features,
Error **errp)
{
virtio_add_feature(&features, VIRTIO_9P_MOUNT_TAG);
return features;

View File

@@ -14,6 +14,7 @@
#include "hw/virtio/virtio.h"
#include "hw/i386/pc.h"
#include "qemu/error-report.h"
#include "qemu/iov.h"
#include "qemu/sockets.h"
#include "virtio-9p.h"
#include "fsdev/qemu-fsdev.h"
@@ -3261,16 +3262,26 @@ void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
while ((pdu = alloc_pdu(s)) &&
(len = virtqueue_pop(vq, &pdu->elem)) != 0) {
uint8_t *ptr;
struct {
uint32_t size_le;
uint8_t id;
uint16_t tag_le;
} QEMU_PACKED out;
int len;
pdu->s = s;
BUG_ON(pdu->elem.out_num == 0 || pdu->elem.in_num == 0);
BUG_ON(pdu->elem.out_sg[0].iov_len < 7);
QEMU_BUILD_BUG_ON(sizeof out != 7);
ptr = pdu->elem.out_sg[0].iov_base;
len = iov_to_buf(pdu->elem.out_sg, pdu->elem.out_num, 0,
&out, sizeof out);
BUG_ON(len != sizeof out);
pdu->size = le32_to_cpu(out.size_le);
pdu->id = out.id;
pdu->tag = le16_to_cpu(out.tag_le);
pdu->size = le32_to_cpu(*(uint32_t *)ptr);
pdu->id = ptr[4];
pdu->tag = le16_to_cpu(*(uint16_t *)(ptr + 5));
qemu_co_queue_init(&pdu->complete);
submit_pdu(s, pdu);
}

View File

@@ -206,9 +206,6 @@ const VMStateDescription vmstate_ich9_pm = {
},
.subsections = (const VMStateDescription*[]) {
&vmstate_memhp_state,
NULL
},
.subsections = (const VMStateDescription*[]) {
&vmstate_tco_io_state,
NULL
}
@@ -224,9 +221,9 @@ static void pm_reset(void *opaque)
acpi_pm_tmr_reset(&pm->acpi_regs);
acpi_gpe_reset(&pm->acpi_regs);
pm->smi_en = 0;
if (!pm->smm_enabled) {
/* Mark SMM as already inited to prevent SMM from running. KVM does not
* support SMM mode. */
/* Mark SMM as already inited to prevent SMM from running. */
pm->smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
}
pm->smi_en_wmask = ~0;

View File

@@ -187,11 +187,6 @@ static void eth_rx_desc_get(uint32_t addr, mv88w8618_rx_desc *desc)
le32_to_cpus(&desc->next);
}
static int eth_can_receive(NetClientState *nc)
{
return 1;
}
static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size)
{
mv88w8618_eth_state *s = qemu_get_nic_opaque(nc);
@@ -381,7 +376,6 @@ static void eth_cleanup(NetClientState *nc)
static NetClientInfo net_mv88w8618_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = eth_can_receive,
.receive = eth_receive,
.cleanup = eth_cleanup,
};

View File

@@ -144,6 +144,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
} else {
s->boot_cpu_ptr = &s->apu_cpu[i];
}
g_free(name);
object_property_set_int(OBJECT(&s->apu_cpu[i]), GIC_BASE_ADDR,
"reset-cbar", &err);
@@ -181,6 +182,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
} else {
s->boot_cpu_ptr = &s->rpu_cpu[i];
}
g_free(name);
object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, "reset-hivecs",
&err);

View File

@@ -223,8 +223,8 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
virtio_blk_data_plane_stop(s);
blk_op_unblock_all(s->conf->conf.blk, s->blocker);
error_free(s->blocker);
object_unref(OBJECT(s->iothread));
qemu_bh_delete(s->bh);
object_unref(OBJECT(s->iothread));
g_free(s);
}

View File

@@ -722,7 +722,8 @@ static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
aio_context_release(blk_get_aio_context(s->blk));
}
static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features)
static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features,
Error **errp)
{
VirtIOBlock *s = VIRTIO_BLK(vdev);
@@ -730,7 +731,15 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features)
virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY);
virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
virtio_add_feature(&features, VIRTIO_BLK_F_SCSI);
if (__virtio_has_feature(features, VIRTIO_F_VERSION_1)) {
if (s->conf.scsi) {
error_setg(errp, "Please set scsi=off for virtio-blk devices in order to use virtio 1.0");
return 0;
}
} else {
virtio_clear_feature(&features, VIRTIO_F_ANY_LAYOUT);
virtio_add_feature(&features, VIRTIO_BLK_F_SCSI);
}
if (s->conf.config_wce) {
virtio_add_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);

View File

@@ -195,7 +195,8 @@ static size_t send_control_msg(VirtIOSerial *vser, void *buf, size_t len)
return 0;
}
memcpy(elem.in_sg[0].iov_base, buf, len);
/* TODO: detect a buffer that's too short, set NEEDS_RESET */
iov_from_buf(elem.in_sg, elem.in_num, 0, buf, len);
virtqueue_push(vq, &elem, len);
virtio_notify(VIRTIO_DEVICE(vser), vq);
@@ -499,7 +500,8 @@ static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
}
}
static uint64_t get_features(VirtIODevice *vdev, uint64_t features)
static uint64_t get_features(VirtIODevice *vdev, uint64_t features,
Error **errp)
{
VirtIOSerial *vser;

View File

@@ -21,12 +21,40 @@
#include "ui/console.h"
#include "framebuffer.h"
void framebuffer_update_memory_section(
MemoryRegionSection *mem_section,
MemoryRegion *root,
hwaddr base,
unsigned rows,
unsigned src_width)
{
hwaddr src_len = (hwaddr)rows * src_width;
if (mem_section->mr) {
memory_region_set_log(mem_section->mr, false, DIRTY_MEMORY_VGA);
memory_region_unref(mem_section->mr);
mem_section->mr = NULL;
}
*mem_section = memory_region_find(root, base, src_len);
if (!mem_section->mr) {
return;
}
if (int128_get64(mem_section->size) < src_len ||
!memory_region_is_ram(mem_section->mr)) {
memory_region_unref(mem_section->mr);
mem_section->mr = NULL;
return;
}
memory_region_set_log(mem_section->mr, true, DIRTY_MEMORY_VGA);
}
/* Render an image from a shared memory framebuffer. */
void framebuffer_update_display(
DisplaySurface *ds,
MemoryRegion *address_space,
hwaddr base,
MemoryRegionSection *mem_section,
int cols, /* Width in pixels. */
int rows, /* Height in pixels. */
int src_width, /* Length of source line, in bytes. */
@@ -41,51 +69,33 @@ void framebuffer_update_display(
hwaddr src_len;
uint8_t *dest;
uint8_t *src;
uint8_t *src_base;
int first, last = 0;
int dirty;
int i;
ram_addr_t addr;
MemoryRegionSection mem_section;
MemoryRegion *mem;
i = *first_row;
*first_row = -1;
src_len = src_width * rows;
mem_section = memory_region_find(address_space, base, src_len);
mem = mem_section.mr;
if (int128_get64(mem_section.size) != src_len ||
!memory_region_is_ram(mem_section.mr)) {
goto out;
mem = mem_section->mr;
if (!mem) {
return;
}
assert(mem);
assert(mem_section.offset_within_address_space == base);
memory_region_sync_dirty_bitmap(mem);
if (!memory_region_is_logging(mem, DIRTY_MEMORY_VGA)) {
invalidate = true;
}
src_base = cpu_physical_memory_map(base, &src_len, 0);
/* If we can't map the framebuffer then bail. We could try harder,
but it's not really worth it as dirty flag tracking will probably
already have failed above. */
if (!src_base)
goto out;
if (src_len != src_width * rows) {
cpu_physical_memory_unmap(src_base, src_len, 0, 0);
goto out;
}
src = src_base;
addr = mem_section->offset_within_region;
src = memory_region_get_ram_ptr(mem) + addr;
dest = surface_data(ds);
if (dest_col_pitch < 0)
if (dest_col_pitch < 0) {
dest -= dest_col_pitch * (cols - 1);
}
if (dest_row_pitch < 0) {
dest -= dest_row_pitch * (rows - 1);
}
first = -1;
addr = mem_section.offset_within_region;
addr += i * src_width;
src += i * src_width;
@@ -104,14 +114,11 @@ void framebuffer_update_display(
src += src_width;
dest += dest_row_pitch;
}
cpu_physical_memory_unmap(src_base, src_len, 0, 0);
if (first < 0) {
goto out;
return;
}
memory_region_reset_dirty(mem, mem_section.offset_within_region, src_len,
memory_region_reset_dirty(mem, mem_section->offset_within_region, src_len,
DIRTY_MEMORY_VGA);
*first_row = first;
*last_row = last;
out:
memory_region_unref(mem);
}

View File

@@ -7,10 +7,50 @@
typedef void (*drawfn)(void *, uint8_t *, const uint8_t *, int, int);
/* framebuffer_update_memory_section: Update framebuffer
* #MemoryRegionSection, for example if the framebuffer is switched to
* a different memory area.
*
* @mem_section: Output #MemoryRegionSection, to be passed to
* framebuffer_update_display().
* @root: #MemoryRegion within which the framebuffer lies
* @base: Base address of the framebuffer within @root.
* @rows: Height of the screen.
* @src_width: Number of bytes in framebuffer memory between two rows.
*/
void framebuffer_update_memory_section(
MemoryRegionSection *mem_section,
MemoryRegion *root,
hwaddr base,
unsigned rows,
unsigned src_width);
/* framebuffer_update_display: Draw the framebuffer on a surface.
*
* @ds: #DisplaySurface to draw to.
* @mem_section: #MemoryRegionSection provided by
* framebuffer_update_memory_section().
* @cols: Width the screen.
* @rows: Height of the screen.
* @src_width: Number of bytes in framebuffer memory between two rows.
* @dest_row_pitch: Number of bytes in the surface data between two rows.
* Negative if the framebuffer is stored in the opposite order (e.g.
* bottom-to-top) compared to the framebuffer.
* @dest_col_pitch: Number of bytes in the surface data between two pixels.
* Negative if the framebuffer is stored in the opposite order (e.g.
* right-to-left) compared to the framebuffer.
* @invalidate: True if the function should redraw the whole screen
* without checking the DIRTY_MEMORY_VGA dirty bitmap.
* @fn: Drawing function to be called for each row that has to be drawn.
* @opaque: Opaque pointer passed to @fn.
* @first_row: Pointer to an integer, receives the number of the first row
* that was drawn (either the first dirty row, or 0 if @invalidate is true).
* @last_row: Pointer to an integer, receives the number of the last row that
* was drawn (either the last dirty row, or @rows-1 if @invalidate is true).
*/
void framebuffer_update_display(
DisplaySurface *ds,
MemoryRegion *address_space,
hwaddr base,
MemoryRegionSection *mem_section,
int cols,
int rows,
int src_width,

View File

@@ -71,6 +71,7 @@ struct MilkymistVgafbState {
SysBusDevice parent_obj;
MemoryRegion regs_region;
MemoryRegionSection fbsection;
QemuConsole *con;
int invalidate;
@@ -91,6 +92,7 @@ static void vgafb_update_display(void *opaque)
MilkymistVgafbState *s = opaque;
SysBusDevice *sbd;
DisplaySurface *surface = qemu_console_surface(s->con);
int src_width;
int first = 0;
int last = 0;
drawfn fn;
@@ -129,11 +131,18 @@ static void vgafb_update_display(void *opaque)
break;
}
framebuffer_update_display(surface, sysbus_address_space(sbd),
s->regs[R_BASEADDRESS] + s->fb_offset,
src_width = s->regs[R_HRES] * 2;
if (s->invalidate) {
framebuffer_update_memory_section(&s->fbsection,
sysbus_address_space(sbd),
s->regs[R_BASEADDRESS] + s->fb_offset,
s->regs[R_VRES], src_width);
}
framebuffer_update_display(surface, &s->fbsection,
s->regs[R_HRES],
s->regs[R_VRES],
s->regs[R_HRES] * 2,
src_width,
dest_width,
0,
s->invalidate,

View File

@@ -25,6 +25,7 @@
struct omap_lcd_panel_s {
MemoryRegion *sysmem;
MemoryRegion iomem;
MemoryRegionSection fbsection;
qemu_irq irq;
QemuConsole *con;
@@ -215,12 +216,19 @@ static void omap_update_display(void *opaque)
step = width * bpp >> 3;
linesize = surface_stride(surface);
framebuffer_update_display(surface, omap_lcd->sysmem,
frame_base, width, height,
if (omap_lcd->invalidate) {
framebuffer_update_memory_section(&omap_lcd->fbsection,
omap_lcd->sysmem, frame_base,
height, step);
}
framebuffer_update_display(surface, &omap_lcd->fbsection,
width, height,
step, linesize, 0,
omap_lcd->invalidate,
draw_line, omap_lcd->palette,
&first, &last);
if (first >= 0) {
dpy_gfx_update(omap_lcd->con, 0, first, width, last - first + 1);
}

View File

@@ -46,6 +46,7 @@ typedef struct PL110State {
SysBusDevice parent_obj;
MemoryRegion iomem;
MemoryRegionSection fbsection;
QemuConsole *con;
int version;
@@ -238,12 +239,20 @@ static void pl110_update_display(void *opaque)
}
dest_width *= s->cols;
first = 0;
framebuffer_update_display(surface, sysbus_address_space(sbd),
s->upbase, s->cols, s->rows,
if (s->invalidate) {
framebuffer_update_memory_section(&s->fbsection,
sysbus_address_space(sbd),
s->upbase,
s->rows, src_width);
}
framebuffer_update_display(surface, &s->fbsection,
s->cols, s->rows,
src_width, dest_width, 0,
s->invalidate,
fn, s->palette,
&first, &last);
if (first >= 0) {
dpy_gfx_update(s->con, 0, first, s->cols, last - first + 1);
}

View File

@@ -35,6 +35,7 @@ struct DMAChannel {
struct PXA2xxLCDState {
MemoryRegion *sysmem;
MemoryRegion iomem;
MemoryRegionSection fbsection;
qemu_irq irq;
int irqlevel;
@@ -687,8 +688,11 @@ static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s,
dest_width = s->xres * s->dest_width;
*miny = 0;
framebuffer_update_display(surface, s->sysmem,
addr, s->xres, s->yres,
if (s->invalidated) {
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
addr, s->yres, src_width);
}
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
src_width, dest_width, s->dest_width,
s->invalidated,
fn, s->dma_ch[0].palette, miny, maxy);
@@ -715,8 +719,11 @@ static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s,
dest_width = s->yres * s->dest_width;
*miny = 0;
framebuffer_update_display(surface, s->sysmem,
addr, s->xres, s->yres,
if (s->invalidated) {
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
addr, s->yres, src_width);
}
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
src_width, s->dest_width, -dest_width,
s->invalidated,
fn, s->dma_ch[0].palette,
@@ -747,8 +754,11 @@ static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s,
dest_width = s->xres * s->dest_width;
*miny = 0;
framebuffer_update_display(surface, s->sysmem,
addr, s->xres, s->yres,
if (s->invalidated) {
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
addr, s->yres, src_width);
}
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
src_width, -dest_width, -s->dest_width,
s->invalidated,
fn, s->dma_ch[0].palette, miny, maxy);
@@ -778,8 +788,11 @@ static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s,
dest_width = s->yres * s->dest_width;
*miny = 0;
framebuffer_update_display(surface, s->sysmem,
addr, s->xres, s->yres,
if (s->invalidated) {
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
addr, s->yres, src_width);
}
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
src_width, -s->dest_width, dest_width,
s->invalidated,
fn, s->dma_ch[0].palette,

View File

@@ -271,6 +271,11 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,
0));
} else {
#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
if (qxl->max_outputs) {
spice_qxl_set_max_monitors(&qxl->ssd.qxl, qxl->max_outputs);
}
#endif
qxl->guest_monitors_config = qxl->ram->monitors_config;
spice_qxl_monitors_config_async(&qxl->ssd.qxl,
qxl->ram->monitors_config,
@@ -991,6 +996,7 @@ static int interface_client_monitors_config(QXLInstance *sin,
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
QXLRom *rom = memory_region_get_ram_ptr(&qxl->rom_bar);
int i;
unsigned max_outputs = ARRAY_SIZE(rom->client_monitors_config.heads);
if (qxl->revision < 4) {
trace_qxl_client_monitors_config_unsupported_by_device(qxl->id,
@@ -1013,17 +1019,23 @@ static int interface_client_monitors_config(QXLInstance *sin,
if (!monitors_config) {
return 1;
}
#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
/* limit number of outputs based on setting limit */
if (qxl->max_outputs && qxl->max_outputs <= max_outputs) {
max_outputs = qxl->max_outputs;
}
#endif
memset(&rom->client_monitors_config, 0,
sizeof(rom->client_monitors_config));
rom->client_monitors_config.count = monitors_config->num_of_monitors;
/* monitors_config->flags ignored */
if (rom->client_monitors_config.count >=
ARRAY_SIZE(rom->client_monitors_config.heads)) {
if (rom->client_monitors_config.count >= max_outputs) {
trace_qxl_client_monitors_config_capped(qxl->id,
monitors_config->num_of_monitors,
ARRAY_SIZE(rom->client_monitors_config.heads));
rom->client_monitors_config.count =
ARRAY_SIZE(rom->client_monitors_config.heads);
max_outputs);
rom->client_monitors_config.count = max_outputs;
}
for (i = 0 ; i < rom->client_monitors_config.count ; ++i) {
VDAgentMonConfig *monitor = &monitors_config->monitors[i];
@@ -2274,6 +2286,9 @@ static Property qxl_properties[] = {
DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, -1),
DEFINE_PROP_UINT32("vgamem_mb", PCIQXLDevice, vgamem_size_mb, 16),
DEFINE_PROP_INT32("surfaces", PCIQXLDevice, ssd.num_surfaces, 1024),
#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
DEFINE_PROP_UINT16("max_outputs", PCIQXLDevice, max_outputs, 0),
#endif
DEFINE_PROP_END_OF_LIST(),
};

View File

@@ -99,6 +99,9 @@ typedef struct PCIQXLDevice {
QXLModes *modes;
uint32_t rom_size;
MemoryRegion rom_bar;
#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */
uint16_t max_outputs;
#endif
/* vram pci bar */
uint32_t vram_size;

View File

@@ -89,7 +89,8 @@ static void virtio_gpu_set_config(VirtIODevice *vdev, const uint8_t *config)
}
}
static uint64_t virtio_gpu_get_features(VirtIODevice *vdev, uint64_t features)
static uint64_t virtio_gpu_get_features(VirtIODevice *vdev, uint64_t features,
Error **errp)
{
return features;
}

View File

@@ -1108,8 +1108,8 @@ build_ssdt(GArray *table_data, GArray *linker,
aml_append(field, aml_named_field("PEPT", 8));
aml_append(dev, field);
/* device present, functioning, decoding, not shown in UI */
aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
/* device present, functioning, decoding, shown in UI */
aml_append(dev, aml_name_decl("_STA", aml_int(0xF)));
method = aml_method("RDPT", 0);
aml_append(method, aml_store(aml_name("PEPT"), aml_local(0)));

View File

@@ -279,8 +279,13 @@ static void ahci_port_write(AHCIState *s, int port, int offset, uint32_t val)
break;
case PORT_CMD:
/* Block any Read-only fields from being set;
* including LIST_ON and FIS_ON. */
pr->cmd = (pr->cmd & PORT_CMD_RO_MASK) | (val & ~PORT_CMD_RO_MASK);
* including LIST_ON and FIS_ON.
* The spec requires to set ICC bits to zero after the ICC change
* is done. We don't support ICC state changes, therefore always
* force the ICC bits to zero.
*/
pr->cmd = (pr->cmd & PORT_CMD_RO_MASK) |
(val & ~(PORT_CMD_RO_MASK|PORT_CMD_ICC_MASK));
/* Check FIS RX and CLB engines, allow transition to false: */
ahci_cond_start_engines(&s->dev[port], true);

View File

@@ -127,7 +127,7 @@
#define PORT_CMD_SPIN_UP (1 << 1) /* Spin up device */
#define PORT_CMD_START (1 << 0) /* Enable port DMA engine */
#define PORT_CMD_ICC_MASK (0xf << 28) /* i/f ICC state mask */
#define PORT_CMD_ICC_MASK (0xfU << 28) /* i/f ICC state mask */
#define PORT_CMD_ICC_ACTIVE (0x1 << 28) /* Put i/f in active state */
#define PORT_CMD_ICC_PARTIAL (0x2 << 28) /* Put i/f in partial state */
#define PORT_CMD_ICC_SLUMBER (0x6 << 28) /* Put i/f in slumber state */

View File

@@ -983,6 +983,7 @@ static void cmd_start_stop_unit(IDEState *s, uint8_t* buf)
if (pwrcnd) {
/* eject/load only happens for power condition == 0 */
ide_atapi_cmd_ok(s);
return;
}

View File

@@ -2021,11 +2021,17 @@ void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
}
p = s->data_ptr;
if (p + 2 > s->data_end) {
return;
}
*(uint16_t *)p = le16_to_cpu(val);
p += 2;
s->data_ptr = p;
if (p >= s->data_end)
if (p >= s->data_end) {
s->status &= ~DRQ_STAT;
s->end_transfer_func(s);
}
}
uint32_t ide_data_readw(void *opaque, uint32_t addr)
@@ -2042,11 +2048,17 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr)
}
p = s->data_ptr;
if (p + 2 > s->data_end) {
return 0;
}
ret = cpu_to_le16(*(uint16_t *)p);
p += 2;
s->data_ptr = p;
if (p >= s->data_end)
if (p >= s->data_end) {
s->status &= ~DRQ_STAT;
s->end_transfer_func(s);
}
return ret;
}
@@ -2063,11 +2075,17 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
}
p = s->data_ptr;
if (p + 4 > s->data_end) {
return;
}
*(uint32_t *)p = le32_to_cpu(val);
p += 4;
s->data_ptr = p;
if (p >= s->data_end)
if (p >= s->data_end) {
s->status &= ~DRQ_STAT;
s->end_transfer_func(s);
}
}
uint32_t ide_data_readl(void *opaque, uint32_t addr)
@@ -2084,11 +2102,17 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr)
}
p = s->data_ptr;
if (p + 4 > s->data_end) {
return 0;
}
ret = cpu_to_le32(*(uint32_t *)p);
p += 4;
s->data_ptr = p;
if (p >= s->data_end)
if (p >= s->data_end) {
s->status &= ~DRQ_STAT;
s->end_transfer_func(s);
}
return ret;
}

View File

@@ -208,6 +208,33 @@ static void pmac_dma_write(BlockBackend *blk,
cb, io);
}
static void pmac_dma_trim(BlockBackend *blk,
int64_t offset, int bytes,
void (*cb)(void *opaque, int ret), void *opaque)
{
DBDMA_io *io = opaque;
MACIOIDEState *m = io->opaque;
IDEState *s = idebus_active_if(&m->bus);
dma_addr_t dma_addr, dma_len;
void *mem;
qemu_iovec_destroy(&io->iov);
qemu_iovec_init(&io->iov, io->len / MACIO_PAGE_SIZE + 1);
dma_addr = io->addr;
dma_len = io->len;
mem = dma_memory_map(&address_space_memory, dma_addr, &dma_len,
DMA_DIRECTION_TO_DEVICE);
qemu_iovec_add(&io->iov, mem, io->len);
s->io_buffer_size -= io->len;
s->io_buffer_index += io->len;
io->len = 0;
m->aiocb = ide_issue_trim(blk, (offset >> 9), &io->iov, (bytes >> 9),
cb, io);
}
static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
{
DBDMA_io *io = opaque;
@@ -313,6 +340,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
pmac_dma_write(s->blk, offset, io->len, pmac_ide_transfer_cb, io);
break;
case IDE_DMA_TRIM:
pmac_dma_trim(s->blk, offset, io->len, pmac_ide_transfer_cb, io);
break;
}

View File

@@ -169,6 +169,7 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
PCIIDEState *pci_ide;
DriveInfo *di;
int i;
IDEDevice *idedev;
pci_ide = PCI_IDE(dev);
@@ -181,6 +182,12 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
blk_detach_dev(blk, ds);
}
pci_ide->bus[di->bus].ifs[di->unit].blk = NULL;
if (!(i % 2)) {
idedev = pci_ide->bus[di->bus].master;
} else {
idedev = pci_ide->bus[di->bus].slave;
}
idedev->conf.blk = NULL;
blk_unref(blk);
}
}

View File

@@ -166,7 +166,8 @@ static void virtio_input_set_config(VirtIODevice *vdev,
virtio_notify_config(vdev);
}
static uint64_t virtio_input_get_features(VirtIODevice *vdev, uint64_t f)
static uint64_t virtio_input_get_features(VirtIODevice *vdev, uint64_t f,
Error **errp)
{
return f;
}

View File

@@ -327,9 +327,14 @@ static void dp8393x_do_stop_timer(dp8393xState *s)
dp8393x_update_wt_regs(s);
}
static int dp8393x_can_receive(NetClientState *nc);
static void dp8393x_do_receiver_enable(dp8393xState *s)
{
s->regs[SONIC_CR] &= ~SONIC_CR_RXDIS;
if (dp8393x_can_receive(s->nic->ncs)) {
qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
}
static void dp8393x_do_receiver_disable(dp8393xState *s)
@@ -569,6 +574,9 @@ static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data,
dp8393x_do_read_rra(s);
}
dp8393x_update_irq(s);
if (dp8393x_can_receive(s->nic->ncs)) {
qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
break;
/* Ignore least significant bit */
case SONIC_RSA:
@@ -635,11 +643,6 @@ static int dp8393x_receive_filter(dp8393xState *s, const uint8_t * buf,
static const uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
int i;
/* Check for runt packet (remember that checksum is not there) */
if (size < 64 - 4) {
return (s->regs[SONIC_RCR] & SONIC_RCR_RNT) ? 0 : -1;
}
/* Check promiscuous mode */
if ((s->regs[SONIC_RCR] & SONIC_RCR_PRO) && (buf[0] & 1) == 0) {
return 0;
@@ -828,6 +831,7 @@ static void dp8393x_realize(DeviceState *dev, Error **errp)
dp8393xState *s = DP8393X(dev);
int i, checksum;
uint8_t *prom;
Error *local_err = NULL;
address_space_init(&s->as, s->dma_mr, "dp8393x");
memory_region_init_io(&s->mmio, OBJECT(dev), &dp8393x_ops, s,
@@ -840,8 +844,13 @@ static void dp8393x_realize(DeviceState *dev, Error **errp)
s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
memory_region_init_rom_device(&s->prom, OBJECT(dev), NULL, NULL,
"dp8393x-prom", SONIC_PROM_SIZE, NULL);
memory_region_init_ram(&s->prom, OBJECT(dev),
"dp8393x-prom", SONIC_PROM_SIZE, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
memory_region_set_readonly(&s->prom, true);
prom = memory_region_get_ram_ptr(&s->prom);
checksum = 0;
for (i = 0; i < 6; i++) {
@@ -881,6 +890,8 @@ static void dp8393x_class_init(ObjectClass *klass, void *data)
dc->reset = dp8393x_reset;
dc->vmsd = &vmstate_dp8393x;
dc->props = dp8393x_properties;
/* Reason: dma_mr property can't be set */
dc->cannot_instantiate_with_device_add_yet = true;
}
static const TypeInfo dp8393x_info = {

View File

@@ -1617,16 +1617,6 @@ static const MemoryRegionOps eepro100_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
static int nic_can_receive(NetClientState *nc)
{
EEPRO100State *s = qemu_get_nic_opaque(nc);
TRACE(RXTX, logout("%p\n", s));
return get_ru_state(s) == ru_ready;
#if 0
return !eepro100_buffer_full(s);
#endif
}
static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size)
{
/* TODO:
@@ -1844,7 +1834,6 @@ static void pci_nic_uninit(PCIDevice *pci_dev)
static NetClientInfo net_eepro100_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = nic_can_receive,
.receive = nic_receive,
};

View File

@@ -520,11 +520,6 @@ static int eth_match_groupaddr(ETRAXFSEthState *eth, const unsigned char *sa)
return match;
}
static int eth_can_receive(NetClientState *nc)
{
return 1;
}
static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size)
{
unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@@ -584,7 +579,6 @@ static const MemoryRegionOps eth_ops = {
static NetClientInfo net_etraxfs_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = eth_can_receive,
.receive = eth_receive,
.link_status_changed = eth_set_link,
};

View File

@@ -338,25 +338,26 @@ static void etsec_reset(DeviceState *d)
MII_SR_100X_FD_CAPS | MII_SR_100T4_CAPS;
}
static int etsec_can_receive(NetClientState *nc)
{
eTSEC *etsec = qemu_get_nic_opaque(nc);
return etsec->rx_buffer_len == 0;
}
static ssize_t etsec_receive(NetClientState *nc,
const uint8_t *buf,
size_t size)
{
ssize_t ret;
eTSEC *etsec = qemu_get_nic_opaque(nc);
#if defined(HEX_DUMP)
fprintf(stderr, "%s receive size:%d\n", etsec->nic->nc.name, size);
qemu_hexdump(buf, stderr, "", size);
#endif
etsec_rx_ring_write(etsec, buf, size);
return size;
/* Flush is unnecessary as are already in receiving path */
etsec->need_flush = false;
ret = etsec_rx_ring_write(etsec, buf, size);
if (ret == 0) {
/* The packet will be queued, let's flush it when buffer is avilable
* again. */
etsec->need_flush = true;
}
return ret;
}
@@ -370,7 +371,6 @@ static void etsec_set_link_status(NetClientState *nc)
static NetClientInfo net_etsec_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = etsec_can_receive,
.receive = etsec_receive,
.link_status_changed = etsec_set_link_status,
};

View File

@@ -144,6 +144,8 @@ typedef struct eTSEC {
QEMUBH *bh;
struct ptimer_state *ptimer;
/* Whether we should flush the rx queue when buffer becomes available. */
bool need_flush;
} eTSEC;
#define TYPE_ETSEC_COMMON "eTSEC"
@@ -162,7 +164,7 @@ DeviceState *etsec_create(hwaddr base,
void etsec_walk_tx_ring(eTSEC *etsec, int ring_nbr);
void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr);
void etsec_rx_ring_write(eTSEC *etsec, const uint8_t *buf, size_t size);
ssize_t etsec_rx_ring_write(eTSEC *etsec, const uint8_t *buf, size_t size);
void etsec_write_miim(eTSEC *etsec,
eTSEC_Register *reg,

View File

@@ -481,40 +481,42 @@ static void rx_init_frame(eTSEC *etsec, const uint8_t *buf, size_t size)
etsec->rx_buffer_len, etsec->rx_padding);
}
void etsec_rx_ring_write(eTSEC *etsec, const uint8_t *buf, size_t size)
ssize_t etsec_rx_ring_write(eTSEC *etsec, const uint8_t *buf, size_t size)
{
int ring_nbr = 0; /* Always use ring0 (no filer) */
if (etsec->rx_buffer_len != 0) {
RING_DEBUG("%s: We can't receive now,"
" a buffer is already in the pipe\n", __func__);
return;
return 0;
}
if (etsec->regs[RSTAT].value & 1 << (23 - ring_nbr)) {
RING_DEBUG("%s: The ring is halted\n", __func__);
return;
return -1;
}
if (etsec->regs[DMACTRL].value & DMACTRL_GRS) {
RING_DEBUG("%s: Graceful receive stop\n", __func__);
return;
return -1;
}
if (!(etsec->regs[MACCFG1].value & MACCFG1_RX_EN)) {
RING_DEBUG("%s: MAC Receive not enabled\n", __func__);
return;
return -1;
}
if ((etsec->regs[RCTRL].value & RCTRL_RSF) && (size < 60)) {
/* CRC is not in the packet yet, so short frame is below 60 bytes */
RING_DEBUG("%s: Drop short frame\n", __func__);
return;
return -1;
}
rx_init_frame(etsec, buf, size);
etsec_walk_rx_ring(etsec, ring_nbr);
return size;
}
void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr)
@@ -644,6 +646,9 @@ void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr)
} else {
etsec->rx_buffer_len = 0;
etsec->rx_buffer = NULL;
if (etsec->need_flush) {
qemu_flush_queued_packets(qemu_get_queue(etsec->nic));
}
}
RING_DEBUG("eTSEC End of ring_write: remaining_data:%zu\n", remaining_data);

View File

@@ -461,11 +461,6 @@ static void lan9118_reset(DeviceState *d)
lan9118_reload_eeprom(s);
}
static int lan9118_can_receive(NetClientState *nc)
{
return 1;
}
static void rx_fifo_push(lan9118_state *s, uint32_t val)
{
int fifo_pos;
@@ -1312,7 +1307,6 @@ static const MemoryRegionOps lan9118_16bit_mem_ops = {
static NetClientInfo net_lan9118_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = lan9118_can_receive,
.receive = lan9118_receive,
.link_status_changed = lan9118_set_link,
};

View File

@@ -94,7 +94,6 @@ static const MemoryRegionOps lance_mem_ops = {
static NetClientInfo net_lance_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = pcnet_can_receive,
.receive = pcnet_receive,
.link_status_changed = pcnet_set_link_status,
};

View File

@@ -8,6 +8,7 @@
#include "hw/hw.h"
#include "net/net.h"
#include "hw/m68k/mcf.h"
#include "hw/net/mii.h"
/* For crc32 */
#include <zlib.h>
#include "exec/address-spaces.h"
@@ -195,12 +196,14 @@ static void mcf_fec_do_tx(mcf_fec_state *s)
static void mcf_fec_enable_rx(mcf_fec_state *s)
{
NetClientState *nc = qemu_get_queue(s->nic);
mcf_fec_bd bd;
mcf_fec_read_bd(&bd, s->rx_descriptor);
s->rx_enabled = ((bd.flags & FEC_BD_E) != 0);
if (!s->rx_enabled)
DPRINTF("RX buffer full\n");
if (s->rx_enabled) {
qemu_flush_queued_packets(nc);
}
}
static void mcf_fec_reset(mcf_fec_state *s)
@@ -216,6 +219,51 @@ static void mcf_fec_reset(mcf_fec_state *s)
s->rfsr = 0x500;
}
#define MMFR_WRITE_OP (1 << 28)
#define MMFR_READ_OP (2 << 28)
#define MMFR_PHYADDR(v) (((v) >> 23) & 0x1f)
#define MMFR_REGNUM(v) (((v) >> 18) & 0x1f)
static uint64_t mcf_fec_read_mdio(mcf_fec_state *s)
{
uint64_t v;
if (s->mmfr & MMFR_WRITE_OP)
return s->mmfr;
if (MMFR_PHYADDR(s->mmfr) != 1)
return s->mmfr |= 0xffff;
switch (MMFR_REGNUM(s->mmfr)) {
case MII_BMCR:
v = MII_BMCR_SPEED | MII_BMCR_AUTOEN | MII_BMCR_FD;
break;
case MII_BMSR:
v = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD | MII_BMSR_10T_FD |
MII_BMSR_10T_HD | MII_BMSR_MFPS | MII_BMSR_AN_COMP |
MII_BMSR_AUTONEG | MII_BMSR_LINK_ST;
break;
case MII_PHYID1:
v = DP83848_PHYID1;
break;
case MII_PHYID2:
v = DP83848_PHYID2;
break;
case MII_ANAR:
v = MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD |
MII_ANAR_10 | MII_ANAR_CSMACD;
break;
case MII_ANLPAR:
v = MII_ANLPAR_ACK | MII_ANLPAR_TXFD | MII_ANLPAR_TX |
MII_ANLPAR_10FD | MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
break;
default:
v = 0xffff;
break;
}
s->mmfr = (s->mmfr & ~0xffff) | v;
return s->mmfr;
}
static uint64_t mcf_fec_read(void *opaque, hwaddr addr,
unsigned size)
{
@@ -226,7 +274,7 @@ static uint64_t mcf_fec_read(void *opaque, hwaddr addr,
case 0x010: return s->rx_enabled ? (1 << 24) : 0; /* RDAR */
case 0x014: return 0; /* TDAR */
case 0x024: return s->ecr;
case 0x040: return s->mmfr;
case 0x040: return mcf_fec_read_mdio(s);
case 0x044: return s->mscr;
case 0x064: return 0; /* MIBC */
case 0x084: return s->rcr;
@@ -287,8 +335,8 @@ static void mcf_fec_write(void *opaque, hwaddr addr,
}
break;
case 0x040:
/* TODO: Implement MII. */
s->mmfr = value;
s->eir |= FEC_INT_MII;
break;
case 0x044:
s->mscr = value & 0xfe;
@@ -351,10 +399,30 @@ static void mcf_fec_write(void *opaque, hwaddr addr,
mcf_fec_update(s);
}
static int mcf_fec_can_receive(NetClientState *nc)
static int mcf_fec_have_receive_space(mcf_fec_state *s, size_t want)
{
mcf_fec_state *s = qemu_get_nic_opaque(nc);
return s->rx_enabled;
mcf_fec_bd bd;
uint32_t addr;
/* Walk descriptor list to determine if we have enough buffer */
addr = s->rx_descriptor;
while (want > 0) {
mcf_fec_read_bd(&bd, addr);
if ((bd.flags & FEC_BD_E) == 0) {
return 0;
}
if (want < s->emrbr) {
return 1;
}
want -= s->emrbr;
/* Advance to the next descriptor. */
if ((bd.flags & FEC_BD_W) != 0) {
addr = s->erdsr;
} else {
addr += 8;
}
}
return 0;
}
static ssize_t mcf_fec_receive(NetClientState *nc, const uint8_t *buf, size_t size)
@@ -367,10 +435,11 @@ static ssize_t mcf_fec_receive(NetClientState *nc, const uint8_t *buf, size_t si
uint32_t buf_addr;
uint8_t *crc_ptr;
unsigned int buf_len;
size_t retsize;
DPRINTF("do_rx len %d\n", size);
if (!s->rx_enabled) {
fprintf(stderr, "mcf_fec_receive: Unexpected packet\n");
return -1;
}
/* 4 bytes for the CRC. */
size += 4;
@@ -385,17 +454,14 @@ static ssize_t mcf_fec_receive(NetClientState *nc, const uint8_t *buf, size_t si
if (size > (s->rcr >> 16)) {
flags |= FEC_BD_LG;
}
/* Check if we have enough space in current descriptors */
if (!mcf_fec_have_receive_space(s, size)) {
return 0;
}
addr = s->rx_descriptor;
retsize = size;
while (size > 0) {
mcf_fec_read_bd(&bd, addr);
if ((bd.flags & FEC_BD_E) == 0) {
/* No descriptors available. Bail out. */
/* FIXME: This is wrong. We should probably either save the
remainder for when more RX buffers are available, or
flag an error. */
fprintf(stderr, "mcf_fec: Lost end of frame\n");
break;
}
buf_len = (size <= s->emrbr) ? size: s->emrbr;
bd.length = buf_len;
size -= buf_len;
@@ -430,7 +496,7 @@ static ssize_t mcf_fec_receive(NetClientState *nc, const uint8_t *buf, size_t si
s->rx_descriptor = addr;
mcf_fec_enable_rx(s);
mcf_fec_update(s);
return size;
return retsize;
}
static const MemoryRegionOps mcf_fec_ops = {
@@ -442,7 +508,6 @@ static const MemoryRegionOps mcf_fec_ops = {
static NetClientInfo net_mcf_fec_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = mcf_fec_can_receive,
.receive = mcf_fec_receive,
};

View File

@@ -303,8 +303,7 @@ static ssize_t minimac2_rx(NetClientState *nc, const uint8_t *buf, size_t size)
r_state = R_STATE1;
rx_buf = s->rx1_buf;
} else {
trace_milkymist_minimac2_drop_rx_frame(buf);
return size;
return 0;
}
/* assemble frame */
@@ -354,6 +353,18 @@ minimac2_read(void *opaque, hwaddr addr, unsigned size)
return r;
}
static int minimac2_can_rx(MilkymistMinimac2State *s)
{
if (s->regs[R_STATE0] == STATE_LOADED) {
return 1;
}
if (s->regs[R_STATE1] == STATE_LOADED) {
return 1;
}
return 0;
}
static void
minimac2_write(void *opaque, hwaddr addr, uint64_t value,
unsigned size)
@@ -387,6 +398,9 @@ minimac2_write(void *opaque, hwaddr addr, uint64_t value,
case R_STATE1:
s->regs[addr] = value;
update_rx_interrupt(s);
if (minimac2_can_rx(s)) {
qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
break;
case R_SETUP:
case R_COUNT0:
@@ -411,20 +425,6 @@ static const MemoryRegionOps minimac2_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
static int minimac2_can_rx(NetClientState *nc)
{
MilkymistMinimac2State *s = qemu_get_nic_opaque(nc);
if (s->regs[R_STATE0] == STATE_LOADED) {
return 1;
}
if (s->regs[R_STATE1] == STATE_LOADED) {
return 1;
}
return 0;
}
static void milkymist_minimac2_reset(DeviceState *d)
{
MilkymistMinimac2State *s = MILKYMIST_MINIMAC2(d);
@@ -445,7 +445,6 @@ static void milkymist_minimac2_reset(DeviceState *d)
static NetClientInfo net_milkymist_minimac2_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = minimac2_can_rx,
.receive = minimac2_rx,
};

View File

@@ -80,7 +80,7 @@ static ssize_t mipsnet_receive(NetClientState *nc, const uint8_t *buf, size_t si
trace_mipsnet_receive(size);
if (!mipsnet_can_receive(nc))
return -1;
return 0;
s->busy = 1;
@@ -134,6 +134,9 @@ static uint64_t mipsnet_ioport_read(void *opaque, hwaddr addr,
if (s->rx_count) {
s->rx_count--;
ret = s->rx_buffer[s->rx_read++];
if (mipsnet_can_receive(s->nic->ncs)) {
qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
}
break;
/* Reads as zero. */
@@ -170,6 +173,9 @@ static void mipsnet_ioport_write(void *opaque, hwaddr addr,
}
s->busy = !!s->intctl;
mipsnet_update_irq(s);
if (mipsnet_can_receive(s->nic->ncs)) {
qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
break;
case MIPSNET_TX_DATA_BUFFER:
s->tx_buffer[s->tx_written++] = val;
@@ -214,7 +220,6 @@ static const VMStateDescription vmstate_mipsnet = {
static NetClientInfo net_mipsnet_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = mipsnet_can_receive,
.receive = mipsnet_receive,
};

View File

@@ -273,7 +273,6 @@ static void pci_pcnet_uninit(PCIDevice *dev)
static NetClientInfo net_pci_pcnet_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = pcnet_can_receive,
.receive = pcnet_receive,
.link_status_changed = pcnet_set_link_status,
};

View File

@@ -995,15 +995,6 @@ static int pcnet_tdte_poll(PCNetState *s)
return !!(CSR_CXST(s) & 0x8000);
}
int pcnet_can_receive(NetClientState *nc)
{
PCNetState *s = qemu_get_nic_opaque(nc);
if (CSR_STOP(s) || CSR_SPND(s))
return 0;
return sizeof(s->buffer)-16;
}
#define MIN_BUF_SIZE 60
ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_)

View File

@@ -60,7 +60,6 @@ uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr);
void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val);
uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr);
uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
int pcnet_can_receive(NetClientState *nc);
ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_);
void pcnet_set_link_status(NetClientState *nc);
void pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info);

View File

@@ -2150,6 +2150,11 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
{
DPRINTF("+++ C+ mode offloaded task checksum\n");
/* Large enough for Ethernet and IP headers? */
if (saved_size < ETH_HLEN + sizeof(ip_header)) {
goto skip_offload;
}
/* ip packet header */
ip_header *ip = NULL;
int hlen = 0;
@@ -2160,223 +2165,235 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
size_t eth_payload_len = 0;
int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12));
if (proto == ETH_P_IP)
if (proto != ETH_P_IP)
{
DPRINTF("+++ C+ mode has IP packet\n");
/* not aligned */
eth_payload_data = saved_buffer + ETH_HLEN;
eth_payload_len = saved_size - ETH_HLEN;
ip = (ip_header*)eth_payload_data;
if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
DPRINTF("+++ C+ mode packet has bad IP version %d "
"expected %d\n", IP_HEADER_VERSION(ip),
IP_HEADER_VERSION_4);
ip = NULL;
} else {
hlen = IP_HEADER_LENGTH(ip);
ip_protocol = ip->ip_p;
ip_data_len = be16_to_cpu(ip->ip_len) - hlen;
}
goto skip_offload;
}
if (ip)
DPRINTF("+++ C+ mode has IP packet\n");
/* not aligned */
eth_payload_data = saved_buffer + ETH_HLEN;
eth_payload_len = saved_size - ETH_HLEN;
ip = (ip_header*)eth_payload_data;
if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
DPRINTF("+++ C+ mode packet has bad IP version %d "
"expected %d\n", IP_HEADER_VERSION(ip),
IP_HEADER_VERSION_4);
goto skip_offload;
}
hlen = IP_HEADER_LENGTH(ip);
if (hlen < sizeof(ip_header) || hlen > eth_payload_len) {
goto skip_offload;
}
ip_protocol = ip->ip_p;
ip_data_len = be16_to_cpu(ip->ip_len);
if (ip_data_len < hlen || ip_data_len > eth_payload_len) {
goto skip_offload;
}
ip_data_len -= hlen;
if (txdw0 & CP_TX_IPCS)
{
if (txdw0 & CP_TX_IPCS)
{
DPRINTF("+++ C+ mode need IP checksum\n");
DPRINTF("+++ C+ mode need IP checksum\n");
if (hlen<sizeof(ip_header) || hlen>eth_payload_len) {/* min header length */
/* bad packet header len */
/* or packet too short */
}
else
{
ip->ip_sum = 0;
ip->ip_sum = ip_checksum(ip, hlen);
DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n",
hlen, ip->ip_sum);
}
ip->ip_sum = 0;
ip->ip_sum = ip_checksum(ip, hlen);
DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n",
hlen, ip->ip_sum);
}
if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)
{
/* Large enough for the TCP header? */
if (ip_data_len < sizeof(tcp_header)) {
goto skip_offload;
}
if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)
int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;
DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d "
"frame data %d specified MSS=%d\n", ETH_MTU,
ip_data_len, saved_size - ETH_HLEN, large_send_mss);
int tcp_send_offset = 0;
int send_count = 0;
/* maximum IP header length is 60 bytes */
uint8_t saved_ip_header[60];
/* save IP header template; data area is used in tcp checksum calculation */
memcpy(saved_ip_header, eth_payload_data, hlen);
/* a placeholder for checksum calculation routine in tcp case */
uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
// size_t data_to_checksum_len = eth_payload_len - hlen + 12;
/* pointer to TCP header */
tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen);
int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr);
/* Invalid TCP data offset? */
if (tcp_hlen < sizeof(tcp_header) || tcp_hlen > ip_data_len) {
goto skip_offload;
}
/* ETH_MTU = ip header len + tcp header len + payload */
int tcp_data_len = ip_data_len - tcp_hlen;
int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP "
"data len %d TCP chunk size %d\n", ip_data_len,
tcp_hlen, tcp_data_len, tcp_chunk_size);
/* note the cycle below overwrites IP header data,
but restores it from saved_ip_header before sending packet */
int is_last_frame = 0;
for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size)
{
int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;
uint16_t chunk_size = tcp_chunk_size;
DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d "
"frame data %d specified MSS=%d\n", ETH_MTU,
ip_data_len, saved_size - ETH_HLEN, large_send_mss);
int tcp_send_offset = 0;
int send_count = 0;
/* maximum IP header length is 60 bytes */
uint8_t saved_ip_header[60];
/* save IP header template; data area is used in tcp checksum calculation */
memcpy(saved_ip_header, eth_payload_data, hlen);
/* a placeholder for checksum calculation routine in tcp case */
uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
// size_t data_to_checksum_len = eth_payload_len - hlen + 12;
/* pointer to TCP header */
tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen);
int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr);
/* ETH_MTU = ip header len + tcp header len + payload */
int tcp_data_len = ip_data_len - tcp_hlen;
int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP "
"data len %d TCP chunk size %d\n", ip_data_len,
tcp_hlen, tcp_data_len, tcp_chunk_size);
/* note the cycle below overwrites IP header data,
but restores it from saved_ip_header before sending packet */
int is_last_frame = 0;
for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size)
/* check if this is the last frame */
if (tcp_send_offset + tcp_chunk_size >= tcp_data_len)
{
uint16_t chunk_size = tcp_chunk_size;
/* check if this is the last frame */
if (tcp_send_offset + tcp_chunk_size >= tcp_data_len)
{
is_last_frame = 1;
chunk_size = tcp_data_len - tcp_send_offset;
}
DPRINTF("+++ C+ mode TSO TCP seqno %08x\n",
be32_to_cpu(p_tcp_hdr->th_seq));
/* add 4 TCP pseudoheader fields */
/* copy IP source and destination fields */
memcpy(data_to_checksum, saved_ip_header + 12, 8);
DPRINTF("+++ C+ mode TSO calculating TCP checksum for "
"packet with %d bytes data\n", tcp_hlen +
chunk_size);
if (tcp_send_offset)
{
memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size);
}
/* keep PUSH and FIN flags only for the last frame */
if (!is_last_frame)
{
TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN);
}
/* recalculate TCP checksum */
ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
p_tcpip_hdr->zeros = 0;
p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size);
p_tcp_hdr->th_sum = 0;
int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12);
DPRINTF("+++ C+ mode TSO TCP checksum %04x\n",
tcp_checksum);
p_tcp_hdr->th_sum = tcp_checksum;
/* restore IP header */
memcpy(eth_payload_data, saved_ip_header, hlen);
/* set IP data length and recalculate IP checksum */
ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size);
/* increment IP id for subsequent frames */
ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id));
ip->ip_sum = 0;
ip->ip_sum = ip_checksum(eth_payload_data, hlen);
DPRINTF("+++ C+ mode TSO IP header len=%d "
"checksum=%04x\n", hlen, ip->ip_sum);
int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size;
DPRINTF("+++ C+ mode TSO transferring packet size "
"%d\n", tso_send_size);
rtl8139_transfer_frame(s, saved_buffer, tso_send_size,
0, (uint8_t *) dot1q_buffer);
/* add transferred count to TCP sequence number */
p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq));
++send_count;
is_last_frame = 1;
chunk_size = tcp_data_len - tcp_send_offset;
}
/* Stop sending this frame */
saved_size = 0;
}
else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS))
{
DPRINTF("+++ C+ mode need TCP or UDP checksum\n");
/* maximum IP header length is 60 bytes */
uint8_t saved_ip_header[60];
memcpy(saved_ip_header, eth_payload_data, hlen);
uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
// size_t data_to_checksum_len = eth_payload_len - hlen + 12;
DPRINTF("+++ C+ mode TSO TCP seqno %08x\n",
be32_to_cpu(p_tcp_hdr->th_seq));
/* add 4 TCP pseudoheader fields */
/* copy IP source and destination fields */
memcpy(data_to_checksum, saved_ip_header + 12, 8);
if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP)
DPRINTF("+++ C+ mode TSO calculating TCP checksum for "
"packet with %d bytes data\n", tcp_hlen +
chunk_size);
if (tcp_send_offset)
{
DPRINTF("+++ C+ mode calculating TCP checksum for "
"packet with %d bytes data\n", ip_data_len);
ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
p_tcpip_hdr->zeros = 0;
p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12);
p_tcp_hdr->th_sum = 0;
int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
DPRINTF("+++ C+ mode TCP checksum %04x\n",
tcp_checksum);
p_tcp_hdr->th_sum = tcp_checksum;
memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size);
}
else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP)
/* keep PUSH and FIN flags only for the last frame */
if (!is_last_frame)
{
DPRINTF("+++ C+ mode calculating UDP checksum for "
"packet with %d bytes data\n", ip_data_len);
ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum;
p_udpip_hdr->zeros = 0;
p_udpip_hdr->ip_proto = IP_PROTO_UDP;
p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12);
p_udp_hdr->uh_sum = 0;
int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
DPRINTF("+++ C+ mode UDP checksum %04x\n",
udp_checksum);
p_udp_hdr->uh_sum = udp_checksum;
TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN);
}
/* recalculate TCP checksum */
ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
p_tcpip_hdr->zeros = 0;
p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size);
p_tcp_hdr->th_sum = 0;
int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12);
DPRINTF("+++ C+ mode TSO TCP checksum %04x\n",
tcp_checksum);
p_tcp_hdr->th_sum = tcp_checksum;
/* restore IP header */
memcpy(eth_payload_data, saved_ip_header, hlen);
/* set IP data length and recalculate IP checksum */
ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size);
/* increment IP id for subsequent frames */
ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id));
ip->ip_sum = 0;
ip->ip_sum = ip_checksum(eth_payload_data, hlen);
DPRINTF("+++ C+ mode TSO IP header len=%d "
"checksum=%04x\n", hlen, ip->ip_sum);
int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size;
DPRINTF("+++ C+ mode TSO transferring packet size "
"%d\n", tso_send_size);
rtl8139_transfer_frame(s, saved_buffer, tso_send_size,
0, (uint8_t *) dot1q_buffer);
/* add transferred count to TCP sequence number */
p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq));
++send_count;
}
/* Stop sending this frame */
saved_size = 0;
}
else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS))
{
DPRINTF("+++ C+ mode need TCP or UDP checksum\n");
/* maximum IP header length is 60 bytes */
uint8_t saved_ip_header[60];
memcpy(saved_ip_header, eth_payload_data, hlen);
uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
// size_t data_to_checksum_len = eth_payload_len - hlen + 12;
/* add 4 TCP pseudoheader fields */
/* copy IP source and destination fields */
memcpy(data_to_checksum, saved_ip_header + 12, 8);
if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP)
{
DPRINTF("+++ C+ mode calculating TCP checksum for "
"packet with %d bytes data\n", ip_data_len);
ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
p_tcpip_hdr->zeros = 0;
p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12);
p_tcp_hdr->th_sum = 0;
int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
DPRINTF("+++ C+ mode TCP checksum %04x\n",
tcp_checksum);
p_tcp_hdr->th_sum = tcp_checksum;
}
else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP)
{
DPRINTF("+++ C+ mode calculating UDP checksum for "
"packet with %d bytes data\n", ip_data_len);
ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum;
p_udpip_hdr->zeros = 0;
p_udpip_hdr->ip_proto = IP_PROTO_UDP;
p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12);
p_udp_hdr->uh_sum = 0;
int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
DPRINTF("+++ C+ mode UDP checksum %04x\n",
udp_checksum);
p_udp_hdr->uh_sum = udp_checksum;
}
/* restore IP header */
memcpy(eth_payload_data, saved_ip_header, hlen);
}
}
skip_offload:
/* update tally counter */
++s->tally_counters.TxOk;

View File

@@ -228,8 +228,7 @@ static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf, si
if ((s->rctl & SE_RCTL_RXEN) == 0)
return -1;
if (s->np >= 31) {
DPRINTF("Packet dropped\n");
return -1;
return 0;
}
DPRINTF("Received packet len=%zu\n", size);
@@ -260,13 +259,8 @@ static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf, si
return size;
}
static int stellaris_enet_can_receive(NetClientState *nc)
static int stellaris_enet_can_receive(stellaris_enet_state *s)
{
stellaris_enet_state *s = qemu_get_nic_opaque(nc);
if ((s->rctl & SE_RCTL_RXEN) == 0)
return 1;
return (s->np < 31);
}
@@ -307,6 +301,9 @@ static uint64_t stellaris_enet_read(void *opaque, hwaddr offset,
s->next_packet = 0;
s->np--;
DPRINTF("RX done np=%d\n", s->np);
if (!s->np && stellaris_enet_can_receive(s)) {
qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
}
return val;
}
@@ -454,7 +451,6 @@ static void stellaris_enet_reset(stellaris_enet_state *s)
static NetClientInfo net_stellaris_enet_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = stellaris_enet_can_receive,
.receive = stellaris_enet_receive,
};

View File

@@ -160,7 +160,6 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
net->dev.nvqs = 2;
net->dev.vqs = net->vqs;
net->dev.vq_index = net->nc->queue_index;
r = vhost_dev_init(&net->dev, options->opaque,
options->backend_type);
@@ -287,7 +286,7 @@ static void vhost_net_stop_one(struct vhost_net *net,
for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
const VhostOps *vhost_ops = net->dev.vhost_ops;
int r = vhost_ops->vhost_call(&net->dev, VHOST_RESET_OWNER,
&file);
NULL);
assert(r >= 0);
}
}

View File

@@ -162,6 +162,8 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
virtio_net_vhost_status(n, status);
for (i = 0; i < n->max_queues; i++) {
NetClientState *ncs = qemu_get_subqueue(n->nic, i);
bool queue_started;
q = &n->vqs[i];
if ((!n->multiqueue && i != 0) || i >= n->curr_queues) {
@@ -169,12 +171,18 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
} else {
queue_status = status;
}
queue_started =
virtio_net_started(n, queue_status) && !n->vhost_started;
if (queue_started) {
qemu_flush_queued_packets(ncs);
}
if (!q->tx_waiting) {
continue;
}
if (virtio_net_started(n, queue_status) && !n->vhost_started) {
if (queue_started) {
if (q->tx_timer) {
timer_mod(q->tx_timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout);
@@ -438,7 +446,8 @@ static void virtio_net_set_queues(VirtIONet *n)
static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue);
static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features)
static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
Error **errp)
{
VirtIONet *n = VIRTIO_NET(vdev);
NetClientState *nc = qemu_get_queue(n->nic);
@@ -1142,7 +1151,8 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
ssize_t ret, len;
unsigned int out_num = elem.out_num;
struct iovec *out_sg = &elem.out_sg[0];
struct iovec sg[VIRTQUEUE_MAX_SIZE];
struct iovec sg[VIRTQUEUE_MAX_SIZE], sg2[VIRTQUEUE_MAX_SIZE + 1];
struct virtio_net_hdr_mrg_rxbuf mhdr;
if (out_num < 1) {
error_report("virtio-net header not in first element");
@@ -1150,13 +1160,25 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
}
if (n->has_vnet_hdr) {
if (out_sg[0].iov_len < n->guest_hdr_len) {
if (iov_to_buf(out_sg, out_num, 0, &mhdr, n->guest_hdr_len) <
n->guest_hdr_len) {
error_report("virtio-net header incorrect");
exit(1);
}
virtio_net_hdr_swap(vdev, (void *) out_sg[0].iov_base);
if (virtio_needs_swap(vdev)) {
virtio_net_hdr_swap(vdev, (void *) &mhdr);
sg2[0].iov_base = &mhdr;
sg2[0].iov_len = n->guest_hdr_len;
out_num = iov_copy(&sg2[1], ARRAY_SIZE(sg2) - 1,
out_sg, out_num,
n->guest_hdr_len, -1);
if (out_num == VIRTQUEUE_MAX_SIZE) {
goto drop;
}
out_num += 1;
out_sg = sg2;
}
}
/*
* If host wants to see the guest header as is, we can
* pass it on unchanged. Otherwise, copy just the parts
@@ -1186,7 +1208,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
}
len += ret;
drop:
virtqueue_push(q->tx_vq, &elem, 0);
virtio_notify(vdev, q->tx_vq);
@@ -1306,9 +1328,86 @@ static void virtio_net_tx_bh(void *opaque)
}
}
static void virtio_net_add_queue(VirtIONet *n, int index)
{
VirtIODevice *vdev = VIRTIO_DEVICE(n);
n->vqs[index].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx);
if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) {
n->vqs[index].tx_vq =
virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer);
n->vqs[index].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
virtio_net_tx_timer,
&n->vqs[index]);
} else {
n->vqs[index].tx_vq =
virtio_add_queue(vdev, 256, virtio_net_handle_tx_bh);
n->vqs[index].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[index]);
}
n->vqs[index].tx_waiting = 0;
n->vqs[index].n = n;
}
static void virtio_net_del_queue(VirtIONet *n, int index)
{
VirtIODevice *vdev = VIRTIO_DEVICE(n);
VirtIONetQueue *q = &n->vqs[index];
NetClientState *nc = qemu_get_subqueue(n->nic, index);
qemu_purge_queued_packets(nc);
virtio_del_queue(vdev, index * 2);
if (q->tx_timer) {
timer_del(q->tx_timer);
timer_free(q->tx_timer);
} else {
qemu_bh_delete(q->tx_bh);
}
virtio_del_queue(vdev, index * 2 + 1);
}
static void virtio_net_change_num_queues(VirtIONet *n, int new_max_queues)
{
VirtIODevice *vdev = VIRTIO_DEVICE(n);
int old_num_queues = virtio_get_num_queues(vdev);
int new_num_queues = new_max_queues * 2 + 1;
int i;
assert(old_num_queues >= 3);
assert(old_num_queues % 2 == 1);
if (old_num_queues == new_num_queues) {
return;
}
/*
* We always need to remove and add ctrl vq if
* old_num_queues != new_num_queues. Remove ctrl_vq first,
* and then we only enter one of the following too loops.
*/
virtio_del_queue(vdev, old_num_queues - 1);
for (i = new_num_queues - 1; i < old_num_queues - 1; i += 2) {
/* new_num_queues < old_num_queues */
virtio_net_del_queue(n, i / 2);
}
for (i = old_num_queues - 1; i < new_num_queues - 1; i += 2) {
/* new_num_queues > old_num_queues */
virtio_net_add_queue(n, i / 2);
}
/* add ctrl_vq last */
n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl);
}
static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue)
{
int max = multiqueue ? n->max_queues : 1;
n->multiqueue = multiqueue;
virtio_net_change_num_queues(n, max);
virtio_net_set_queues(n);
}
@@ -1583,21 +1682,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
}
for (i = 0; i < n->max_queues; i++) {
n->vqs[i].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx);
if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) {
n->vqs[i].tx_vq =
virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer);
n->vqs[i].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
virtio_net_tx_timer,
&n->vqs[i]);
} else {
n->vqs[i].tx_vq =
virtio_add_queue(vdev, 256, virtio_net_handle_tx_bh);
n->vqs[i].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[i]);
}
n->vqs[i].tx_waiting = 0;
n->vqs[i].n = n;
virtio_net_add_queue(n, i);
}
n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl);
@@ -1651,7 +1736,7 @@ static void virtio_net_device_unrealize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIONet *n = VIRTIO_NET(dev);
int i;
int i, max_queues;
/* This will stop vhost backend if appropriate. */
virtio_net_set_status(vdev, 0);
@@ -1666,18 +1751,9 @@ static void virtio_net_device_unrealize(DeviceState *dev, Error **errp)
g_free(n->mac_table.macs);
g_free(n->vlans);
for (i = 0; i < n->max_queues; i++) {
VirtIONetQueue *q = &n->vqs[i];
NetClientState *nc = qemu_get_subqueue(n->nic, i);
qemu_purge_queued_packets(nc);
if (q->tx_timer) {
timer_del(q->tx_timer);
timer_free(q->tx_timer);
} else if (q->tx_bh) {
qemu_bh_delete(q->tx_bh);
}
max_queues = n->multiqueue ? n->max_queues : 1;
for (i = 0; i < max_queues; i++) {
virtio_net_del_queue(n, i);
}
timer_del(n->announce_timer);
@@ -1702,8 +1778,6 @@ static void virtio_net_instance_init(Object *obj)
}
static Property virtio_net_properties[] = {
DEFINE_PROP_BIT("any_layout", VirtIONet, host_features,
VIRTIO_F_ANY_LAYOUT, true),
DEFINE_PROP_BIT("csum", VirtIONet, host_features, VIRTIO_NET_F_CSUM, true),
DEFINE_PROP_BIT("guest_csum", VirtIONet, host_features,
VIRTIO_NET_F_GUEST_CSUM, true),

View File

@@ -885,6 +885,63 @@ vmxnet3_get_next_rx_descr(VMXNET3State *s, bool is_head,
}
}
/* In case packet was csum offloaded (either NEEDS_CSUM or DATA_VALID),
* the implementation always passes an RxCompDesc with a "Checksum
* calculated and found correct" to the OS (cnc=0 and tuc=1, see
* vmxnet3_rx_update_descr). This emulates the observed ESXi behavior.
*
* Therefore, if packet has the NEEDS_CSUM set, we must calculate
* and place a fully computed checksum into the tcp/udp header.
* Otherwise, the OS driver will receive a checksum-correct indication
* (CHECKSUM_UNNECESSARY), but with the actual tcp/udp checksum field
* having just the pseudo header csum value.
*
* While this is not a problem if packet is destined for local delivery,
* in the case the host OS performs forwarding, it will forward an
* incorrectly checksummed packet.
*/
static void vmxnet3_rx_need_csum_calculate(struct VmxnetRxPkt *pkt,
const void *pkt_data,
size_t pkt_len)
{
struct virtio_net_hdr *vhdr;
bool isip4, isip6, istcp, isudp;
uint8_t *data;
int len;
if (!vmxnet_rx_pkt_has_virt_hdr(pkt)) {
return;
}
vhdr = vmxnet_rx_pkt_get_vhdr(pkt);
if (!VMXNET_FLAG_IS_SET(vhdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM)) {
return;
}
vmxnet_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
if (!(isip4 || isip6) || !(istcp || isudp)) {
return;
}
vmxnet3_dump_virt_hdr(vhdr);
/* Validate packet len: csum_start + scum_offset + length of csum field */
if (pkt_len < (vhdr->csum_start + vhdr->csum_offset + 2)) {
VMW_PKPRN("packet len:%d < csum_start(%d) + csum_offset(%d) + 2, "
"cannot calculate checksum",
len, vhdr->csum_start, vhdr->csum_offset);
return;
}
data = (uint8_t *)pkt_data + vhdr->csum_start;
len = pkt_len - vhdr->csum_start;
/* Put the checksum obtained into the packet */
stw_be_p(data + vhdr->csum_offset, net_raw_checksum(data, len));
vhdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
vhdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID;
}
static void vmxnet3_rx_update_descr(struct VmxnetRxPkt *pkt,
struct Vmxnet3_RxCompDesc *rxcd)
{
@@ -1897,6 +1954,8 @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size)
get_eth_packet_type(PKT_GET_ETH_HDR(buf)));
if (vmxnet3_rx_filter_may_indicate(s, buf, size)) {
vmxnet_rx_pkt_set_protocols(s->rx_pkt, buf, size);
vmxnet3_rx_need_csum_calculate(s->rx_pkt, buf, size);
vmxnet_rx_pkt_attach_data(s->rx_pkt, buf, size, s->rx_vlan_stripping);
bytes_indicated = vmxnet3_indicate_packet(s) ? size : -1;
if (bytes_indicated < size) {

View File

@@ -92,9 +92,6 @@ void vmxnet_rx_pkt_attach_data(struct VmxnetRxPkt *pkt, const void *data,
}
pkt->tci = tci;
eth_get_protocols(data, len, &pkt->isip4, &pkt->isip6,
&pkt->isudp, &pkt->istcp);
}
void vmxnet_rx_pkt_dump(struct VmxnetRxPkt *pkt)
@@ -131,6 +128,15 @@ size_t vmxnet_rx_pkt_get_total_len(struct VmxnetRxPkt *pkt)
return pkt->tot_len;
}
void vmxnet_rx_pkt_set_protocols(struct VmxnetRxPkt *pkt, const void *data,
size_t len)
{
assert(pkt);
eth_get_protocols(data, len, &pkt->isip4, &pkt->isip6,
&pkt->isudp, &pkt->istcp);
}
void vmxnet_rx_pkt_get_protocols(struct VmxnetRxPkt *pkt,
bool *isip4, bool *isip6,
bool *isudp, bool *istcp)

View File

@@ -54,6 +54,17 @@ void vmxnet_rx_pkt_init(struct VmxnetRxPkt **pkt, bool has_virt_hdr);
*/
size_t vmxnet_rx_pkt_get_total_len(struct VmxnetRxPkt *pkt);
/**
* parse and set packet analysis results
*
* @pkt: packet
* @data: pointer to the data buffer to be parsed
* @len: data length
*
*/
void vmxnet_rx_pkt_set_protocols(struct VmxnetRxPkt *pkt, const void *data,
size_t len);
/**
* fetches packet analysis results
*

View File

@@ -234,27 +234,6 @@ static void net_rx_response(struct XenNetDev *netdev,
#define NET_IP_ALIGN 2
static int net_rx_ok(NetClientState *nc)
{
struct XenNetDev *netdev = qemu_get_nic_opaque(nc);
RING_IDX rc, rp;
if (netdev->xendev.be_state != XenbusStateConnected) {
return 0;
}
rc = netdev->rx_ring.req_cons;
rp = netdev->rx_ring.sring->req_prod;
xen_rmb();
if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
xen_be_printf(&netdev->xendev, 2, "%s: no rx buffers (%d/%d)\n",
__FUNCTION__, rc, rp);
return 0;
}
return 1;
}
static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size)
{
struct XenNetDev *netdev = qemu_get_nic_opaque(nc);
@@ -271,8 +250,7 @@ static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size
xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");
return -1;
return 0;
}
if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
@@ -304,7 +282,6 @@ static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size
static NetClientInfo net_xen_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = net_rx_ok,
.receive = net_rx_packet,
};

View File

@@ -312,10 +312,8 @@ static const MemoryRegionOps enet_mem_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
static int eth_can_rx(NetClientState *nc)
static int eth_can_rx(XgmacState *s)
{
XgmacState *s = qemu_get_nic_opaque(nc);
/* RX enabled? */
return s->regs[DMA_CONTROL] & DMA_CONTROL_SR;
}
@@ -329,6 +327,9 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
struct desc bd;
ssize_t ret;
if (!eth_can_rx(s)) {
return -1;
}
unicast = ~buf[0] & 0x1;
broadcast = memcmp(buf, sa_bcast, 6) == 0;
multicast = !unicast && !broadcast;
@@ -371,7 +372,6 @@ out:
static NetClientInfo net_xgmac_enet_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = eth_can_rx,
.receive = eth_rx,
};

View File

@@ -401,6 +401,9 @@ struct XilinxAXIEnet {
uint8_t rxapp[CONTROL_PAYLOAD_SIZE];
uint32_t rxappsize;
/* Whether axienet_eth_rx_notify should flush incoming queue. */
bool need_flush;
};
static void axienet_rx_reset(XilinxAXIEnet *s)
@@ -658,10 +661,8 @@ static const MemoryRegionOps enet_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
static int eth_can_rx(NetClientState *nc)
static int eth_can_rx(XilinxAXIEnet *s)
{
XilinxAXIEnet *s = qemu_get_nic_opaque(nc);
/* RX enabled? */
return !s->rxsize && !axienet_rx_resetting(s) && axienet_rx_enabled(s);
}
@@ -701,6 +702,10 @@ static void axienet_eth_rx_notify(void *opaque)
s->rxpos += ret;
if (!s->rxsize) {
s->regs[R_IS] |= IS_RX_COMPLETE;
if (s->need_flush) {
s->need_flush = false;
qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
}
}
enet_update_irq(s);
@@ -721,6 +726,11 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
DENET(qemu_log("%s: %zd bytes\n", __func__, size));
if (!eth_can_rx(s)) {
s->need_flush = true;
return 0;
}
unicast = ~buf[0] & 0x1;
broadcast = memcmp(buf, sa_bcast, 6) == 0;
multicast = !unicast && !broadcast;
@@ -925,7 +935,6 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size)
static NetClientInfo net_xilinx_enet_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = eth_can_rx,
.receive = eth_rx,
};

View File

@@ -2101,12 +2101,10 @@ static void pci_del_option_rom(PCIDevice *pdev)
}
/*
* if !offset
* Reserve space and add capability to the linked list in pci config space
*
* if offset = 0,
* Find and reserve space and add capability to the linked list
* in pci config space */
* in pci config space
*/
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
uint8_t offset, uint8_t size)
{

View File

@@ -873,8 +873,9 @@ static int timebase_post_load(void *opaque, int version_id)
*/
host_ns = qemu_clock_get_ns(QEMU_CLOCK_HOST);
ns_diff = MAX(0, host_ns - tb_remote->time_of_the_day_ns);
migration_duration_ns = MIN(NSEC_PER_SEC, ns_diff);
migration_duration_tb = muldiv64(migration_duration_ns, freq, NSEC_PER_SEC);
migration_duration_ns = MIN(NANOSECONDS_PER_SECOND, ns_diff);
migration_duration_tb = muldiv64(migration_duration_ns, freq,
NANOSECONDS_PER_SECOND);
guest_tb = tb_remote->guest_timebase + MIN(0, migration_duration_tb);
tb_off_adj = guest_tb - cpu_get_real_ticks();

View File

@@ -422,6 +422,7 @@ static void realize(DeviceState *d, Error **errp)
error_free(err);
object_unref(OBJECT(drc));
}
g_free(child_name);
DPRINTFN("drc realize complete");
}

View File

@@ -51,7 +51,7 @@ void spapr_rtc_read(DeviceState *dev, struct tm *tm, uint32_t *ns)
assert(rtc);
guest_ns = host_ns + rtc->ns_offset;
guest_s = guest_ns / NSEC_PER_SEC;
guest_s = guest_ns / NANOSECONDS_PER_SECOND;
if (tm) {
gmtime_r(&guest_s, tm);
@@ -71,7 +71,7 @@ int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset)
rtc = SPAPR_RTC(dev);
rtc->ns_offset = legacy_offset * NSEC_PER_SEC;
rtc->ns_offset = legacy_offset * NANOSECONDS_PER_SECOND;
return 0;
}
@@ -146,7 +146,7 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
host_ns = qemu_clock_get_ns(rtc_clock);
rtc->ns_offset = (new_s * NSEC_PER_SEC) - host_ns;
rtc->ns_offset = (new_s * NANOSECONDS_PER_SECOND) - host_ns;
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
@@ -168,7 +168,7 @@ static void spapr_rtc_realize(DeviceState *dev, Error **errp)
qemu_get_timedate(&tm, 0);
host_s = mktimegm(&tm);
rtc_ns = qemu_clock_get_ns(rtc_clock);
rtc->ns_offset = host_s * NSEC_PER_SEC - rtc_ns;
rtc->ns_offset = host_s * NANOSECONDS_PER_SECOND - rtc_ns;
object_property_add_tm(OBJECT(rtc), "date", spapr_rtc_qom_date, NULL);
}

View File

@@ -2202,8 +2202,15 @@ static uint64_t megasas_queue_read(void *opaque, hwaddr addr,
return 0;
}
static void megasas_queue_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
return;
}
static const MemoryRegionOps megasas_queue_ops = {
.read = megasas_queue_read,
.write = megasas_queue_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.impl = {
.min_access_size = 8,

View File

@@ -1239,10 +1239,15 @@ int scsi_cdb_length(uint8_t *buf) {
int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf)
{
int rc;
int len;
cmd->lba = -1;
cmd->len = scsi_cdb_length(buf);
len = scsi_cdb_length(buf);
if (len < 0) {
return -1;
}
cmd->len = len;
switch (dev->type) {
case TYPE_TAPE:
rc = scsi_req_stream_xfer(cmd, dev, buf);

View File

@@ -765,6 +765,9 @@ static inline bool media_is_dvd(SCSIDiskState *s)
if (!blk_is_inserted(s->qdev.conf.blk)) {
return false;
}
if (s->tray_open) {
return false;
}
blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
return nb_sectors > CD_MAX_SECTORS;
}
@@ -778,6 +781,9 @@ static inline bool media_is_cd(SCSIDiskState *s)
if (!blk_is_inserted(s->qdev.conf.blk)) {
return false;
}
if (s->tray_open) {
return false;
}
blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
return nb_sectors <= CD_MAX_SECTORS;
}
@@ -975,7 +981,15 @@ static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf)
if (s->qdev.type != TYPE_ROM) {
return -1;
}
current = media_is_dvd(s) ? MMC_PROFILE_DVD_ROM : MMC_PROFILE_CD_ROM;
if (media_is_dvd(s)) {
current = MMC_PROFILE_DVD_ROM;
} else if (media_is_cd(s)) {
current = MMC_PROFILE_CD_ROM;
} else {
current = MMC_PROFILE_NONE;
}
memset(outbuf, 0, 40);
stl_be_p(&outbuf[0], 36); /* Bytes after the data length field */
stw_be_p(&outbuf[6], current);

View File

@@ -153,7 +153,8 @@ static void vhost_scsi_stop(VHostSCSI *s)
}
static uint64_t vhost_scsi_get_features(VirtIODevice *vdev,
uint64_t features)
uint64_t features,
Error **errp)
{
VHostSCSI *s = VHOST_SCSI(vdev);

View File

@@ -629,7 +629,8 @@ static void virtio_scsi_set_config(VirtIODevice *vdev,
}
static uint64_t virtio_scsi_get_features(VirtIODevice *vdev,
uint64_t requested_features)
uint64_t requested_features,
Error **errp)
{
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
@@ -953,8 +954,6 @@ static Property virtio_scsi_properties[] = {
0xFFFF),
DEFINE_PROP_UINT32("cmd_per_lun", VirtIOSCSI, parent_obj.conf.cmd_per_lun,
128),
DEFINE_PROP_BIT("any_layout", VirtIOSCSI, host_features,
VIRTIO_F_ANY_LAYOUT, true),
DEFINE_PROP_BIT("hotplug", VirtIOSCSI, host_features,
VIRTIO_SCSI_F_HOTPLUG, true),
DEFINE_PROP_BIT("param_change", VirtIOSCSI, host_features,

View File

@@ -56,7 +56,7 @@
#define RTC_REINJECT_ON_ACK_COUNT 20
#define RTC_CLOCK_RATE 32768
#define UIP_HOLD_LENGTH (8 * NSEC_PER_SEC / 32768)
#define UIP_HOLD_LENGTH (8 * NANOSECONDS_PER_SECOND / 32768)
#define MC146818_RTC(obj) OBJECT_CHECK(RTCState, (obj), TYPE_MC146818_RTC)
@@ -105,7 +105,7 @@ static uint64_t get_guest_rtc_ns(RTCState *s)
uint64_t guest_rtc;
uint64_t guest_clock = qemu_clock_get_ns(rtc_clock);
guest_rtc = s->base_rtc * NSEC_PER_SEC
guest_rtc = s->base_rtc * NANOSECONDS_PER_SECOND
+ guest_clock - s->last_update + s->offset;
return guest_rtc;
}
@@ -231,16 +231,17 @@ static void check_update_timer(RTCState *s)
return;
}
guest_nsec = get_guest_rtc_ns(s) % NSEC_PER_SEC;
guest_nsec = get_guest_rtc_ns(s) % NANOSECONDS_PER_SECOND;
/* if UF is clear, reprogram to next second */
next_update_time = qemu_clock_get_ns(rtc_clock)
+ NSEC_PER_SEC - guest_nsec;
+ NANOSECONDS_PER_SECOND - guest_nsec;
/* Compute time of next alarm. One second is already accounted
* for in next_update_time.
*/
next_alarm_sec = get_next_alarm(s);
s->next_alarm_time = next_update_time + (next_alarm_sec - 1) * NSEC_PER_SEC;
s->next_alarm_time = next_update_time +
(next_alarm_sec - 1) * NANOSECONDS_PER_SECOND;
if (s->cmos_data[RTC_REG_C] & REG_C_UF) {
/* UF is set, but AF is clear. Program the timer to target
@@ -456,7 +457,7 @@ static void cmos_ioport_write(void *opaque, hwaddr addr,
/* if disabling set mode, update the time */
if ((s->cmos_data[RTC_REG_B] & REG_B_SET) &&
(s->cmos_data[RTC_REG_A] & 0x70) <= 0x20) {
s->offset = get_guest_rtc_ns(s) % NSEC_PER_SEC;
s->offset = get_guest_rtc_ns(s) % NANOSECONDS_PER_SECOND;
rtc_set_time(s);
}
}
@@ -580,7 +581,7 @@ static void rtc_update_time(RTCState *s)
int64_t guest_nsec;
guest_nsec = get_guest_rtc_ns(s);
guest_sec = guest_nsec / NSEC_PER_SEC;
guest_sec = guest_nsec / NANOSECONDS_PER_SECOND;
gmtime_r(&guest_sec, &ret);
/* Is SET flag of Register B disabled? */
@@ -608,7 +609,8 @@ static int update_in_progress(RTCState *s)
guest_nsec = get_guest_rtc_ns(s);
/* UIP bit will be set at last 244us of every second. */
if ((guest_nsec % NSEC_PER_SEC) >= (NSEC_PER_SEC - UIP_HOLD_LENGTH)) {
if ((guest_nsec % NANOSECONDS_PER_SECOND) >=
(NANOSECONDS_PER_SECOND - UIP_HOLD_LENGTH)) {
return 1;
}
return 0;

View File

@@ -1268,6 +1268,10 @@ static ssize_t usbnet_receive(NetClientState *nc, const uint8_t *buf, size_t siz
uint8_t *in_buf = s->in_buf;
size_t total_size = size;
if (!s->dev.config) {
return -1;
}
if (is_rndis(s)) {
if (s->rndis_state != RNDIS_DATA_INITIALIZED) {
return -1;
@@ -1309,21 +1313,6 @@ static ssize_t usbnet_receive(NetClientState *nc, const uint8_t *buf, size_t siz
return size;
}
static int usbnet_can_receive(NetClientState *nc)
{
USBNetState *s = qemu_get_nic_opaque(nc);
if (!s->dev.config) {
return 0;
}
if (is_rndis(s) && s->rndis_state != RNDIS_DATA_INITIALIZED) {
return 1;
}
return !s->in_len;
}
static void usbnet_cleanup(NetClientState *nc)
{
USBNetState *s = qemu_get_nic_opaque(nc);
@@ -1343,7 +1332,6 @@ static void usb_net_handle_destroy(USBDevice *dev)
static NetClientInfo net_usbnet_info = {
.type = NET_CLIENT_OPTIONS_KIND_NIC,
.size = sizeof(NICState),
.can_receive = usbnet_can_receive,
.receive = usbnet_receive,
.cleanup = usbnet_cleanup,
};

View File

@@ -283,6 +283,7 @@ typedef struct CCIDBus {
typedef struct USBCCIDState {
USBDevice dev;
USBEndpoint *intr;
USBEndpoint *bulk;
CCIDBus bus;
CCIDCardState *card;
BulkIn bulk_in_pending[BULK_IN_PENDING_NUM]; /* circular */
@@ -769,6 +770,7 @@ static void ccid_write_slot_status(USBCCIDState *s, CCID_Header *recv)
h->b.bError = s->bError;
h->bClockStatus = CLOCK_STATUS_RUNNING;
ccid_reset_error_status(s);
usb_wakeup(s->bulk, 0);
}
static void ccid_write_parameters(USBCCIDState *s, CCID_Header *recv)
@@ -789,6 +791,7 @@ static void ccid_write_parameters(USBCCIDState *s, CCID_Header *recv)
h->bProtocolNum = s->bProtocolNum;
h->abProtocolDataStructure = s->abProtocolDataStructure;
ccid_reset_error_status(s);
usb_wakeup(s->bulk, 0);
}
static void ccid_write_data_block(USBCCIDState *s, uint8_t slot, uint8_t seq,
@@ -810,6 +813,7 @@ static void ccid_write_data_block(USBCCIDState *s, uint8_t slot, uint8_t seq,
}
memcpy(p->abData, data, len);
ccid_reset_error_status(s);
usb_wakeup(s->bulk, 0);
}
static void ccid_report_error_failed(USBCCIDState *s, uint8_t error)
@@ -1184,7 +1188,7 @@ void ccid_card_send_apdu_to_guest(CCIDCardState *card,
uint8_t *apdu, uint32_t len)
{
DeviceState *qdev = DEVICE(card);
USBDevice *dev = USB_DEVICE(qdev);
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
USBCCIDState *s = USB_CCID_DEV(dev);
Answer *answer;
@@ -1207,7 +1211,7 @@ void ccid_card_send_apdu_to_guest(CCIDCardState *card,
void ccid_card_card_removed(CCIDCardState *card)
{
DeviceState *qdev = DEVICE(card);
USBDevice *dev = USB_DEVICE(qdev);
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
USBCCIDState *s = USB_CCID_DEV(dev);
ccid_on_slot_change(s, false);
@@ -1218,7 +1222,7 @@ void ccid_card_card_removed(CCIDCardState *card)
int ccid_card_ccid_attach(CCIDCardState *card)
{
DeviceState *qdev = DEVICE(card);
USBDevice *dev = USB_DEVICE(qdev);
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
USBCCIDState *s = USB_CCID_DEV(dev);
DPRINTF(s, 1, "CCID Attach\n");
@@ -1231,7 +1235,7 @@ int ccid_card_ccid_attach(CCIDCardState *card)
void ccid_card_ccid_detach(CCIDCardState *card)
{
DeviceState *qdev = DEVICE(card);
USBDevice *dev = USB_DEVICE(qdev);
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
USBCCIDState *s = USB_CCID_DEV(dev);
DPRINTF(s, 1, "CCID Detach\n");
@@ -1244,7 +1248,7 @@ void ccid_card_ccid_detach(CCIDCardState *card)
void ccid_card_card_error(CCIDCardState *card, uint64_t error)
{
DeviceState *qdev = DEVICE(card);
USBDevice *dev = USB_DEVICE(qdev);
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
USBCCIDState *s = USB_CCID_DEV(dev);
s->bmCommandStatus = COMMAND_STATUS_FAILED;
@@ -1263,7 +1267,7 @@ void ccid_card_card_error(CCIDCardState *card, uint64_t error)
void ccid_card_card_inserted(CCIDCardState *card)
{
DeviceState *qdev = DEVICE(card);
USBDevice *dev = USB_DEVICE(qdev);
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
USBCCIDState *s = USB_CCID_DEV(dev);
s->bmCommandStatus = COMMAND_STATUS_NO_ERROR;
@@ -1275,7 +1279,7 @@ static int ccid_card_exit(DeviceState *qdev)
{
int ret = 0;
CCIDCardState *card = CCID_CARD(qdev);
USBDevice *dev = USB_DEVICE(qdev);
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
USBCCIDState *s = USB_CCID_DEV(dev);
if (ccid_card_inserted(s)) {
@@ -1289,7 +1293,7 @@ static int ccid_card_exit(DeviceState *qdev)
static int ccid_card_init(DeviceState *qdev)
{
CCIDCardState *card = CCID_CARD(qdev);
USBDevice *dev = USB_DEVICE(qdev);
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
USBCCIDState *s = USB_CCID_DEV(dev);
int ret = 0;
@@ -1319,6 +1323,7 @@ static void ccid_realize(USBDevice *dev, Error **errp)
NULL);
qbus_set_hotplug_handler(BUS(&s->bus), DEVICE(dev), &error_abort);
s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP);
s->bulk = usb_ep_get(dev, USB_TOKEN_IN, CCID_BULK_IN_EP);
s->card = NULL;
s->migration_state = MIGRATION_NONE;
s->migration_target_ip = 0;

View File

@@ -32,7 +32,7 @@
#include "trace.h"
#define FRAME_TIMER_FREQ 1000
#define FRAME_TIMER_NS (NSEC_PER_SEC / FRAME_TIMER_FREQ)
#define FRAME_TIMER_NS (NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ)
#define UFRAME_TIMER_NS (FRAME_TIMER_NS / 8)
#define NB_MAXINTRATE 8 // Max rate at which controller issues ints

View File

@@ -2222,8 +2222,6 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
if (xfer->running_retry) {
DPRINTF("xhci: xfer nacked, stopping schedule\n");
epctx->retry = xfer;
timer_mod(epctx->kick_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
epctx->interval * 125000);
break;
}
}

View File

@@ -889,6 +889,9 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev)
fail:
trace_usb_host_open_failure(bus_num, addr);
if (s->dh != NULL) {
usb_host_release_interfaces(s);
libusb_reset_device(s->dh);
usb_host_attach_kernel(s);
libusb_close(s->dh);
s->dh = NULL;
s->dev = NULL;

View File

@@ -1517,7 +1517,7 @@ static uint64_t vfio_rtl8168_window_quirk_read(void *opaque,
memory_region_name(&quirk->mem),
vdev->vbasedev.name);
return quirk->data.address_match ^ 0x10000000U;
return quirk->data.address_match ^ 0x80000000U;
}
break;
case 0: /* data */
@@ -1558,7 +1558,7 @@ static void vfio_rtl8168_window_quirk_write(void *opaque, hwaddr addr,
switch (addr) {
case 4: /* address */
if ((data & 0x7fff0000) == 0x10000) {
if (data & 0x10000000U &&
if (data & 0x80000000U &&
vdev->pdev.cap_present & QEMU_PCI_CAP_MSIX) {
trace_vfio_rtl8168_window_quirk_write_table(
@@ -1566,11 +1566,9 @@ static void vfio_rtl8168_window_quirk_write(void *opaque, hwaddr addr,
vdev->vbasedev.name);
memory_region_dispatch_write(&vdev->pdev.msix_table_mmio,
(hwaddr)(quirk->data.address_match
& 0xfff),
data,
size,
MEMTXATTRS_UNSPECIFIED);
(hwaddr)(data & 0xfff),
(uint64_t)quirk->data.address_mask,
size, MEMTXATTRS_UNSPECIFIED);
}
quirk->data.flags = 1;
@@ -3751,7 +3749,6 @@ static Property vfio_pci_dev_properties[] = {
VFIO_FEATURE_ENABLE_VGA_BIT, false),
DEFINE_PROP_BIT("x-req", VFIOPCIDevice, features,
VFIO_FEATURE_ENABLE_REQ_BIT, true),
DEFINE_PROP_INT32("bootindex", VFIOPCIDevice, bootindex, -1),
DEFINE_PROP_BOOL("x-mmap", VFIOPCIDevice, vbasedev.allow_mmap, true),
/*
* TODO - support passed fds... is this necessary?

View File

@@ -210,12 +210,7 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
break;
case VHOST_SET_OWNER:
break;
case VHOST_RESET_OWNER:
memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
msg.state.index += dev->vq_index;
msg.size = sizeof(m.state);
break;
case VHOST_SET_MEM_TABLE:
@@ -258,20 +253,17 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
case VHOST_SET_VRING_NUM:
case VHOST_SET_VRING_BASE:
memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
msg.state.index += dev->vq_index;
msg.size = sizeof(m.state);
break;
case VHOST_GET_VRING_BASE:
memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
msg.state.index += dev->vq_index;
msg.size = sizeof(m.state);
need_reply = 1;
break;
case VHOST_SET_VRING_ADDR:
memcpy(&msg.addr, arg, sizeof(struct vhost_vring_addr));
msg.addr.index += dev->vq_index;
msg.size = sizeof(m.addr);
break;
@@ -279,7 +271,7 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
case VHOST_SET_VRING_CALL:
case VHOST_SET_VRING_ERR:
file = arg;
msg.u64 = (file->index + dev->vq_index) & VHOST_USER_VRING_IDX_MASK;
msg.u64 = file->index & VHOST_USER_VRING_IDX_MASK;
msg.size = sizeof(m.u64);
if (ioeventfd_enabled() && file->fd > 0) {
fds[fd_num++] = file->fd;
@@ -321,7 +313,6 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
error_report("Received bad msg size.");
return -1;
}
msg.state.index -= dev->vq_index;
memcpy(arg, &msg.state, sizeof(struct vhost_vring_state));
break;
default:

View File

@@ -310,7 +310,8 @@ static void virtio_balloon_set_config(VirtIODevice *vdev,
trace_virtio_balloon_set_config(dev->actual, oldactual);
}
static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f)
static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
Error **errp)
{
VirtIOBalloon *dev = VIRTIO_BALLOON(vdev);
f |= dev->host_features;

View File

@@ -54,7 +54,8 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp)
/* Get the features of the plugged device. */
assert(vdc->get_features != NULL);
vdev->host_features = vdc->get_features(vdev, vdev->host_features);
vdev->host_features = vdc->get_features(vdev, vdev->host_features,
errp);
}
/* Reset the virtio_bus */

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