Compare commits

...

286 Commits

Author SHA1 Message Date
Michael Roth
ff0245dea2 update VERSION for v1.2.2
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-11 15:09:44 -06:00
Michael Contreras
e1a0ffb957 e1000: Discard packets that are too long if !SBP and !LPE
The e1000_receive function for the e1000 needs to discard packets longer than
1522 bytes if the SBP and LPE flags are disabled. The linux driver assumes
this behavior and allocates memory based on this assumption.

Signed-off-by: Michael Contreras <michael@inetric.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit b0d9ffcd02)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 15:02:28 -06:00
Dietmar Maurer
178ef3a43a stream: fix ratelimit_set_speed
The formula to compute slice_quota was wrong since commit 6ef228fc.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit e3980e28bb)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 15:02:28 -06:00
Stefan Hajnoczi
cd00334f1a usb: fail usbdevice_create() when there is no USB bus
Report an error instead of segfaulting when attaching a USB device to a
machine with no USB busses:

  $ qemu-system-arm -machine vexpress-a9 \
      -sd Fedora-17-armhfp-vexpress-mmcblk0.img \
      -kernel vmlinuz-3.4.2-3.fc17.armv7hl \
      -initrd initramfs-3.4.2-3.fc17.armv7hl.img \
      -usbdevice disk:format=raw:test.img

Note that the vexpress-a9 machine does not have a USB host controller.

Reported-by: David Abdurachmanov <David.Abdurachmanov@cern.ch>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit c128d6a6d7)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 15:02:28 -06:00
Yonit Halperin
8c9283c82a qxl: reload memslots after migration, when qxl is in UNDEFINED mode
The devram memslot stays active when qxl enters UNDEFINED mode (i.e, no
primary surface). If migration has occurred while the device is in
UNDEFINED stae, the memslots have to be reloaded at the destination.

Fixes rhbz#874574

Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit fa98efe932)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 15:02:28 -06:00
David Gibson
bf47da47db virtio-scsi: Fix subtle (guest) endian bug
The virtio-scsi config space is, by specification, in guest endian (which
is ill-defined, but there you go).  In virtio_scsi_get_config() we set up
all the fields in there, using stl_raw().  Which is a problem for the
max_channel and max_target fields, which are 16-bit, not 32-bit.  For
little-endian targets we get away with it by accident, since the first
two bytes will still be correct, and the extra two bytes written (with
zeroes) will be overwritten correctly by the next store.

But for big-endian guests, this means the max_target field ends up as zero,
which means the guest will only recognize a single disk on the virtio-scsi
bus.  This patch fixes the problem.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Paul 'Rusty' Russell <rusty@rustcorp.com.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 863d1050c9)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 15:02:28 -06:00
David Gibson
ea08f3a4e2 virtio-scsi: Fix some endian bugs with virtio-scsi
The virtio-scsi specification does not specify the correct endianness for
fields in the request structure.  It's therefore best to assume that it is
"guest native" endian since that's the (stupid and poorly defined) norm in
virtio.

However, the qemu device for virtio-scsi has no byteswaps at all, and so
will break if the guest has different endianness from the host.  This patch
fixes it by adding tswap() calls for the sense_len and resid fields in
the request structure.  In theory status_qualifier needs swaps as well,
but that field is never actually touched.  The tag field is a uint64_t, but
since its value is completely arbitrary, it might as well be uint8_t[8]
and so it does not need swapping.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Paul 'Rusty' Russell <rusty@rustcorp.com.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 474ee55a18)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 15:02:28 -06:00
Peter Lieven
cef2566953 iscsi: do not assume device is zero initialized
Without any complex checks we can't assume that an
iscsi target is initialized to zero.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit f807ecd574)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 15:02:28 -06:00
Peter Lieven
707f2b69ff iscsi: fix deadlock during login
If the connection is interrupted before the first login is successfully
completed qemu-kvm is waiting forever in qemu_aio_wait().

This is fixed by performing an sync login to the target. If the
connection breaks after the first successful login errors are
handled internally by libiscsi.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e829b0bb05)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 15:02:28 -06:00
Peter Lieven
972a2bf072 iscsi: fix segfault in url parsing
If an invalid URL is specified iscsi_get_error(iscsi) is called
with iscsi == NULL.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 8da1e18b0c)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 15:02:28 -06:00
Bruce Rogers
ffffff0146 qapi: fix qapi_dealloc_type_size parameter type
The second parameter to qapi_dealloc_type_size should be a uint64_t *,
not a size_t *. This was causing our 32 bit x86 build to fail, since
warnings are treated as errors.

Signed-off-by: Bruce Rogers <brogers@suse.com>
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
(cherry picked from commit 1d16252652)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 15:02:28 -06:00
Stefan Hajnoczi
54c6c5a35d qapi: handle visitor->type_size() in QapiDeallocVisitor
visit_type_size() requires either visitor->type_size() or
visitor_uint64() to be implemented, otherwise a NULL function pointer is
invoked.

It is possible to trigger this crash as follows:

  $ qemu-system-x86_64 -netdev tap,sndbuf=0,id=netdev0 \
                       -device virtio-blk-pci,netdev=netdev0

The 'sndbuf' option has type "size".

Reviewed-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 0c26f2eca4)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 15:02:28 -06:00
Paolo Bonzini
f05a3da4e0 qom: fix refcount of non-heap-allocated objects
The reference count for embedded objects is always one too low, because
object_initialize_with_type returns with zero references to the object.
This causes premature finalization of the object (or an assertion failure)
after calling object_ref to add an extra reference and object_unref to
remove it.

The fix is to move the initial object_ref call from object_new_with_type
to object_initialize_with_type.

Acked-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 764b63125a)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 15:02:28 -06:00
Julio Guerra
0aad8f1a49 PPC: Fix missing TRACE exception
This patch fixes bug 1031698 :
https://bugs.launchpad.net/qemu/+bug/1031698

If we look at the (truncated) translation of the conditional branch
instruction in the test submitted in the bug post, the call to the
exception helper is missing in the "bne-false" chunk of translated
code :

IN:
bne-    0x1800278

OUT:
0xb544236d:  jne    0xb5442396

0xb5442373:  mov    %ebp,(%esp)
0xb5442376:  mov    $0x44,%ebx
0xb544237b:  mov    %ebx,0x4(%esp)
0xb544237f:  mov    $0x1800278,%ebx
0xb5442384:  mov    %ebx,0x25c(%ebp)
0xb544238a:  call   0x827475a
                     ^^^^^^^^^^^^^^^^^^

0xb5442396:  mov    %ebp,(%esp)
0xb5442399:  mov    $0x44,%ebx
0xb544239e:  mov    %ebx,0x4(%esp)
0xb54423a2:  mov    $0x1800270,%ebx
0xb54423a7:  mov    %ebx,0x25c(%ebp)

Indeed, gen_exception(ctx, excp) called by gen_goto_tb (called by
gen_bcond) changes ctx->exception's value to excp's :

gen_bcond()
{
  gen_goto_tb(ctx, 0, ctx->nip + li - 4);
  /* ctx->exception value is POWERPC_EXCP_BRANCH */

  gen_goto_tb(ctx, 1, ctx->nip);
  /* ctx->exception now value is POWERPC_EXCP_TRACE */
}

Making the following gen_goto_tb()'s test false during the second call :

if ((ctx->singlestep_enabled &
    (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
    ctx->exception == POWERPC_EXCP_BRANCH /* false...*/) {
         target_ulong tmp = ctx->nip;
         ctx->nip = dest;
         /* ... and this is the missing call */
         gen_exception(ctx, POWERPC_EXCP_TRACE);
         ctx->nip = tmp;
}

So the patch simply adds the missing matching case, fixing our problem.

Signed-off-by: Julio Guerra <guerr@julio.in>
Signed-off-by: Alexander Graf <agraf@suse.de>
(cherry picked from commit f0cc4aa845)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 15:02:28 -06:00
Paolo Bonzini
a99cb0d20a hmp: do not crash on invalid SCSI hotplug
Commit 0d93692 (qdev: Convert busses to QEMU Object Model, 2012-05-02)
removed a check on the type of the bus where a SCSI disk is hotplugged.
However, hot-plugging to the wrong kind of device now causes a crash
due to either a NULL pointer dereference (avoided by the previous patch)
or a failed QOM cast.

Instead, in this case we need to use object_dynamic_cast and check for
the result, similar to what was done before that commit.

Reported-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit b5007bcc97)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 14:27:39 -06:00
Paolo Bonzini
5e19e498b4 qom: dynamic_cast of NULL is always NULL
Trying to cast a NULL value will cause a crash.  Returning
NULL is also sensible, and it is also what the type-unsafe
DO_UPCAST macro does.

Reported-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit b7f43fe460)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 14:26:56 -06:00
Stefan Weil
4fb9656b9d block: Fix regression for MinGW (assertion caused by short string)
The local string tmp_filename is passed to function get_tmp_filename
which expects a string with minimum size MAX_PATH for w32 hosts.

MAX_PATH is 260 and PATH_MAX is 259, so tmp_filename was too short.

Commit eba25057b9 introduced this
regression.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit 89c9bc3d14)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 14:22:57 -06:00
Richard Henderson
38c6d17e75 tci: Fix type of tci_read_label
Fixes the pointer truncation that was occurring for branches.

Cc: Stefan Weil <sw@weilnetz.de>
Cc: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Tested-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit c6c5063c7a)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 14:04:34 -06:00
Kevin Wolf
600a9efdb1 qcow2: Fix refcount table size calculation
A missing factor for the refcount table entry size in the calculation
could mean that too little memory was allocated for the in-memory
representation of the table, resulting in a buffer overflow.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Tested-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit a354807706)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 13:32:32 -06:00
Bruce Rogers
ea79e157c6 configure: avoid compiler warning in pipe2 detection
When building qemu-kvm for openSUSE:Factory, I am getting a
warning in the pipe2 detection performed by configure, which
prevents using --enable-werror.

Change detection code to use return value of pipe2.

Signed-off-by: Bruce Rogers <brogers@suse.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit 9bca81624e)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 13:24:20 -06:00
Aurelien Jarno
4a8e490cbc target-openrisc: remove conflicting definitions from cpu.h
On an ARM host, the registers definitions from cpu.h clash
with /usr/include/sys/ucontext.h. As there are unused, just remove
them.

Cc: Jia Liu <proljc@gmail.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 44e04d3b94)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 13:23:11 -06:00
Aurelien Jarno
ede76edace tcg/arm: fix cross-endian qemu_st16
The bswap16 TCG opcode assumes that the high bytes of the temp equal
to 0 before calling it. The ARM backend implementation takes this
assumption to slightly optimize the generated code.

The same implementation is called for implementing the cross-endian
qemu_st16 opcode, where this assumption is not true anymore. One way to
fix that would be to zero the high bytes before calling it. Given the
store instruction just ignore them, it is possible to provide a slightly
more optimized version. With ARMv6+ the rev16 instruction does the work
correctly. For lower ARM versions the patch provides a version which
behaves correctly with non-zero high bytes, but fill them with junk.

Cc: Andrzej Zaborowski <balrogg@gmail.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 7aab08aa78)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 13:22:56 -06:00
Aurelien Jarno
ac914c1fc2 tcg/arm: fix TLB access in qemu-ld/st ops
The TCG arm backend considers likely that the offset to the TLB
entries does not exceed 12 bits for mem_index = 0. In practice this is
not true for at least the MIPS target.

The current patch fixes that by loading the bits 23-12 with a separate
instruction, and using loads with address writeback, independently of
the value of mem_idx. In total this allow a 24-bit offset, which is a
lot more than needed.

Cc: Andrzej Zaborowski <balrogg@gmail.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-stable@nongnu.org
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit d17bd1d8cc)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-12-03 13:21:47 -06:00
陳韋任 (Wei-Ren Chen)
357414daa4 target-mips: fix wrong microMIPS opcode encoding
While reading microMIPS decoding, I found a possible wrong opcode
encoding. According to [1] page 166, the bits 13..12 for MULTU is
0x01 rather than 0x00. Please review, thanks.

[1] MIPS Architecture for Programmers VolumeIV-e: The MIPS DSP
    Application-Specific Extension to the microMIPS32 Architecture

Signed-off-by: Chen Wei-Ren <chenwj@iis.sinica.edu.tw>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 6801038bc5)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 16:07:16 -06:00
Aurelien Jarno
f6b803df74 mips/malta: fix CBUS UART interrupt pin
According to the MIPS Malta Developement Platform User's Manual, the
i8259 interrupt controller is supposed to be connected to the hardware
IRQ0, and the CBUS UART to the hardware interrupt 2.

In QEMU they are both connected to hardware interrupt 0, the CBUS UART
interrupt being wrong. This patch fixes that. It should be noted that
the irq array in QEMU includes the software interrupts, hence
env->irq[2] is the first hardware interrupt.

Cc: Ralf Baechle <ralf@linux-mips.org>
Reviewed-by: Eric Johnson <ericj@mips.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 68d001928b)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 16:05:41 -06:00
Paolo Bonzini
879c264803 nbd: fixes to read-only handling
We do not need BLKROSET if the kernel supports setting flags.
Also, always do BLKROSET even for a read-write export, otherwise
the read-only state remains "sticky" after the invocation of
"qemu-nbd -r".

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit c8969eded2)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 16:02:14 -06:00
Meador Inge
382a582c1f m68k: Return semihosting errno values correctly
Fixing a simple typo, s/errno/err/, that caused
the error status from GDB semihosted system calls
to be returned incorrectly.

Signed-off-by: Meador Inge <meadori@codesourcery.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit aed91c1bff)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 16:01:29 -06:00
Paolo Bonzini
5c0d5aebd5 tools: initialize main loop before block layer
Tools were broken because they initialized the block layer while
qemu_aio_context was still NULL.

Reported-by: malc <av1474@comtv.ru>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: malc <av1474@comtv.ru>
(cherry picked from commit 2592c59a66)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:59:27 -06:00
Gerd Hoffmann
3dd59b4dc7 xhci: fix usb name in caps
Used to be "UTB" not "USB".

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 0ebfb144e8)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:57:51 -06:00
Aurelien Jarno
03e044136a target-sparc64: disable VGA cirrus
OpenBIOS on sparc64 only support Standard VGA and not Cirrus VGA. Don't
build Cirrus VGA support so that it can't be selected.

This fixes the breakage introduced by commit f2898771.

Reported-by: Richard Henderson <rth@twiddle.net>
Cc: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Tested-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit 0356404b0f)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:56:47 -06:00
Alexander Graf
db6e5ab78e PPC: Bamboo: Fix memory size DT property
Device tree properties need to be specified in big endian. Fix the
bamboo memory size property accordingly.

Signed-off-by: Alexander Graf <agraf@suse.de>
CC: qemu-stable@nongnu.org
(cherry picked from commit 5232fa59b1)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:56:10 -06:00
Alexander Graf
7817b8d858 s390x: fix -initrd in virtio machine
When using -initrd in the virtio machine, we need to indicate the initrd
start and size inside the kernel image. These parameters need to be stored
in native endianness.

Signed-off-by: Alexander Graf <agraf@suse.de>
Acked-by: Richard Henderson <rth@twiddle.net>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
(cherry picked from commit 235a3f0bed)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:55:22 -06:00
Avi Kivity
0dfd8215c2 memory: fix rendering of a region obscured by another
The memory core drops regions that are hidden by another region (for example,
during BAR sizing), but it doesn't do so correctly if the lower address of the
existing range is below the lower address of the new range.

Example (qemu-system-mips -M malta -kernel vmlinux-2.6.32-5-4kc-malta
         -append "console=ttyS0"  -nographic -vga cirrus):

Existing range: 10000000-107fffff
New range:      100a0000-100bffff

Correct behaviour: drop new range
Incorrect behaviour: add new range

Fix by taking this case into account (previously we only considered
equal lower boundaries).

Tested-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d26a8caea3)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:54:07 -06:00
Dmitry Fleytman
e16d81df85 e1000: drop check_rxov, always treat RX ring with RDH == RDT as empty
Real HW always treats RX ring with RDH == RDT as empty.
Emulation is supposed to behave the same.

Reported-by: Chris Webb <chris.webb@elastichosts.com>
Reported-by: Richard Davies <richard.davies@elastichosts.com>
Signed-off-by: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit e5b8b0d4ba)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:53:11 -06:00
Don Slutz
3dfbc51e78 target-i386: Allow tsc-frequency to be larger then 2.147G
The check using INT_MAX (2147483647) is wrong in this case.

Signed-off-by: Fred Oliveira <foliveira@cloudswitch.com>
Signed-off-by: Don Slutz <Don@CloudSwitch.com>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit 2e84849aa2)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:44:14 -06:00
Stefan Weil
eb63b0c2da hw: Fix return value check for bdrv_read, bdrv_write
Those functions return -errno in case of an error.
The old code would typically only detect EPERM (1) errors.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit 7a608f562e)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:42:17 -06:00
Paolo Bonzini
4843c928f9 rtc: fix overflow in mktimegm
When setting a date in 1980, Linux is actually disregarding the century
byte and setting the year to 2080.  This causes a year-2038 overflow
in mktimegm.  Fix this by doing the days-to-seconds computation in
64-bit math.

Reported-by: Lucas Meneghel Rodrigues <lookkas@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit b6db4aca20)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:41:52 -06:00
Gerd Hoffmann
a106eaa3a6 qxl: always update displaysurface on resize
Don't try to be clever and skip displaysurface reinitialization in case
the size hasn't changed.  Other parameters might have changed
nevertheless, for example depth or stride, resulting in rendering being
broken then.

Trigger: boot linux guest with vesafb, start X11, make sure both vesafb
and X11 use the display same resolution.  Then watch X11 screen being
upside down.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 0ec8df3974)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:41:11 -06:00
Alon Levy
472da83043 hw/qxl: qxl_dirty_surfaces: use uintptr_t
As suggested by Paolo Bonzini, to avoid possible integer overflow issues.

Signed-off-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit c5825ac6c8)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:39:56 -06:00
Hans de Goede
85c91ea7e2 uhci: Raise interrupt when requested even for non active tds
According to the spec we must raise an interrupt when one is requested
even for non active tds.

Linux depends on this, for bulk transfers it runs an inactivity timer
to work around a bug in early uhci revisions, when we take longer then
200 ms to process a packet, this timer goes of, and as part of the
handling Linux then unlinks the qh, and relinks it after the frindex
has increased by atleast 1, the problem is Linux only checks for the
frindex increases on an interrupt, and we don't send that, causing
the qh to go inactive for more then 32 frames, at which point we
consider the packet cancelled.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 883bca776d)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:39:28 -06:00
Paolo Bonzini
5af7caaadd vnc: fix "info vnc" with "-vnc ..., reverse=on"
When reverse connection is in use, there is no active VNC server
socket.  Because of this, getsockopt(-1, ...) is attempted and
the following error is emitted:

    $ socat TCP-LISTEN:5900,reuseaddr TCP-LISTEN:5901,reuseaddr &
    $ x86_64-softmmu/qemu-system-x86_64 -vnc localhost:5900,reverse -monitor stdio
    QEMU 1.2.50 monitor - type 'help' for more information
    (qemu) info vnc
    An undefined error has occurred

Because however the host, family, service and auth fields are
optional, we can just exit if there is no active server socket.

    $ x86_64-softmmu/qemu-system-x86_64 -vnc localhost:5900,reverse -monitor stdio
    QEMU 1.2.50 monitor - type 'help' for more information
    (qemu) info vnc
    Server:
    Client:
         address: 127.0.0.1:5900
      x509_dname: none
        username: none

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 417b0b8890)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:38:14 -06:00
Joel Martin
0ae18b369c ui/vnc: Only report/use TIGHT_PNG encoding if enabled.
If TIGHT_PNG is not enabled by the --enable-vnc-png configure flag
then do not report to the client that it is supported.

Also, since TIGHT_PNG is the same as the TIGHT encoding but with the
filter/copy replaced with PNG data, adding it to the supported
encodings list when it is disabled will cause the TIGHT encoding to be
used even though the client requested TIGHT_PNG.

Signed-off-by: Joel Martin <github@martintribe.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit fe3e7f2dc0)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:36:13 -06:00
Michael Tokarev
5a99c8ca01 fix CONFIG_QEMU_HELPERDIR generation again
commit 38f419f352 fixed a breakage with CONFIG_QEMU_HELPERDIR
which has been introduced by 8bf188aa18.  But while techinically
that fix has been correct, all other similar variables are handled
differently.  Make it consistent, and let scripts/create_config
expand and capitalize the variable properly like for all other
qemu_*dir variables.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit f354b1a1ee)

Conflicts:

	configure

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:27:54 -06:00
Jan Kiszka
029eae1a75 configure: Fix CONFIG_QEMU_HELPERDIR generation
We need to evaluate $libexecdir in configure, otherwise we literally end
up with "${prefix}/libexec" instead of the absolute path as
CONFIG_QEMU_HELPERDIR.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 38f419f352)

Conflicts:

	configure

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-11-30 15:21:15 -06:00
Michael Roth
f4c53d94d2 update VERSION for v1.2.1
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:47:44 -05:00
David Gibson
159fe82dea pseries: Don't test for MSR_PR for hypercalls under KVM
PAPR hypercalls should only be invoked from the guest kernel, not guest
user programs, that is, with MSR[PR]=0.  Currently we check this in
spapr_hypercall, returning H_PRIVILEGE if MSR[PR]=1.

However, under KVM the state of MSR[PR] is already checked by the host
kernel before passing the hypercall to qemu, making this check redundant.
Worse, however, we don't generally synchronize KVM and qemu state on the
hypercall path, meaning that qemu could incorrectly reject a hypercall
because it has a stale MSR value.

This patch fixes the problem by moving the privilege test exclusively to
the TCG hypercall path.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
CC: qemu-stable@nongnu.org
Signed-off-by: Alexander Graf <agraf@suse.de>
(cherry picked from commit efcb9383b9)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:21 -05:00
Peter Maydell
a8f2299d1b fpu/softfloat.c: Return correctly signed values from uint64_to_float32
The uint64_to_float32() conversion function was incorrectly always
returning numbers with the sign bit set (ie negative numbers). Correct
this so we return positive numbers instead.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit e744c06fca)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:21 -05:00
Eduardo Habkost
68fc5d1d27 i386: kvm: bit 10 of CPUID[8000_0001].EDX is reserved
Bit 10 of CPUID[8000_0001].EDX is not defined as an alias of
CPUID[1].EDX[10], so do not duplicate it on
kvm_arch_get_supported_cpuid().

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-By: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Don Slutz <Don@CloudSwitch.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit b1f4679392)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:21 -05:00
Francesco Lavra
3e1954cb4a Versatile Express: Fix NOR flash 0 address and remove flash alias
In the A series memory map (implemented in the Cortex A15 CoreTile), the
first NOR flash bank (flash 0) is mapped to address 0x08000000, while
address 0x00000000 can be configured as alias to either the first or the
second flash bank. This patch fixes the definition of flash 0 address,
and for simplicity removes the alias definition.

Signed-off-by: Francesco Lavra <francescolavra.fl@gmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 661bafb3e1)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:21 -05:00
Meador Inge
14bdf978ef hw/armv7m_nvic: Correctly register GIC region when setting up NVIC
When setting up the NVIC memory regions the memory range
0x100..0xcff is aliased to an IO memory region that belongs
to the ARM GIC.  This aliased region should be added to the
NVIC memory container, but the actual GIC IO memory region
was being added instead.  This mixup was causing the wrong
IO memory access functions to be called when accessing parts
of the NVIC memory.

Signed-off-by: Meador Inge <meadori@codesourcery.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 9892cae395)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:21 -05:00
Brendan Fennell
806d996789 pl190: fix read of VECTADDR
Reading VECTADDR was causing us to set the current priority to
the wrong value, the most obvious effect of which was that we
would return the vector for the wrong interrupt as the result
of the read.

Signed-off-by: Brendan Fennell <bfennell@skynet.ie>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 14c126baf1)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:21 -05:00
Orit Wasserman
d893e56f72 Clear handler only for valid fd
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 3202becaa2)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:21 -05:00
Orit Wasserman
240f68ce5b Fix address handling in inet_nonblocking_connect
getaddrinfo can give us a list of addresses, but we only try to
connect to the first one. If that fails we never proceed to
the next one.  This is common on desktop setups that often have ipv6
configured but not actually working.

To fix this make inet_connect_nonblocking retry connection with a different
address.
callers on inet_nonblocking_connect register a callback function that will
be called when connect opertion completes, in case of failure the fd will have
a negative value

Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 233aa5c2d1)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:21 -05:00
Orit Wasserman
ee0999b16a Separate inet_connect into inet_connect (blocking) and inet_nonblocking_connect
No need to add non blocking parameters to the blocking inet_connect
add block parameter for inet_connect_opts instead of using QemuOpt "block".

Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 5db5f44cb4)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:21 -05:00
Michael S. Tsirkin
57f8a4c507 Refactor inet_connect_opts function
refactor address resolution code to fix nonblocking connect
remove getnameinfo call

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Amos Kong <akong@redhat.com>
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 05bc1d8a4b)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:21 -05:00
Stefan Weil
b83465006d configure: Allow builds without any system or user emulation
The old code aborted configure when no emulation target was selected.
Even after removing the 'exit 1', it tried to read from STDIN
when QEMU was configured with

    configure' '--disable-user' '--disable-system'

This is fixed here.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 8bdd3d499f)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:21 -05:00
Jeff Cody
d80210efbc block: correctly set the keep_read_only flag
I believe the bs->keep_read_only flag is supposed to reflect
the initial open state of the device. If the device is initially
opened R/O, then commit operations, or reopen operations changing
to R/W, are prohibited.

Currently, the keep_read_only flag is only accurate for the active
layer, and its backing file. Subsequent images end up always having
the keep_read_only flag set.

For instance, what happens now:

[  base  ]  kro = 1, ro = 1
    |
    v
[ snap-1 ]  kro = 1, ro = 1
    |
    v
[ snap-2 ]  kro = 0, ro = 1
    |
    v
[ active ]  kro = 0, ro = 0

What we want:

[  base  ]  kro = 0, ro = 1
    |
    v
[ snap-1 ]  kro = 0, ro = 1
    |
    v
[ snap-2 ]  kro = 0, ro = 1
    |
    v
[ active ]  kro = 0, ro = 0

Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit be028adced)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Kevin Shanahan
513cdda198 blockdev: preserve readonly and snapshot states across media changes
If readonly=on is given at device creation time, the ->readonly flag
needs to be set in the block driver state for this device so that
readonly-ness is preserved across media changes (qmp change command).
Similarly, to preserve the snapshot property requires ->open_flags to
be correct.

Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 80dd1aae36)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Stefan Weil
eea54caab0 w32: Add implementation of gmtime_r, localtime_r
Those functions are missing in MinGW.

Some versions of MinGW-w64 include defines for gmtime_r and localtime_r.
Older versions of these macros are buggy (they return a pointer to a
static variable), therefore we don't want them. Newer versions are
similar to the code used here, but without the memset.

The implementation which is used here is not strictly reentrant,
but sufficiently good for QEMU on w32 or w64.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
[blauwirbel@gmail.com: added comment about locking]
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit d3e8f95753)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Stefan Weil
78fd27b3b6 w32: Always use standard instead of native format strings
GLib 2.0 include files use __printf__ for the format attribute
which resolves to native format strings on w32 hosts.

QEMU wants standard format strings instead of native format
strings, so we simply change any declaration with __printf__
to use __gnu_printf__.

This works because all basic printf functions support both
kinds of format strings.

This fixes a compiler warning:

qapi/string-output-visitor.c: In function ‘print_type_int’:
qapi/string-output-visitor.c:34:5: warning: unknown conversion type character ‘l’ in format [-Wformat]
qapi/string-output-visitor.c:34:5: warning: too many arguments for format [-Wformat-extra-args]

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit 95df51a4a0)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Stefan Weil
d4413913e1 net/socket: Fix compiler warning (regression for MinGW)
Commit 213fd5087e removed a type cast
which is needed for MinGW:

net/socket.c:136: warning:
 pointer targets in passing argument 2 of ‘sendto’ differ in signedness
/usr/lib/gcc/amd64-mingw32msvc/4.4.4/../../../../amd64-mingw32msvc/include/winsock2.h:1313: note:
 expected ‘const char *’ but argument is of type ‘const uint8_t *’

Add a 'qemu_sendto' macro which provides that type cast where needed
and use the new macro instead of 'sendto'.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit 73062dfe6b)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Stefan Weil
61dea8e914 linux-user: Remove redundant null check and replace free by g_free
Report from smatch:

linux-user/syscall.c:3632 do_ioctl_dm(220) info:
 redundant null check on big_buf calling free()

'big_buf' was allocated by g_malloc0, therefore free was also
replaced by g_free.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit ad11ad7774)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Laszlo Ersek
a2aad5fdc4 TextConsole: saturate escape parameter in TTY_STATE_CSI
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit c10600af60)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Hitoshi Mitake
5730401442 curses: don't initialize curses when qemu is daemonized
Current qemu initializes curses even if -daemonize option is
passed. This cause problem because shell prompt appears without
calling endwin().

This patch adds new function, is_daemonized(), to OS dependent
code. With this function, curses_display_init() can check that qemu is
daemonized or not. If daemonized, curses_display_init() isn't called
and the problem is avoided.

Of course, -daemonize && -curses doesn't make sense. Users shouldn't
pass the arguments at the same time. But the problem is very painful
because Ctrl-C cannot be delivered to the terminal.

Cc: Andrzej Zaborowski  <balrog@zabor.org>
Cc: Stefan Hajnoczi <stefanha@gmail.com>
Cc: Anthony Liguori <aliguori@us.ibm.com>
Cc: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Hitoshi Mitake <h.mitake@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit 995ee2bf46)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Stefan Weil
f3e9893078 pflash_cfi01: Fix warning caused by unreachable code
Report from smatch:
hw/pflash_cfi01.c:431 pflash_write(180) info: ignoring unreachable code.

Instead of removing the return statement after the switch statement,
the patch replaces the return statements in the switch statement by
break statements. Other switch statements in the same code do it also
like that.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit 12dabc79f9)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Stefan Weil
4d0fcc1968 ioh3420: Remove unreachable code
Report from smatch:
hw/ioh3420.c:128 ioh3420_initfn(35) info: ignoring unreachable code.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit 997f15672a)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Stefan Weil
2b9a5aca51 lm4549: Fix buffer overflow
Report from smatch:
lm4549.c:234 lm4549_write_samples(14) error:
 buffer overflow 's->buffer' 1024 <= 1024

There must be enough space to add two entries starting with index
s->buffer_level, therefore the old check was wrong.

[Peter Maydell <peter.maydell@linaro.org> clarifies the nature of the
analyser warning:

I don't object to making the change to placate the analyser,
but I don't think this is actually a buffer overrun. We always
add and remove samples from the buffer two at a time, so it's
not possible to get here with s->buffer_level == BUFFER_SIZE-1
(which is the only case where the old and new conditions
give different answers).]

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit 8139626643)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Stefan Weil
96d90d32ac cadence_uart: Fix buffer overflow
Report from smatch:
hw/cadence_uart.c:413 uart_read(13) error: buffer overflow 's->r' 18 <= 18

This fixes read access to s->r[R_MAX] which is behind the limits of s->r.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit 5d40097fc0)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Stefan Weil
3c980e22ac qemu-sockets: Fix potential memory leak
The old code leaks variable 'peer'.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit 39b384591f)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Stefan Weil
907a34c9d7 qemu-ga: Remove unreachable code after g_error
Report from smatch:
qemu-ga.c:117 register_signal_handlers(11) info: ignoring unreachable code.
qemu-ga.c:122 register_signal_handlers(16) info: ignoring unreachable code.

g_error calls abort which terminates the program.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit b548828862)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Stefan Weil
b79ba45af1 audio: Fix warning from static code analysis
smatch report:
audio/audio_template.h:416 AUD_open_out(18) warn:
 variable dereferenced before check 'as' (see line 414)

Moving the ldebug statement after the statement which checks 'as'
fixes that warning.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: malc <av1474@comtv.ru>
(cherry picked from commit 93b6599734)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Ronnie Sahlberg
75a44ae297 SCSI: Standard INQUIRY data should report HiSup flag as set.
QEMU as far as I know only reports LUN numbers using the modes that
are described in SAM4.
As such, since all LUN numbers generated by the SCSI emulation in QEMU
follow SAM4, we should set the HiSup bit in the standard INQUIRY data
to indicate such.

From SAM4:
  4.6.3 LUNs overview
  All LUN formats described in this standard are hierarchical in
  structure even when only a single level in that hierarchy is used.
  The HISUP bit shall be set to one in the standard INQUIRY data
  (see SPC-4) when any LUN format described in this standard is used.
  Non-hierarchical formats are outside the scope of this standard.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
(cherry picked from commit 1109c89405)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:20 -05:00
Paolo Bonzini
ff498e4a0d scsi-disk: fix check for out-of-range LBA
This fix is needed to correctly handle 0-block read and writes.
Without it, a 0-block access at LBA 0 would underflow.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 12ca76fc48)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
Paolo Bonzini
394a2f28cb scsi-disk: introduce check_lba_range
Abstract the test for an out-of-range (starting block, block count)
pair.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 444bc90861)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
Ronnie Sahlberg
60088e5b83 iSCSI: We dont need to explicitely call qemu_notify_event() any more
We no longer need to explicitely call qemu_notify_event() any more
since this is now done automatically any time the filehandles we listen
to change.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 40a13ca8d2)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
Ronnie Sahlberg
ae06193d73 iSCSI: We need to support SG_IO also from iscsi_ioctl()
We need to support SG_IO from the synchronous iscsi_ioctl() since
scsi-block uses this to do an INQ to the device to discover its properties
This patch makes scsi-block work with iscsi.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit f1a12821d7)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
Andreas Färber
e8ca4a8ac7 MAINTAINERS: Add entry for QOM CPU
Signed-off-by: Andreas Färber <afaerber@suse.de>
(cherry picked from commit f2ca052414)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
Aurelien Jarno
68958c31b5 pflash_cfi01: fix vendor specific extended query
pflash_cfi01 announces a version number of 1.1, which implies
"Protection Register Information" and "Burst Read information"
sections, which are not provided.

Decrease the version number to 1.0 so that only the "Protection
Register Information" section is needed.

Set the number of protection fields (0x3f) to 0x01, as 0x00 means 256
protections field, which makes the CFI table bigger than the current
implementation, causing some kernels to fail to read it.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 262e1eaafa)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
Chris Wulff
584717a39a xilinx_timer: Fix a compile error if debug enabled
There was a missing include of qemu-log and a variable name in a printf was out
of date.

Signed-off-by: Chris Wulff <crwulff@gmail.com>
Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>
(cherry picked from commit 8354cd722e)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
Peter A. G. Crosthwaite
85368b79a0 xilinx.h: Error check when setting links
Assert that the ethernet and dma controller are sucessfully linked to their
peers.

Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>
(cherry picked from commit 4b5e52101f)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
Peter A. G. Crosthwaite
36d7fb299a xilinx_timer: Send dbg msgs to stderr not stdout
Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>
(cherry picked from commit e03377ae75)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
Peter A. G. Crosthwaite
3412955066 xilinx_timer: Removed comma in device name
Fixes an error in a61e4b07a3

Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>
(cherry picked from commit c0a1dcb9f0)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
Peter Maydell
b52c8f78f2 arch_init.c: Improve '-soundhw help' for non-HAS_AUDIO_CHOICE archs
For architectures which don't set HAS_AUDIO_CHOICE, improve the
'-soundhw help' message so that it doesn't simply print an empty
list, implying no sound support at all.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: malc <av1474@comtv.ru>
(cherry picked from commit 55d4fd3c24)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
David Gibson
668194d5a5 cpu_physical_memory_write_rom() needs to do TB invalidates
cpu_physical_memory_write_rom(), despite the name, can also be used to
write images into RAM - and will often be used that way if the machine
uses load_image_targphys() into RAM addresses.

However, cpu_physical_memory_write_rom(), unlike cpu_physical_memory_rw()
doesn't invalidate any cached TBs which might be affected by the region
written.

This was breaking reset (under full emu) on the pseries machine - we loaded
our firmware image into RAM, and while executing it rewrite the code at
the entry point (correctly causing a TB invalidate/refresh).  When we
reset the firmware image was reloaded, but the TB from the rewrite was
still active and caused us to get an illegal instruction trap.

This patch fixes the bug by duplicating the tb invalidate code from
cpu_physical_memory_rw() in cpu_physical_memory_write_rom().

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 0b57e28713)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
David Gibson
8484fead29 qemu-char: BUGFIX, don't call FD_ISSET with negative fd
tcp_chr_connect(), unlike for example udp_chr_update_read_handler() does
not check if the fd it is using is valid (>= 0) before passing it to
qemu_set_fd_handler2().  If using e.g. a TCP serial port, which is not
initially connected, this can result in -1 being passed to FD_ISSET, which
has undefined behaviour.  On x86 it seems to harmlessly return 0, but on
PowerPC, it causes a fortify buffer overflow error to be thrown.

This patch fixes this by putting an extra test in tcp_chr_connect(), and
also adds an assert qemu_set_fd_handler2() to catch other such errors on
all platforms, rather than just some.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit bbdd2ad081)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
Anthony Liguori
57683d6354 Revert 455aa1e08 and c3767ed0eb
commit c3767ed0eb
    qemu-char: (Re-)connect for tcp_chr_write() unconnected writing

Has no hope of working because tcp_chr_connect() does not actually connect.

455aa1e08 just fixes the SEGV with server() but the attempt to connect a client
socket is still completely broken.

This patch reverts both.

Reported-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 6db0fdce02)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:19 -05:00
Natanael Copa
5d6ad6262b configure: properly check if -lrt and -lm is needed
Fixes build against uClibc.

uClibc provides 2 versions of clock_gettime(), one with realtime
support and one without (this is so you can avoid linking in -lrt
unless actually needed). This means that the clock_gettime() don't
need -lrt. We still need it for timer_create() so we check for this
function in addition.

We also need check if -lm is needed for isnan().

Both -lm and -lrt are needed for libs_qga.

Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit 8bacde8d86)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Yann E. MORIN
a63eb7a227 configure: fix seccomp check
Currently, if libseccomp is missing but the user explicitly requested
seccomp support using --enable-seccomp, configure silently ignores the
situation and disables seccomp support.

This is unlike all other tests that explicitly fail in such situation.

Fix that.

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit e84d5956cc)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Stefan Hajnoczi
a638498f51 net: EAGAIN handling for net/socket.c TCP
Replace spinning send_all() with a proper non-blocking send.  When the
socket write buffer limit is reached, we should stop trying to send and
wait for the socket to become writable again.

Non-blocking TCP sockets can return in two different ways when the write
buffer limit is reached:

1. ret = -1 and errno = EAGAIN/EWOULDBLOCK.  No data has been written.

2. ret < total_size.  Short write, only part of the message was
   transmitted.

Handle both cases and keep track of how many bytes have been written in
s->send_index.  (This includes the 'length' header before the actual
payload buffer.)

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 45a7f54a8b)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Stefan Hajnoczi
9d72a090b2 net: EAGAIN handling for net/socket.c UDP
Implement asynchronous send for UDP (or other SOCK_DGRAM) sockets.  If
send fails with EAGAIN we wait for the socket to become writable again.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 213fd5087e)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Stefan Hajnoczi
ab52df7712 net: asynchronous send/receive infrastructure for net/socket.c
The net/socket.c net client is not truly asynchronous.  This patch
borrows the qemu_set_fd_handler2() code from net/tap.c as the basis for
proper asynchronous send/receive.

Only read packets from the socket when the peer is able to receive.
This avoids needless queuing.

Later patches implement asynchronous send.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 863f678fba)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Stefan Hajnoczi
5c8240c09c net: broadcast hub packets if at least one port can receive
In commit 60c07d933c ("net: fix
qemu_can_send_packet logic") the "VLAN" broadcast behavior was changed
to queue packets if any net client cannot receive.  It turns out that
this was not actually the right fix and just hides the real bug that
hw/usb/dev-network.c:usbnet_receive() clobbers its receive buffer when
called multiple times in a row.  The commit also introduced a new bug
that "VLAN" packets would not be sent if one of multiple net clients was
down.

The hw/usb/dev-network.c bug has since been fixed, so this patch reverts
broadcast behavior to send packets as long as one net client can
receive.  Packets simply get queued for the net clients that are
temporarily unable to receive.

Reported-by: Roy.Li <rongqing.li@windriver.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 61518a74ca)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Stefan Hajnoczi
d8f4811880 net: fix usbnet_receive() packet drops
The USB network interface has a single buffer which the guest reads
from.  This patch prevents multiple calls to usbnet_receive() from
clobbering the input buffer.  Instead we queue packets until buffer
space becomes available again.

This is inspired by virtio-net and e1000 rxbuf handling.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 190563f9a9)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Stefan Hajnoczi
2747a3eee3 net: clean up usbnet_receive()
The USB network interface has two code paths depending on whether or not
RNDIS mode is enabled.  Refactor usbnet_receive() so that there is a
common path throughout the function instead of duplicating everything
across if (is_rndis(s)) ... else ... code paths.

Clean up coding style and 80 character line wrap along the way.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit f237ddbb89)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Stefan Hajnoczi
aa69dd05ce net: add -netdev options to man page
Document the -netdev syntax which supercedes the older -net syntax.
This patch is a first step to making -netdev prominent in the QEMU
manual.

Reported-by: Anatoly Techtonik <techtonik@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 08d12022c7)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Stefan Hajnoczi
a9d8f7b1c4 net: do not report queued packets as sent
Net send functions have a return value where 0 means the packet has not
been sent and will be queued.  A non-zero value means the packet was
sent or an error caused the packet to be dropped.

This patch fixes two instances where packets are queued but we return
their size.  This causes callers to believe the packets were sent.  When
the caller uses the async send interface this creates a real problem
because the callback will be invoked for a packet that the caller
believed to be already sent.  This bug can cause double-frees in the
caller.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 06b5f36d05)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Stefan Hajnoczi
0d91cd5aa7 net: add receive_disabled logic to iov delivery path
This patch adds the missing NetClient->receive_disabled logic in the
sendv delivery code path.  It seems that commit
893379efd0 ("net: disable receiving if
client returns zero") only added the logic to qemu_deliver_packet() and
not qemu_deliver_packet_iov().

The receive_disabled flag should be automatically set when .receive(),
.receive_raw(), or .receive_iov() return 0.  No further packets will be
delivered to the NetClient until the receive_disabled flag is cleared
again by calling qemu_flush_queued_packets().

Typically the NetClient will wait until its file descriptor becomes
writable and then invoke qemu_flush_queued_packets() to resume
transmission.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit c67f5dc105)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Bo Yang
bfa23099aa eepro100: Fix network hang when rx buffers run out
This is reported by QA. When installing os with pxe, after the initial
kernel and initrd are loaded, the procedure tries to copy files from install
server to local harddisk, the network becomes stall because of running out of
receive descriptor.

[Whitespace fixes and removed qemu_notify_event() because Paolo's
earlier net patches have moved it into qemu_flush_queued_packets().

Additional info:

I can reproduce the network hang with a tap device doing a iPXE HTTP
boot as follows:

  $ qemu -enable-kvm -m 1024 \
    -netdev tap,id=netdev0,script=no,downscript=no \
    -device i82559er,netdev=netdev0,romfile=80861209.rom \
    -drive if=virtio,cache=none,file=test.img
  iPXE> ifopen net0
  iPXE> config # set static network configuration
  iPXE> kernel http://mirror.bytemark.co.uk/fedora/linux/releases/17/Fedora/x86_64/os/images/pxeboot/vmlinuz

I needed a vanilla iPXE ROM to get to the iPXE prompt.  I think the boot
prompt has been disabled in the ROMs that ship with QEMU to reduce boot
time.

During the vmlinuz HTTP download there is a network hang.  hw/eepro100.c
has reached the end of the rx descriptor list.  When the iPXE driver
replenishes the rx descriptor list we don't kick the QEMU net subsystem
and event loop, thereby leaving the tap netdev without its file
descriptor in select(2).

Stefan Hajnoczi <stefanha@gmail.com>]

Signed-off-by: Bo Yang <boyang@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit 1069985fb1)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Paolo Bonzini
65a2f8e27c xen: flush queue when getting an event
xen does not have a register that, when written, will cause can_receive
to go from false to true.  However, flushing the queue can be attempted
whenever the front-end raises its side of the Xen event channel.  There
is a single event channel for tx and rx.

Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Amos Kong <akong@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit a98b140223)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Paolo Bonzini
7575a6d2f2 e1000: flush queue whenever can_receive can go from false to true
When the guests replenish the receive ring buffer, the network device
should flush its queue of pending packets.  This is done with
qemu_flush_queued_packets.

e1000's can_receive can go from false to true when RCTL or RDT are
modified.

Reported-by: Luigi Rizzo <rizzo@iet.unipi.it>
Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Cc: Jan Kiszka <jan.kiszka@siemens.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Amos Kong <akong@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit e8b4c680b4)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:18 -05:00
Paolo Bonzini
8e9fdc4a88 net: notify iothread after flushing queue
virtio-net has code to flush the queue and notify the iothread
whenever new receive buffers are added by the guest.  That is
fine, and indeed we need to do the same in all other drivers.
However, notifying the iothread should be work for the network
subsystem.  And since we are at it we can add a little smartness:
if some of the queued packets already could not be delivered,
there is no need to notify the iothread.

Reported-by: Luigi Rizzo <rizzo@iet.unipi.it>
Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Cc: Jan Kiszka <jan.kiszka@siemens.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Amos Kong <akong@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 987a9b4800)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Igor Mitsyanko
ca54dc1e75 arch_init.c: add missing '%' symbols before PRIu64 in debug printfs
'%' symbols were missing in front of PRIu64 macros in DPRINTF() messages in
arch_init.c, this caused compilation warnings when compiled with DEBUG_ARCH_INIT defined.

Signed-off-by: Igor Mitsyanko <i.mitsyanko@samsung.com>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit ef37a699a0)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Stefan Weil
a78cedc09e kvm: Fix warning from static code analysis
Report from smatch:

kvm-all.c:1373 kvm_init(135) warn:
 variable dereferenced before check 's' (see line 1360)

's' cannot by NULL (it was alloced using g_malloc0), so there is no need
to check it here.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit 6d1cc3210c)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Lei Li
59a01f73c3 qapi: Fix enumeration typo error
Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com>
Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
(cherry picked from commit 6932a69b20)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
BALATON Zoltan
c6553fee81 console: Clean up bytes per pixel calculation
Division with round up is the correct way to compute this even if the
only case where division with round down gives incorrect result is
probably 15 bpp. This case was explicitely patched up in one of these
functions but was unhandled in the other. (I'm not sure about setting
16 bpp for the 15bpp case either but I left that there for now.)

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit feadf1a4de)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Stefan Weil
a0d718a395 Spelling fixes in comments and documentation
These wrong spellings were detected by codespell:

* successully -> successfully

* alot -> a lot

* wanna -> want to

* infomation -> information

* occured -> occurred

["also is" -> "is also" and "ressources" -> "resources" suggested by
Peter Maydell <peter.maydell@linaro.org>]

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 0546b8c2f0)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Stefan Weil
34173da021 srp: Don't use QEMU_PACKED for single elements of a structured type
QEMU_PACKED results in a MinGW compiler warning when it is
used for single structure elements:

warning: 'gcc_struct' attribute ignored

Using QEMU_PACKED for the whole structure avoids the compiler warning
without changing the memory layout.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 93d3ad2a80)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Hervé Poussineau
c23314334d slirp: Implement TFTP Blocksize option
This option is described in RFC 1783. As this is only an optional field,
we may ignore it in some situations and handle it in some others.

However, MS Windows 2003 PXE boot client requests a block size of the MTU
(most of the times 1472 bytes), and doesn't work if the option is not
acknowledged (with whatever value).

According to the RFC 1783, we cannot acknowledge the option with a bigger
value than the requested one.

As current implementation is using 512 bytes by block, accept the option
with a value of 512 if the option was specified, and don't acknowledge it
if it is not present or less than 512 bytes.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
(cherry picked from commit 95b1ad7ad8)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Hervé Poussineau
b83f395ba1 slirp: Handle more than 65535 blocks in TFTP transfers
RFC 1350 does not mention block count roll-over. However, a lot of TFTP servers
implement it to be able to transmit big files, so do it also.

Current block size is 512 bytes, so TFTP files were limited to 32 MB.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
(cherry picked from commit 4aa401f39e)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Hervé Poussineau
34f7e690c3 slirp: improve TFTP performance
When transferring a file, keep it open during the whole transfer,
instead of opening/closing it for each block.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
(cherry picked from commit 78be056628)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Stefan Weil
6116adbc0e slirp: Fix error reported by static code analysis
Report from smatch:

slirp/tcp_subr.c:127 tcp_respond(17) error:
 we previously assumed 'tp' could be null (see line 124)

Return if 'tp' is NULL.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
(cherry picked from commit e56afbc54a)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Stefan Weil
3ed791b42d slirp: Remove wrong type casts ins debug statements
The type casts of pointers to long are not allowed
when sizeof(pointer) != sizeof(long).

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
(cherry picked from commit c4d12a743c)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Hans de Goede
2ee160f8e1 uhci: Don't queue up packets after one with the SPD flag set
Don't queue up packets after a packet with the SPD (short packet detect)
flag set. Since we won't know if the packet will actually be short until it
has completed, and if it is short we should stop the queue.

This fixes a miniature photoframe emulating a USB cdrom with the windows
software for it not working.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 72a04d0c17)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Hans de Goede
981e213cf7 usb-redir: Revert usb-redir part of commit 93bfef4c
Commit 93bfef4c6e makes qemu-devices
which report the qemu version string to the guest in some way use a
qemu_get_version function which reports a machine-specific version string.

However usb-redir does not expose the qemu version to the guest, only to
the usbredir-host as part of the initial handshake. This can then be logged
on the usbredir-host side for debugging purposes and is otherwise completely
unused! For debugging purposes it is important to have the real qemu version
in there, rather then the machine-specific version.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 35efba2cc6)

Conflicts:

	hw/usb/redirect.c

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Hans de Goede
d56d7e6ef8 ehci: Walk async schedule before and after migration
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit ceab6f9645)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Hans de Goede
ad2cea3878 ehci: Don't set seen to 0 when removing unseen queue-heads
When removing unseen queue-heads from the async queue list, we should not
set the seen flag to 0, as this may cause them to be removed by
ehci_queues_rip_unused() during the next call to ehci_advance_async_state()
if the timer is late or running at a low frequency.

Note:
1) This *may* have caused the instant unlink / relinks described in commit
   9bc3a3a216

2) Rather then putting more if-s inside ehci_queues_rip_unused, this patch
   instead introduces a new ehci_queues_rip_unseen function.

3) This patch also makes it save to call ehci_queues_rip_unseen() multiple
   times, which gets used in the folluw up patch titled:
   "ehci: Walk async schedule before and after migration"

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 8f5457eb04)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:17 -05:00
Aurelien Jarno
d28ed2ffbb configure: usbredir fixes
usbredir is only used by system emulation, so add the libraries to
libs_softmmu instead of LIBS.

Cc: Michael Tokarev <mjt@tls.msk.ru>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 56ab2ad177)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:16 -05:00
Alon Levy
bffb221775 hw/qxl: tracing fixes
Add two new trace events:
qxl_send_events(int qid, uint32_t events) "%d %d"
qxl_set_guest_bug(int qid) "%d"

Change qxl_io_unexpected_vga_mode parameters to be equivalent to those
of qxl_io_write for easier grouping under a single systemtap probe.

Change d to qxl in one place.

Signed-off-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 917ae08ca1)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:16 -05:00
Dunrong Huang
9cf4af689b block: Don't forget to delete temporary file
The caller would not delete temporary file after failed get_tmp_filename().

Signed-off-by: Dunrong Huang <riegamaths@gmail.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit fe235a06e1)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:16 -05:00
Daniel P. Berrange
f9f552e80b Don't require encryption password for 'qemu-img info' command
The encryption password is only required if I/O is going to be
performed on a disk image. The 'qemu-img info' command merely
reports metadata, so it should not ask for a decryption password

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit f0536bb848)

Conflicts:

	qemu-img.c

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:16 -05:00
Jason Baron
7cf7e305cc ahci: properly reset PxCMD on HBA reset
While testing q35, I found that windows 7 (specifically, windows 7 ultimate
with sp1 x64), wouldn't install because it can't find the cdrom or disk drive.
The failure message is: 'A required cd/dvd device driver is missing. If you
have a driver floppy disk, CD, DVD, or USB flash drive, please insert it now.'
This can also be reproduced on piix by adding an ahci controller, and
observing that windows 7 does not see any devices behind it.

The problem is that when windows issues a HBA reset, qemu does not reset the
individual ports' PxCMD register. Windows 7 then reads back the PxCMD register
and presumably assumes that the ahci controller has already been initialized.
Windows then never sets up the PxIE register to enable interrupts, and thus it
never gets irqs back when it sends ata device inquiry commands.

This change brings qemu into ahci 1.3 specification compliance.

Section 10.4.3 HBA Reset:

"
When GHC.HR is set to '1', GHC.AE, GHC.IE, the IS register, and all port
register fields (except PxFB/PxFBU/PxCLB/PxCLBU) that are not HwInit in the
HBA's register memory space are reset.
"

I've also re-tested Fedora 16 and 17 to verify that they continue to work with
this change.

Signed-off-by: Jason Baron <jbaron@redhat.com>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 2a4f4f34e6)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:16 -05:00
Pavel Hrdina
84a2ca9f90 block: fix block tray status
The tray status should change also if you eject empty block device.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 9ca111544c)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:16 -05:00
Stefan Weil
1c224f0ab3 vdi: Fix warning from clang
ccc-analyzer reports these warnings:

block/vdi.c:704:13: warning: Dereference of null pointer
            bmap[i] = VDI_UNALLOCATED;
            ^
block/vdi.c:702:13: warning: Dereference of null pointer
            bmap[i] = i;
            ^

Moving some code into the if block fixes this.
It also avoids calling function write with 0 bytes of data.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 514f21a5d4)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:16 -05:00
Stefan Weil
1e32a1651a block/curl: Fix wrong free statement
Report from smatch:
block/curl.c:546 curl_close(21) info: redundant null check on s->url calling free()

The check was redundant, and free was also wrong because the memory
was allocated using g_strdup.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 45724d6d02)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:16 -05:00
Stefan Weil
3900d1d992 ide: Fix error messages from static code analysis (no real error)
Report from smatch:
hw/ide/core.c:1472 ide_exec_cmd(423) error: buffer overflow 'smart_attributes' 8 <= 29
hw/ide/core.c:1474 ide_exec_cmd(425) error: buffer overflow 'smart_attributes' 8 <= 29
hw/ide/core.c:1475 ide_exec_cmd(426) error: buffer overflow 'smart_attributes' 8 <= 29
...

The upper limit of 30 was never reached because both for loops terminated
when 'smart_attributes' reached end of list, so there was no real buffer
overflow.

Nevertheless, changing the code not only fixes the error report, but also
reduces the size of smart_attributes and simplifies the for loops.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 1e53537fda)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:16 -05:00
MORITA Kazutaka
1fce4135f3 sheepdog: fix savevm and loadvm
This patch sets data to be sent to Sheepdog correctly and fixes savevm
and loadvm operations on a Sheepdog image.

Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 1f7a48de44)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:16 -05:00
Hans de Goede
349b4e9070 ehci: Don't process too much frames in 1 timer tick (v2)
The Linux ehci isoc scheduling code fills the entire schedule ahead of
time minus 80 frames. If we make a large jump in where we are in the
schedule, ie 40 frames, then the scheduler all of a sudden will only have
40 frames left to work in, causing it to fail packet submissions
with error -27 (-EFBIG).

Changes in v2:
-Don't hardcode a maximum number of frames to process in one tick, instead:
 -Process a minimum number of frames to ensure we do eventually catch up
 -Stop (after the minimum number) when the guest has requested an irq

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 8f74ed1e43)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:16 -05:00
Hans de Goede
29ecaa26a8 ehci: Fix interrupts stopping when Interrupt Threshold Control is 8
If Interrupt Threshold Control is 8 or a multiple of 8, then
s->usbsts_frindex can become exactly 0x4000, at which point
(s->usbsts_frindex > s->frindex) will never become true, as
s->usbsts_frindex will not be lowered / reset in this case.

This patch fixes this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit ffa1f2e088)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:16 -05:00
Gerd Hoffmann
1f97f6c9fe ehci: switch to new-style memory ops
Also register different memory regions for capabilities,
operational registers and port status registers.  Create
separate tracepoints for operational regs and port status
regs.  Ditch a bunch of sanity checks because the memory
core will do this for us now.

Offloading the byte, word and dword access handling to the
memory core also has the side effect of fixing ehci register
access on bigendian hosts.

Cc: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 3e4f910c8d)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:16 -05:00
Uri Lublin
9a5a94de58 qxl: better cleanup for surface destroy
Add back a call to qxl_spice_destroy_surface_wait_complete() in qxl_spice_destroy_surface_wait(),
that was removed by commit c480bb7da4

It is needed to complete surface-removal cleanup, for non async.
For async, qxl_spice_destroy_surface_wait_complete is called upon operation completion.

Signed-off-by: Uri Lublin <uril@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 753b8b0d77)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:15 -05:00
Gerd Hoffmann
462ff6fda1 usb-host: allow emulated (non-async) control requests without USBPacket
xhci needs this for USB_REQ_SET_ADDRESS due to the way
usb addressing is handled by the xhci hardware.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 63587e3135)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:15 -05:00
Dunrong Huang
b26859ab18 qxl: dont update invalid area
This patch fixes the following error:

$ ~/usr/bin/qemu-system-x86_64 -enable-kvm -m 1024 -spice port=5900,disable-ticketing -vga qxl -cdrom ~/Images/linuxmint-13-mate-dvd-32bit.iso
(/home/mathslinux/usr/bin/qemu-system-x86_64:10068): SpiceWorker-CRITICAL **: red_worker.c:4599:red_update_area: condition `area->left >= 0 && area->top >= 0 && area->left < area->right && area->top < area->bottom' failed
Aborted

spice server terminates QEMU process if we pass invalid area to it,
so dont update those invalid areas.

Signed-off-by: Dunrong Huang <riegamaths@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit ccc2960d65)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:15 -05:00
Gerd Hoffmann
03c0342cb8 xhci: allow bytewise capability register reads
Some guests need this according to
Alejandro Martinez Ruiz <alex@securiforest.com>

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 6ee021d410)

Conflicts:

	hw/usb/hcd-xhci.c

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:15 -05:00
Gerd Hoffmann
23ba9d4838 xhci: fix runtime write tracepoint
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 8e9f18b6db)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:15 -05:00
Gerd Hoffmann
640bda8df5 xhci: drop buffering
This patch splits the xhci_xfer_data function into three.
The xhci_xfer_data function used to do does two things:

  (1) copy transfer data between guest memory and a temporary buffer.
  (2) report transfer results to the guest using events.

Now we three functions to handle this:

  (1) xhci_xfer_map creates a scatter list for the transfer and
      uses that (instead of the temporary buffer) to build a
      USBPacket.
  (2) xhci_xfer_unmap undoes the mapping.
  (3) xhci_xfer_report sends out events.

The patch also fixes reporting of transaction errors which must be
reported unconditinally, not only in case the guest asks for it
using the ISP flag.

[ v2: fix warning ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit d5a15814b4)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:15 -05:00
Gerd Hoffmann
64022e9d58 xhci: rip out background transfer code
original xhci code (the one which used libusb directly) used to use
'background transfers' for iso streams.  In upstream qemu the iso
stream buffering is handled by usb-host & usb-redir, so we will
never ever need this.  It has been left in as reference, but is dead
code anyway.  Rip it out.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 331e9406f1)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:15 -05:00
Gerd Hoffmann
3e3750e10a usb-audio: fix usb version
usb-audio is a full speed (1.1) device,
but bcdUSB claims it is usb 2.0.  Fix it.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 2bbd086c41)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:15 -05:00
Samuel Thibault
fbcb89ddc9 Better name usb braille device
Windows users need to know that they have to use the Baum driver to make
the qemu braille device work.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 2964cd9bfa)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:15 -05:00
Hans de Goede
22ba7a7488 usb-redir: Return babble when getting more bulk data then requested
Babble is the appropriate error in this case (rather then signalling a stall).

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 2979a36183)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:15 -05:00
Hans de Goede
636071de92 usb-redir: Move to core packet id and queue handling
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit de550a6afb)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:15 -05:00
Hans de Goede
55a2f465b9 usb-redir: Get rid of unused async-struct dev member
This is a preparation patch for completely getting rid of the async-packet
struct in usb-redir, instead relying on the (new) per ep queues in the
qemu usb core.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 206e7f20fe)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:15 -05:00
Hans de Goede
aa57b628e0 usb-redir: Get rid of local shadow copy of packet headers
The shadow copy only serves as an extra check (besides the packet-id) to
ensure the packet we get back is a reply to the packet we think it is.

This check has never triggered in all the time usb-redir is in use now,
and since the verified data in the returned packet-header is not used
otherwise, removing the check does not open any possibilities for the
usbredirhost to confuse us.

This is a preparation patch for completely getting rid of the async-packet
struct in usb-redir, instead relying on the (new) per ep queues in the
qemu usb core.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 104981d52b)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:15 -05:00
Hans de Goede
57eae744d4 usb-redir: Get rid of async-struct get member
This is a preparation patch for completely getting rid of the async-packet
struct in usb-redir, instead relying on the (new) per ep queues in the
qemu usb core.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit cb897117cd)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:14 -05:00
Hans de Goede
14ecfb09fa usb-redir: Don't delay handling of open events to a bottom half
There is no need for this, and doing so means that a backend trying to
write immediately after an open event will see qemu_chr_be_can_write
returning 0, which not all backends handle well as there is no wakeup
mechanism to detect when the frontend does become writable.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit ed9873bfbf)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:14 -05:00
Hans de Goede
1d5ba9a6a8 usb-redir: Never return USB_RET_NAK for async handled packets
USB_RET_NAK is not a valid response for async handled packets (and will
trigger an assert as such).

Also drop the warning when receiving a status of cancelled for packets not
cancelled by qemu itself, this can happen when a device gets unredirected
by the usbredir-host while transfers are pending.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 181133404f)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:14 -05:00
Hans de Goede
77c3d59256 ehci: Correct a comment in fetchqtd packet processing
Since my previous comment said "Should never happen", I tried changing the
next line to an assert(0), which did not go well, which as the new comments
explains is logical if you think about it for a moment.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit cf1f81691d)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:14 -05:00
Hans de Goede
e2ab86fe2d ehci: Handle USB_RET_PROCERR in ehci_fill_queue
USB_RET_PROCERR can be triggered by the guest (by for example requesting more
then BUFFSIZE bytes), so don't assert on it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit eff6dce79b)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:14 -05:00
Hans de Goede
2f7ba4731b ehci: Fix memory leak in handling of NAK-ed packets
Currently each time we try to execute a NAK-ed packet we redo
ehci_init_transfer, and usb_packet_map, re-allocing (without freeing) the
sg list every time.

This patch fixes this, it does this by introducing another async state, so
that we also properly cleanup a NAK-ed packet on cancel.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit ef5b234477)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:14 -05:00
Hans de Goede
0154d330c7 ehci: Add some additional ehci_trace_guest_bug() calls
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 3a8ca08e01)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:14 -05:00
Gerd Hoffmann
d294ad6323 ehci: add doorbell trace events
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 1defcbd1e8)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:14 -05:00
Gerd Hoffmann
62fc5e6983 ehci: trace guest bugs
make qemu_queue_{cancel,reset} return the number of packets released,
so the caller can figure whenever there have been active packets even
though there shouldn't have been any.  Add tracepoint to log this.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 5c514681ab)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:14 -05:00
Gerd Hoffmann
4a6cdb4807 ehci: check for EHCI_ASYNC_FINISHED first in ehci_free_packet
Otherwise we'll see the packet free twice in the trace log even though
it actually happens only once.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 616789cde2)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:14 -05:00
Hans de Goede
a8cf10d5d6 ehci: Properly report completed but not yet processed packets to the guest
Reported packets which have completed before being cancelled as such to the
host. Note that the new code path this patch adds is untested since it I've
been unable to actually trigger the race which needs this code path.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 4b63a0df3b)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:14 -05:00
Hans de Goede
307fea863a ehci: Properly cleanup packets on cancel
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 0e7953525f)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:14 -05:00
Hans de Goede
c15d61b252 ehci: Update copyright headers to reflect recent work
Update copyright headers to reflect all the work Gerd and I have been doing
on the EHCI emulation.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 522079dd44)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:14 -05:00
Hans de Goede
712fc762a6 ehci: Validate qh is not changed unexpectedly by the guest
-combine the qh check with the check for devaddr changes
-also ensure that p gets set to NULL when the queue gets cancelled on
 devaddr change, which was not done properly before this patch

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit dafe31fc2a)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:13 -05:00
Hans de Goede
a37d5e521a Revert "ehci: don't flush cache on doorbell rings."
This reverts commit 9bc3a3a216, which got
added to fix an issue where the real, underlying cause was not stopping
the ep queue on an error.

Now that the underlying cause is fixed by the "usb: Halt ep queue and
cancel pending packets on a packet error" patch, the "don't flush" fix
is no longer needed.

Not only is it not needed, it causes us to see cancellations (unlinks)
done by the Linux EHCI driver too late, which in combination with the new
usb-core packet-id generation where qtd addresses are used as ids, causes
duplicate ids for in flight packets.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
(cherry picked from commit 66f092d256)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:13 -05:00
Hans de Goede
d6e508d3a5 usb-core: Allow the first packet of a pipelined ep to complete immediately
This can happen with usb-redir live-migration when the packet gets re-queued
after the migration and the original queuing from the migration source side
has already finished.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 9c1f67654a)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:13 -05:00
Hans de Goede
d780116ab0 usb-core: Add a usb_ep_find_packet_by_id() helper function
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit c13a9e6136)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:13 -05:00
Hans de Goede
597330bd8d usb-core: Don't set packet state to complete on a nak
This way the hcd can re-use the same packet to retry without needing
to re-init it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit cc40997489)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:13 -05:00
Hans de Goede
4ebbf3229a usb: controllers do not need to check for babble themselves
If an (emulated) usb-device tries to write more data to a packet then
its iov len, this will trigger an assert in usb_packet_copy(), and if
a driver somehow circumvents that check and writes more data to the
iov then there is space, we have a much bigger problem then not correctly
reporting babble to the guest.

In practice babble will only happen with (real) redirected devices, and there
both the usb-host os and the qemu usb-device code already check for it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 45b339b18c)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:13 -05:00
Daniel P. Berrange
b5701820f8 Add ability to force enable/disable of tools build
The qemu-img, qemu-nbd and qemu-io tools are built conditionally
based on whether any softmmu target is enabled. These are useful
self-contained tools which can be used in many other scenarios.
Add new --enable-tools/--disable-tools args to configure to allow
the user to explicitly turn on / off their build. The default
behaviour is now to build these tools are all times, regardless
of whether any softmmu target is enabled

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 4b1c11fd20)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-11 21:44:13 -05:00
Anthony Liguori
5af6b07ab0 socket: don't attempt to reconnect a TCP socket in server mode
Commit c3767ed0eb introduced a possible SEGV when
using a socket chardev with server=on because it assumes that all TCP sockets
are in client mode.

This patch adds a check to only reconnect when in client mode.

Cc: Lei Li <lilei@linux.vnet.ibm.com>
Reported-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 455aa1e081)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:30 -05:00
Michael Tokarev
82645b9e93 use --libexecdir instead of ignoring it first and reinventing it later
Commit 7b93fadf3a "Add basic version
of bridge helper" put the bridge helper executable into a fixed
${prefix}/libexec/ location, instead of using ${libexecdir} for
this.  At the same time, --libexecdir is being happily ignored
by ./configure.  Even more, the same patch sets unused $libexecdir
variable in the generated config-host.mak, and uses fixed string
(\${prefix}/libexecdir) for the bridge helper binary.

Fix this braindamage by introducing $libexecdir variable, using
it for the bridge helper binary, and recognizing --libexecdir.

This patch is applicable to stable-1.1.

Reviewed-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Corey Bryant <coreyb@linux.vnet.ibm.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Cc: Corey Bryant <coreyb@linux.vnet.ibm.com>
Cc: Richa Marwaha <rmarwah@linux.vnet.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 8bf188aa18)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:30 -05:00
Stefan Weil
b750d22466 hw/mcf5206: Fix buffer overflow for MBAR read / write
Report from smatch:

mcf5206.c:384 m5206_mbar_readb(7) error: buffer overflow 'm5206_mbar_width' 128 <= 128
mcf5206.c:403 m5206_mbar_readw(8) error: buffer overflow 'm5206_mbar_width' 128 <= 128
mcf5206.c:427 m5206_mbar_readl(8) error: buffer overflow 'm5206_mbar_width' 128 <= 128
mcf5206.c:451 m5206_mbar_writeb(9) error: buffer overflow 'm5206_mbar_width' 128 <= 128
mcf5206.c:475 m5206_mbar_writew(9) error: buffer overflow 'm5206_mbar_width' 128 <= 128
mcf5206.c:503 m5206_mbar_writel(9) error: buffer overflow 'm5206_mbar_width' 128 <= 128

m5206_mbar_width has 0x80 elements and supports 0 <= offset < 0x200.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit a32354e206)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:30 -05:00
Stefan Weil
bd4dba6658 hw/wm8750: Fix potential buffer overflow
Report from smatch:

hw/wm8750.c:369 wm8750_tx(12) error: buffer overflow 's->i2c_data' 2 <= 2

It looks like the preprocessor statements were simply misplaced.

Replace also __FUNCTION__ by __func__ to please checkpatch.pl.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 149eeb5fe5)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:30 -05:00
Christian Borntraeger
7566759fd5 qemu: Use valgrind annotations to mark kvm guest memory as defined
valgrind with kvm produces a big amount of false positives regarding
"Conditional jump or move depends on uninitialised value(s)". This
happens because the guest memory is allocated with qemu_vmalloc which
boils down posix_memalign etc. This function is (correctly) considered
by valgrind as returning undefined memory.

Since valgrind is based on jitting code, it will not be able to see
changes made by the guest to guest memory if this is done by KVM_RUN,
thus keeping most of the guest memory undefined.

Now lots of places in qemu will then use guest memory to change behaviour.
To avoid the flood of these messages, lets declare the whole guest
memory as defined. This will reduce the noise and allows us to see real
problems.

In the future we might want to make this conditional, since there
is actually something that we can use those false positives for:
These messages will point to code that depends on guest memory, so
we can use these backtraces to actually make an audit that is focussed
only at those code places. For normal development we dont want to
see those messages, though.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
(cherry picked from commit 62fe83318d)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:30 -05:00
Jan Kiszka
47b11da1e9 musicpal: Fix flash mapping
The old arithmetic assumed 32 physical address bits which is no longer
true for ARM since 3cc0cd61f4.

Signed-off-by: Jan Kiszka <jan.kiszka@web.de>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit 0c267217ca)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:30 -05:00
Fabien Chouteau
2ecd8831e0 Add MAINTAINERS entry for leon3
Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit ce6c760c37)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:30 -05:00
Maciej W. Rozycki
27aae39fa0 MIPS/user: Fix reset CPU state initialization
This change updates the CPU reset sequence to use a common piece of code
that figures out CPU state flags, fixing the problem with MIPS_HFLAG_COP1X
not being set where applicable that causes floating-point MADD family
instructions (and other instructions from the MIPS IV FP subset) to trap.

 As compute_hflags is now shared between op_helper.c and translate.c, the
function is now moved to a common header.  There are no changes to this
function.

 The problem was seen with the 24Kf MIPS32r2 processor in user emulation.
The new approach prevents system and user emulation from diverging -- all
the hflags state is initialized in one place now.

Signed-off-by: Maciej W. Rozycki <macro@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 03e6e50177)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:30 -05:00
Aurelien Jarno
635cc81bf9 lan9118: fix multicast filtering
The lan9118 emulation tries to compute the multicast index by calling
directly the crc32() function from zlib, but fails to get the correct
result.

Use the common compute_mcast_idx() function instead, which gives the
correct result. This fixes IPv6 support.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 449bc90e1f)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:30 -05:00
Henning Schild
4de6467cbc fix entry pointer for ELF kernels loaded with -kernel option
Find a hopefully proper patch attached. Take it or leave it.

Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Henning Schild <henning@hennsch.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 7e9c7ffe9f)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:29 -05:00
Jason Baron
4382057785 pcie_aer: clear cmask for Advanced Error Interrupt Message Number
The Advanced Error Interrupt Message Number (bits 31:27 of the Root
Error Status Register) is updated when the number of msi messages assigned to a
device changes. Migration of windows 7 on q35 chipset failed because the check
in get_pci_config_device() fails due to cmask being set on these bits. Its valid
to update these bits and we must restore this state across migration.

Signed-off-by: Jason Baron <jbaron@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 0e180d9c8a)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:29 -05:00
Jason Baron
6ac46e3216 pcie: drop version_id field for live migration
While testing q35 live migration, I found that the migration would abort with
the following error: "Unknown savevm section type 76".

The error is due to this check failing in 'vmstate_load_state()':

    while(field->name) {
        if ((field->field_exists &&
             field->field_exists(opaque, version_id)) ||
            (!field->field_exists &&
             field->version_id <= version_id)) {

The VMSTATE_PCIE_DEVICE() currently has a 'version_id' set to 2. However,
'version_id' in the above check is 1. And thus we fail to load the pcie device
field. Further the code returns to 'qemu_loadvm_state()' which produces the
error that I saw.

I'm proposing to fix this by simply dropping the 'version_id' field from
VMSTATE_PCIE_DEVICE(). VMSTATE_PCI_DEVICE() defines no such field and further
the vmstate_pcie_device that VMSTATE_PCI_DEVICE() refers to is already
versioned. Thus, any versioning issues could be detected at the vmsd level.

Taking a step back, I think that the 'field->version_id' should be compared
against a saved version number for the field not the 'version_id'. Futhermore,
once vmstate_load_state() is called recursively on another vmsd, the check of:

    if (version_id > vmsd->version_id) {
        return -EINVAL;
    }

Will never fail since version_id is always equal to vmsd->version_id. So I'm
wondering why we aren't storing the vmsd version id of the source in the
migration stream?

This patch also renames the 'name' field of vmstate_pcie_device from:
PCIDevice -> PCIEDevice to differentiate it from vmstate_pci_device.

Signed-off-by: Jason Baron <jbaron@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 1de5345927)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:29 -05:00
Stefan Weil
3aec24d195 json-parser: Fix potential NULL pointer segfault
Report from smatch:
json-parser.c:474 parse_object(62) error: potential null derefence 'dict'.
json-parser.c:553 parse_array(75) error: potential null derefence 'list'.

Label 'out' in json-parser.c can be called with list == NULL
which is passed to QDECREF.

Modify QDECREF to handle a NULL argument (inline function qobject_decref
already handles them, too).

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
(cherry picked from commit 149474c934)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:29 -05:00
Stefan Weil
122b92d90a qapi: Fix potential NULL pointer segfault
Report from smatch:

qapi-visit.c:1640 visit_type_BlockdevAction(8) error:
 we previously assumed 'obj' could be null (see line 1639)
qapi-visit.c:2432 visit_type_NetClientOptions(8) error:
 we previously assumed 'obj' could be null (see line 2431)

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
(cherry picked from commit 227ccf6bff)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:29 -05:00
Amos Kong
23086b2054 fix doc of using raw values with sendkey
(qemu) sendkey a
(qemu) sendkey 0x1e
(qemu) sendkey #0x1e
 unknown key: '#0x1e'

The last command doesn't work, '#' is not requested before
raw values, and the raw value in decimal format is not supported.

Signed-off-by: Amos Kong <akong@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
(cherry picked from commit 886cc706ce)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:29 -05:00
Alon Levy
ea4c86551d configure: print spice-protocol and spice-server versions
Signed-off-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 2e0e3c399a)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:29 -05:00
Alon Levy
b75c710575 qxl: add QXL_IO_MONITORS_CONFIG_ASYNC
Revision bumped to 4 for new IO support, enabled for spice-server >=
0.11.1. New io enabled if revision is 4. Revision can be set to 4.

[ kraxel: 3 continues to be the default revision.  Once we have a new
          stable spice-server release and the qemu patches to enable
          the new bits merged we'll go flip the switch and make rev4
          the default ]

This io calls the corresponding new spice api
spice_qxl_monitors_config_async to let spice-server read a new guest set
monitors config and notify the client.

On migration reissue spice_qxl_monitors_config_async.

RHBZ: 770842

Signed-off-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

fixup

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 020af1c45f)

Conflicts:

	hw/qxl.c

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:29 -05:00
Alon Levy
5b7582af06 qxl/update_area_io: guest_bug on invalid parameters
Signed-off-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 511b13e2c9)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:29 -05:00
Yonit Halperin
615198836c spice: increase the verbosity of spice section in "qemu --help"
Added all spice options to the help string. This can be used by libvirt
to determine which spice related features are supported by qemu.

Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 27af778828)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:29 -05:00
Yonit Halperin
7908e4a388 spice: adding seamless-migration option to the command line
The seamless-migration flag is required in order to identify
whether libvirt supports the new QEVENT_SPICE_MIGRATE_COMPLETED or not
(by default the flag is off).
New libvirt versions that wait for QEVENT_SPICE_MIGRATE_COMPLETED should turn on this flag.
When this flag is off, spice fallbacks to its old migration method, which
can result in data loss.

Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 8c9570530c)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:29 -05:00
Yonit Halperin
38a01d68c6 spice: add 'migrated' flag to spice info
The flag is 'true' when spice migration has completed on the src side.
It is needed for a case where libvirt dies before migration completes
and it misses the event QEVENT_SPICE_MIGRATE_COMPLETED.
When libvirt is restored and queries the migration status, it also needs
to query spice and check if its migration has completed.

Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 61c4efe2cb)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:29 -05:00
Yonit Halperin
986b9a1a2a spice migration: add QEVENT_SPICE_MIGRATE_COMPLETED
When migrating, libvirt queries the migration status, and upon migration
completions, it closes the migration src. On the other hand, when
migration is completed, spice transfers data from the src to destination
via the client. This data is required for keeping the spice session
after migration, without suffering from data loss and inconsistencies.
In order to allow this data transfer, we add QEVENT for signaling
libvirt that spice migration has completed, and libvirt needs to wait
for this event before quitting the src process.

Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 2fdd16e239)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:28 -05:00
Yonit Halperin
25bc2251eb spice: notify on vm state change only via spice_server_vm_start/stop
QXLWorker->start/stop are deprecated since spice-server 0.11.2

Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 71d388d420)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:28 -05:00
Yonit Halperin
fc24f3bd2e spice: notify spice server on vm start/stop
Spice server needs to know about the vm state in order to prevent
attempts to write to devices when they are stopped, mainly during
the non-live stage of migration.
Instead, spice will take care of restoring this writes, on the migration
target side, after migration completes.

Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit f5bb039c6d)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:28 -05:00
Christophe Fergeau
3c82758f04 spice: abort on invalid streaming cmdline params
When parsing its command line parameters, spice aborts when it
finds unexpected values, except for the 'streaming-video' option.
This happens because the parsing of the parameters for this option
is done using the 'name2enum' helper, which does not error out
on unknown values. Using the 'parse_name' helper makes sure we
error out in this case. Looking at git history, the use of
'name2enum' instead of 'parse_name' seems to have been an oversight,
so let's change to that now.

Fixes rhbz#831708

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 835cab85ad)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:58:28 -05:00
Stefan Weil
7fd494086b tci: Fix for AREG0 free mode
Support for helper functions with 5 arguments was missing
in the code generator and in the interpreter.

There is no need to pass the constant TCG_AREG0 from the
code generator to the interpreter. Remove that code for
the INDEX_op_qemu_st* opcodes.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:11 -05:00
Stefan Weil
e46258fb50 tcg: Fix MAX_OPC_PARAM_IARGS
DEF_HELPER_FLAGS_5 was added some time ago without adjusting
MAX_OPC_PARAM_IARGS.

Fixing the definition becomes more important as QEMU is using
an increasing number of helper functions called with 5 arguments.

Add also a comment to avoid future problems when DEF_HELPER_FLAGS_6
will be added.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:11 -05:00
Aurelien Jarno
c90a8840b4 tcg/i386: fix build with -march < i686
The movcond_i32 op has to be protected with TCG_TARGET_HAS_movcond_i32
to fix the build with -march < i686.

Thanks to Richard Henderson for the hint.

Reported-by: Alex Barcelo <abarcelo@ac.upc.edu>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:11 -05:00
Richard Henderson
e1312991ed tcg: Adjust descriptions of *cond opcodes
The README file documented the operand ordering of the tcg_gen_*
functions.  Since we're documenting opcodes here, use the true
operand ordering.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Cc: malc <av1474@comtv.ru>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:11 -05:00
Aurelien Jarno
6c975d03a2 tcg/mips: fix MIPS32(R2) detection
Fix the MIPS32(R2) cpu detection so that it also works with
-march=octeon. Thanks to Andrew Pinski for the hint.

Cc: Andrew Pinski <apinski@cavium.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:11 -05:00
Richard Henderson
df6502fac5 target-alpha: Initialize env->cpu_model_str
Save the cpu_model_str so that we have a non-null value when
creating a new cpu during clone.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:11 -05:00
Richard Henderson
fef28a4336 tcg-sparc: Preserve branch destinations during retranslation
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:11 -05:00
Richard Henderson
38df9027ce tcg-sparc: Fix and enable direct TB chaining.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Richard Henderson
ba8b16fac5 tcg-sparc: Add %g/%o registers to alloc_order
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Richard Henderson
39cbcb4b45 tcg-sparc: Use defines for temporaries.
And change from %i4/%i5 to %g1/%o7 to remove a v8plus fixme.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Richard Henderson
db0cfd14ba tcg-sparc: Mask shift immediates to avoid illegal insns.
The xtensa-test image generates a sra_i32 with count 0x40.
Whether this is accident of tcg constant propagation or
originating directly from the instruction stream is immaterial.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Richard Henderson
5c7199f164 tcg-sparc: Clean up cruft stemming from attempts to use global registers.
Don't use -ffixed-gN.  Don't link statically.  Don't save/restore
AREG0 around calls.  Don't allocate space on the stack for AREG0 save.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Richard Henderson
60db655378 tcg-sparc: Change AREG0 in generated code to %i0.
We can now move the TCG variable from %g[56] to a call-preserved
windowed register.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Richard Henderson
757ee3f9e2 tcg-sparc: Support GUEST_BASE.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Richard Henderson
e85ec822e9 tcg-sparc: Fix qemu_ld/st to handle 32-bit host.
At the same time, split out the tlb load logic to a new function.
Fixes the cases of two data registers and two address registers.
Fixes the signature of, and adds missing, qemu_ld/st opcodes.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Richard Henderson
181dd0b27c tcg-sparc: Assume v9 cpu always, i.e. force v8plus in 32-bit mode.
Current code doesn't actually work in 32-bit mode at all.  Since
no one really noticed, drop the complication of v7 and v8 cpus.
Eliminate the --sparc_cpu configure option and standardize macro
testing on TCG_TARGET_REG_BITS / HOST_LONG_BITS

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Richard Henderson
e1784a4cbd tcg-sparc: Don't MAP_FIXED on top of the program
The address we pick in sparc64.ld is also 0x60000000, so doing a fixed map
on top of that is guaranteed to blow up.  Choosing 0x40000000 is exactly
right for the max of code_gen_buffer_size set below.

No need to ever use MAP_FIXED.  While getting our desired address helps
optimize the generated code, we won't fail if we don't get it.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Richard Henderson
e183eb99fa tcg-sparc: Fix ADDX opcode.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Richard Henderson
ee13de2853 tcg-sparc: Hack in qemu_ld/st64 for 32-bit.
Not actually implemented, but at least we avoid the tcg assert at startup.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
malc
6164c1274e tcg/ppc32: Implement movcond32
Thanks to Richard Henderson

Signed-off-by: malc <av1474@comtv.ru>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Stefan Weil
a48028b8e9 w64: Fix TCG helper functions with 5 arguments
TCG uses 6 registers for function arguments on 64 bit Linux hosts,
but only 4 registers on W64 hosts.

Commit 2999a0b200 increased the number
of arguments for some important helper functions from 4 to 5
which triggered a bug for W64 hosts: QEMU aborts when executing
helper_lcall_real in the guest's BIOS because function
tcg_target_get_call_iarg_regs_count always returned 6.

As W64 has only 4 registers for arguments, the 5th argument must be
passed on the stack using a correct stack offset.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Max Filippov
5096a7c7d8 tcg/README: document tcg_gen_goto_tb restrictions
See
http://lists.nongnu.org/archive/html/qemu-devel/2012-09/msg03196.html
for the whole story.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Aurelien Jarno
2e1d09263b tcg/optimize: add constant folding for deposit
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Aurelien Jarno
ffc1c56815 tcg: remove #ifdef #endif around TCGOpcode tests
Commit 25c4d9cc changed all TCGOpcode enums to be available, so we don't
need to #ifdef #endif the one that are available only on some targets.
This makes the code easier to read.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Aurelien Jarno
cfca711212 tcg/optimize: prefer the "op a, a, b" form for commutative ops
The "op a, a, b" form is better handled on non-RISC host than the "op
a, b, a" form, so swap the arguments to this form when possible, and
when b is not a constant.

This reduces the number of generated instructions by a tiny bit.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Aurelien Jarno
26adaf07da tcg/optimize: further optimize brcond/movcond/setcond
When both argument of brcond/movcond/setcond are the same or when one
of the two values is a constant equal to zero, it's possible to do
further optimizations.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:10 -05:00
Aurelien Jarno
f4643451e9 tcg/optimize: optimize "op r, a, a => movi r, 0"
Now that it's possible to detect copies, we can optimize the case
the "op r, a, a => movi r, 0". This helps in the computation of
overflow flags when one of the two args is 0.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
d3b9fb75c6 tcg/optimize: optimize "op r, a, a => mov r, a"
Now that we can easily detect all copies, we can optimize the
"op r, a, a => mov r, a" case a bit more.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
6599e3faae tcg/optimize: do copy propagation for all operations
It is possible to due copy propagation for all operations, even the one
that have side effects or clobber arguments (it only concerns input
arguments). That said, the call operation should be handled differently
due to the variable number of arguments.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
a17f24e08d tcg/optimize: rework copy progagation
The copy propagation pass tries to keep track what is a copy of what
and what has copy of what, and in addition it keep a circular list of
of all the copies. Unfortunately this doesn't fully work: a mov from
a temp which has a state "COPY" changed it into a state "HAS_COPY".
Later when this temp is used again, it is considered has not having
copy and thus no propagation is done.

This patch fixes that by removing the hiearchy between copies, and thus
only keeping a "COPY" state both meaning "is a copy" and "has a copy".
The decision of which copy to use is deferred to the actual temp
replacement. At this stage there is not one best choice to do, but only
better choices than others. For doing the best choice the operation
would have to be parsed in reversed to know if a temp is going to be
used later or not. That what is done by the liveness analysis. At this
stage it is known that globals will be always live, that local temps
will be dead at the end of the translation block, and that the temps
will be dead at the end of the basic block. This means that this stage
should try to replace temps by local temps or globals and local temps
by globals.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
a4c701ee76 tcg/optimize: check types in copy propagation
The copy propagation doesn't check the types of the temps during copy
propagation. However TCG is using the mov_i32 for the i64 to i32
conversion and thus the two are not equivalent.

With this patch tcg_opt_gen_mov() doesn't consider two temps of
different type as copies anymore.

So far it seems the optimization was not aggressive enough to trigger
this bug, but it will be triggered later in this series once the copy
propagation is improved.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
ad797145ae tcg/optimize: remove TCG_TEMP_ANY
TCG_TEMP_ANY has no different meaning than TCG_TEMP_UNDEF, so use
the later instead.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
7ef9bee924 tcg/mips: implement movcond op on MIPS32R2
movcond operation can be implemented on MIPS32 Release 2 using the MOVN,
MOVZ, SLT and SLTU instructions.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
6d82e71b6a tcg/mips: implement deposit op on MIPS32R2
deposit operations can be optimized on MIPS32 Release 2 using the INS
instruction.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
a8067da5d1 tcg/mips: implement rotl/rotr ops on MIPS32R2
rotr operations can be optimized on MIPS32 Release 2 using the ROTR and
ROTRV instructions. Also implemented rotl operations by subtracting the
shift from 32.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
3b63392482 tcg/mips: optimize bswap{16,16s,32} on MIPS32R2
bswap operations can be optimized on MIPS32 Release 2 using the ROTR,
WSBH and SEH instructions. We can't use the non-R2 code to implement the
ops due to registers constraints, so don't define the corresponding
TCG_TARGET_HAS_bswap* values.

Also bswap16* operations are supposed to be called with the 16 high bits
zeroed. This is the case everywhere (including for TCG by definition)
except when called from the store helper. Remove the AND instructions from
bswap16* and move it there.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
86b4f7ca05 tcg/mips: optimize brcond arg, 0
MIPS has some conditional branch instructions when comparing with zero.
Use them.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
adf89e7483 tcg/mips: use stack for TCG temps
Use stack instead of temp_buf array in CPUState for TCG
temps.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
8193cdd0d0 tcg/mips: don't use global pointer
Don't use the global pointer in TCG, in case helpers try access global
variables.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
f25f0d7751 tcg/mips: use TCGArg or TCGReg instead of int
Instead of int, use the correct TCGArg and TCGReg type: TCGReg when
representing a TCG target register, TCGArg when representing the latter
or a constant.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
b7505cfd52 tcg/mips: kill warnings in user mode
Recent versions of GCC emit warnings when compiling user mode targets.
Kill them by reordering a bit the #ifdef.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
df3e097e21 tcg-mips: fix wrong usage of 'Z' constraint
The 'Z' constraint has been introduced to map the zero register. However
when the op also accept a constant, there is no point to accept the zero
register in addition.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Richard Henderson
707eee12fd tcg-hppa: Fix broken load/store helpers
The CONFIG_TCG_PASS_AREG0 code for calling ld/st helpers
was not respecting the ABI requirement for 64-bit values
being aligned in registers.

Mirror the ARM port in use of helper functions to marshal
arguments into the correct registers.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Richard Henderson
fb1d48edb6 tcg-hppa: Fix brcond2 and setcond2
Neither of these functions were performing double-word
compares properly.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Richard Henderson
4c8f62d388 tcg: Fix !USE_DIRECT_JUMP
Commit 6375e09e changed the type of TranslationBlock.tb_next,
but failed to change the type of TCGContext.tb_next.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Aurelien Jarno
15658ad01b gdbstub/sh4: fix build with USE_SOFTFLOAT_STRUCT_TYPES
We have to use different type to access float values when
USE_SOFTFLOAT_STRUCT_TYPES is defined.

Rework SH4 version of cpu_gdb_{read,write}_register() using
a single case, and fixing the coding style. Use ldll_p() and
stfl_p() to access float values.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Richard Henderson
1d465a94ad tcg: Optimize two-address commutative operations
While swapping constants to the second operand, swap
sources matching destinations to the first operand.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Richard Henderson
b5b6bb16b9 tcg: Optimize movcond for constant comparisons
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:09 -05:00
Richard Henderson
52080f688b tcg-i386: Implement movcond
Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Richard Henderson
72bdbb7f46 target-alpha: Use movcond
For proper cmov insns, as well as the non-goto-tb case
of conditional branch.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Richard Henderson
6314cc0c73 tcg: Introduce movcond
Implemented with setcond if the target does not provide
the optional opcode.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Max Filippov
cc10061717 target-xtensa: don't emit extra tcg_gen_goto_tb
Unconditional gen_check_loop_end at the end of disas_xtensa_insn
can emit tcg_gen_goto_tb with slot id already used in the TB (e.g. when
TB ends at LEND with a branch).

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: malc <av1474@comtv.ru>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Max Filippov
44219e7df2 target-xtensa: fix extui shift amount
extui opcode only uses lowermost op1 bit for sa4.

Reported-by: malc <av1474@comtv.ru>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: malc <av1474@comtv.ru>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Aurelien Jarno
5b681fffe4 tcg/optimize: fix end of basic block detection
Commit e31b0a7c05 fixed copy propagation on
32-bit host by restricting the copy between different types. This was the
wrong fix.

The real problem is that the all temps states should be reset at the end
of a basic block. This was done by adding such operations in the switch,
but brcond2 was forgotten (that's why the crash was only observed on 32-bit
hosts).

Fix that by looking at the TCG_OPF_BB_END instead. We need to keep the case
for op_set_label as temps might be modified through another path.

Cc: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Richard Henderson
447f11b945 target-mips: Always evaluate debugging macro arguments
this will prevent some of the compilation errors with debugging
enabled from creeping back in.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Richard Henderson
fe07dcf262 target-mips: Fix MIPS_DEBUG.
The macro uses the DisasContext.  Pass it around as needed.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Acked-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Richard Henderson
d25c2359de target-mips: Set opn in gen_ldst_multiple.
Used by MIPS_DEBUG, when enabled.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Acked-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Aurelien Jarno
4f17bc1e89 revert "TCG: fix copy propagation"
Given the copy propagation breakage on 32-bit hosts has been fixed
commit e31b0a7c05 can be reverted.

Cc: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Aurelien Jarno
d39d648846 tcg: mark set_label with TCG_OPF_BB_END flag
set_label is effectively the end of a basic block, as no optimization
can be made accross it. It was treated as such in the liveness analysis
code, but as a special case.

Mark it with TCG_OPF_BB_END flag so that this information can be used
by other parts of the TCG code, and remove the special case in the liveness
analysis code.

Cc: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Aurelien Jarno
ea15fd7c1a tcg/i386: allow constants in load/store ops
On x86, it is possible to move a constant value to memory. Add code to
handle a constant argument to load/store ops.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Blue Swirl
a0969d7a46 Remove unused CONFIG_TCG_PASS_AREG0 and dead code
Now that CONFIG_TCG_PASS_AREG0 is enabled for all targets,
remove dead code and support for !CONFIG_TCG_PASS_AREG0 case.

Remove dyngen-exec.h and all references to it. Although included by
hw/spapr_hcall.c, it does not seem to use it.

Remove unused HELPER_CFLAGS.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Blue Swirl
0c4b3c0198 target-mips: switch to AREG0 free mode
Add an explicit CPUState parameter instead of relying on AREG0
and switch to AREG0 free mode.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Acked-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Blue Swirl
ca75e56821 target-sh4: switch to AREG0 free mode
Add an explicit CPUState parameter instead of relying on AREG0
and switch to AREG0 free mode.

Acked-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Aurelien Jarno
c383331e9d target-cris: Switch to AREG0 free mode
Add an explicit CPUCRISState parameter instead of relying on AREG0, and
use cpu_ld* in translation and interrupt handling. Remove AREG0 swapping
in tlb_fill(). Switch to AREG0 free mode

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:08 -05:00
Aurelien Jarno
d36ae16dd4 target-cris: Avoid AREG0 for helpers
Add an explicit CPUCRISState parameter instead of relying on AREG0.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Blue Swirl
c9b89e8224 target-microblaze: switch to AREG0 free mode
Add an explicit CPUState parameter instead of relying on AREG0
and switch to AREG0 free mode.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Blue Swirl
40b1f8a804 target-arm: final conversion to AREG0 free mode
Convert code load functions and switch to AREG0 free mode.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Blue Swirl
883864650e target-arm: convert remaining helpers
Convert remaining helpers to AREG0 free mode: add an explicit
CPUState parameter instead of relying on AREG0.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Blue Swirl
6178b83f35 target-arm: convert void helpers
Add an explicit CPUState parameter instead of relying on AREG0.

For easier review, convert only op helpers which don't return any value.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Blue Swirl
af411212ce target-unicore32: switch to AREG0 free mode
Add an explicit CPUState parameter instead of relying on AREG0
and switch to AREG0 free mode.

Tested-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Blue Swirl
e67d4921fd target-m68k: avoid using cpu_single_env
Pass around CPUState instead of using global cpu_single_env.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Blue Swirl
3654ef451e target-m68k: switch to AREG0 free mode
Add an explicit CPUState parameter instead of relying on AREG0
and switch to AREG0 free mode.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Blue Swirl
7a5311f64f target-lm32: switch to AREG0 free mode
Add an explicit CPUState parameter instead of relying on AREG0
and switch to AREG0 free mode.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Blue Swirl
1ada516f0e target-s390x: avoid cpu_single_env
Pass around CPUState instead of using global cpu_single_env.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Aurelien Jarno
578c758200 tcg/optimize: fix if/else/break coding style
optimizer.c contains some cases were the break is appearing in both the
if and the else parts. Fix that by moving it to the outer part. Also
move some common code there.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Aurelien Jarno
97c012c76a tcg/optimize: add constant folding for brcond
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Aurelien Jarno
2108a786ba tcg/optimize: add constant folding for setcond
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Aurelien Jarno
decddd9021 tcg/optimize: swap brcond/setcond arguments when possible
brcond and setcond ops are not commutative, but it's easy to compute the
new condition after swapping the arguments. Try to always put the constant
argument in second position like for commutative ops, to help backends to
generate better code.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Aurelien Jarno
52173babad tcg/optimize: simplify shift/rot r, 0, a => movi r, 0 cases
shift/rot r, 0, a is equivalent to movi r, 0.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Aurelien Jarno
f66f1dab29 tcg/optimize: simplify and r, a, 0 cases
and r, a, 0 is equivalent to a movi r, 0.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Aurelien Jarno
6c9785fb4b tcg/optimize: simplify or/xor r, a, 0 cases
or/xor r, a, 0 is equivalent to a mov r, a.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Aurelien Jarno
d969307261 tcg/optimize: split expression simplification
Split expression simplification in multiple parts so that a given op
can appear multiple times. This patch should not change anything.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:07 -05:00
Stefan Weil
62cdb0fdd3 target-arm: Fix potential buffer overflow
Report from smatch:

target-arm/helper.c:651 arm946_prbs_read(6) error:
 buffer overflow 'env->cp15.c6_region' 8 <= 8
target-arm/helper.c:661 arm946_prbs_write(6) error:
 buffer overflow 'env->cp15.c6_region' 8 <= 8

c7_region is an array with 8 elements, so the index must be less than 8.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Aurelien Jarno
3bc7da7cd7 tcg/s390: fix ld/st with CONFIG_TCG_PASS_AREG0
The load/store slow path has been broken in e141ab52d:
- We need to move 4 registers for store functions and 3 registers for
  load functions and not the reverse.
- According to the s390x calling convention the arguments of a function
  should be zero extended. This means that the register shift should be
  done with TCG_TYPE_I64 to ensure the higher word is correctly zero
  extended when needed.

I am aware that CONFIG_TCG_PASS_AREG0 is being removed and thus that
this patch can be improved, but doing so means it can also be applied to
the 1.1 and 1.2 stable branches.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Blue Swirl
265434460e target-s390x: switch to AREG0 free mode
Add an explicit CPUState parameter instead of relying on AREG0.

Remove temporary wrappers and switch to AREG0 free mode.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
[agraf: fix conflicts]
Signed-off-by: Alexander Graf <agraf@suse.de>

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Blue Swirl
71742e6c68 target-s390x: avoid AREG0 for misc helpers
Make misc helpers take a parameter for CPUState instead
of relying on global env.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
[agraf: fix conflict]
Signed-off-by: Alexander Graf <agraf@suse.de>

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Blue Swirl
719a60ddb3 target-s390x: avoid AREG0 for condition code helpers
Make condition code helpers take a parameter for CPUState instead
of relying on global env.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Blue Swirl
1f983b49f7 target-s390x: avoid AREG0 for integer helpers
Make integer helpers take a parameter for CPUState instead
of relying on global env.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Blue Swirl
313e38b4a1 target-s390x: avoid AREG0 for FPU helpers
Make FPU helpers take a parameter for CPUState instead
of relying on global env.

Introduce temporary wrappers for FPU load and store ops.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Blue Swirl
1a392c8957 target-s390x: rename op_helper.c to misc_helper.c
Now op_helper.c contains miscellaneous helpers, rename
it to misc_helper.c.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
[agraf: fix conflict]
Signed-off-by: Alexander Graf <agraf@suse.de>

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Blue Swirl
84dde20eea target-s390x: split memory access helpers
Move memory access helpers to mem_helper.c.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
[agraf: fold softmmu include ifdefs together]
Signed-off-by: Alexander Graf <agraf@suse.de>

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Blue Swirl
7dc581be44 target-s390x: split integer helpers
Move integer helpers to int_helper.c.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Blue Swirl
f7c50726dd target-s390x: split condition code helpers
Move condition code helpers to cc_helper.c.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Blue Swirl
4bae8a0a90 target-s390x: split FPU ops
Move floating point instructions to fpu_helper.c.

While exporting some condition code helpers,
avoid duplicate identifier conflict with translate.c.

Remove unused set_cc_nz_f64() in translate.c.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Blue Swirl
b05900a761 target-s390x: fix style
Before splitting op_helper.c and helper.c in the next patches,
fix style issues. No functional changes.

Replace also GCC specific __FUNCTION__ with
standard __func__.

Don't init static variable (cpu_s390x_init:inited) with 0.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Aurelien Jarno
b16148e1c6 target-sparc: fix fcmp{s,d,q} instructions wrt exception
fcmp{s,d,q} instructions are supposed to ignore quiet NaN (contrary to
the fcmpe{s,d,q} instructions), but the current code is wrongly setting
the NV exception in that case. Moreover the current code is duplicated:
first the arguments are checked for NaN to generate an exception, and
later in case the comparison is unordered (which can only happens if one
of the argument is a NaN), the same check is done to generate an
exception.

Fix that by calling clear_float_exceptions() followed by
check_ieee_exceptions() as for the other floating point instructions.
Use the _compare_quiet functions for fcmp{s,d,q} and the _compare ones
for fcmpe{s,d,q}. Simplify the flag setting by not clearing a flag that
is set the line just below.

This fix allows the math glibc testsuite to pass.

Cc: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Max Filippov
dafd8866be target-xtensa: fix missing errno codes for mingw32
Put the following errno value mappings under #ifdef:

xtensa-semi.c: In function 'errno_h2g':
xtensa-semi.c:113: error: 'ENOTBLK' undeclared (first use in this function)
xtensa-semi.c:113: error: (Each undeclared identifier is reported only once
xtensa-semi.c:113: error: for each function it appears in.)
xtensa-semi.c:113: error: array index in initializer not of integer type
xtensa-semi.c:113: error: (near initialization for 'guest_errno')
xtensa-semi.c:124: error: 'ETXTBSY' undeclared (first use in this function)
xtensa-semi.c:124: error: array index in initializer not of integer type
xtensa-semi.c:124: error: (near initialization for 'guest_errno')
xtensa-semi.c:134: error: 'ELOOP' undeclared (first use in this function)
xtensa-semi.c:134: error: array index in initializer not of integer type
xtensa-semi.c:134: error: (near initialization for 'guest_errno')

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Stefan Weil
631287933e target-cris: Fix buffer overflow
Report from smatch:

target-cris/translate.c:3464 cpu_dump_state(32) error:
 buffer overflow 'env->sregs' 4 <= 255

sregs is declared 'uint32_t sregs[4][16]', so the first index must be
less than 4 or ARRAY_SIZE(env->sregs).

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
Max Filippov
814395979e target-xtensa: convert host errno values to guest
Guest errno values are taken from the newlib. Convert only those errno
values that can be returned from used system calls.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-10-09 01:42:06 -05:00
218 changed files with 9831 additions and 8822 deletions

View File

@@ -398,6 +398,12 @@ M: Blue Swirl <blauwirbel@gmail.com>
S: Maintained
F: hw/sun4u.c
Leon3
M: Fabien Chouteau <chouteau@adacore.com>
S: Maintained
F: hw/leon3.c
F: hw/grlib*
S390 Machines
-------------
S390 Virtio
@@ -525,6 +531,12 @@ M: Anthony Liguori <aliguori@us.ibm.com>
S: Maintained
F: qemu-char.c
CPU
M: Andreas Färber <afaerber@suse.de>
S: Supported
F: qom/cpu.c
F: include/qemu/cpu.h
Device Tree
M: Peter Crosthwaite <peter.crosthwaite@petalogix.com>
M: Alexander Graf <agraf@suse.de>

View File

@@ -52,8 +52,13 @@ SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory) BUILD_DIR=$(BUILD_DIR)
SUBDIR_DEVICES_MAK=$(patsubst %, %/config-devices.mak, $(TARGET_DIRS))
SUBDIR_DEVICES_MAK_DEP=$(patsubst %, %/config-devices.mak.d, $(TARGET_DIRS))
ifeq ($(SUBDIR_DEVICES_MAK),)
config-all-devices.mak:
$(call quiet-command,echo '# no devices' > $@," GEN $@")
else
config-all-devices.mak: $(SUBDIR_DEVICES_MAK)
$(call quiet-command,cat $(SUBDIR_DEVICES_MAK) | grep =y | sort -u > $@," GEN $@")
endif
-include $(SUBDIR_DEVICES_MAK_DEP)

View File

@@ -80,14 +80,6 @@ obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
tci-dis.o: QEMU_CFLAGS += -I$(SRC_PATH)/tcg -I$(SRC_PATH)/tcg/tci
# HELPER_CFLAGS is used for all the legacy code compiled with static register
# variables
user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
# Note: this is a workaround. The real fix is to avoid compiling
# cpu_signal_handler() in user-exec.c.
%/signal.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
#########################################################
# Linux user emulator target

View File

@@ -1 +1 @@
1.2.0
1.2.2

View File

@@ -562,7 +562,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
if ((i & 63) == 0) {
uint64_t t1 = (qemu_get_clock_ns(rt_clock) - bwidth) / 1000000;
if (t1 > MAX_WAIT) {
DPRINTF("big wait: " PRIu64 " milliseconds, %d iterations\n",
DPRINTF("big wait: %" PRIu64 " milliseconds, %d iterations\n",
t1, i);
break;
}
@@ -587,7 +587,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
DPRINTF("ram_save_live: expected(" PRIu64 ") <= max(" PRIu64 ")?\n",
DPRINTF("ram_save_live: expected(%" PRIu64 ") <= max(%" PRIu64 ")?\n",
expected_time, migrate_max_downtime());
if (expected_time <= migrate_max_downtime()) {
@@ -799,8 +799,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
} while (!(flags & RAM_SAVE_FLAG_EOS));
done:
DPRINTF("Completed load of VM with exit code %d seq iteration " PRIu64 "\n",
ret, seq_iter);
DPRINTF("Completed load of VM with exit code %d seq iteration "
"%" PRIu64 "\n", ret, seq_iter);
return ret;
}
@@ -922,11 +922,16 @@ void select_soundhw(const char *optarg)
if (is_help_option(optarg)) {
show_valid_cards:
#ifdef HAS_AUDIO_CHOICE
printf("Valid sound card names (comma separated):\n");
for (c = soundhw; c->name; ++c) {
printf ("%-11s %s\n", c->name, c->descr);
}
printf("\n-soundhw all will enable all of the above\n");
#else
printf("Machine has no user-selectable audio hardware "
"(it may or may not have always-present audio hardware).\n");
#endif
exit(!is_help_option(optarg));
}
else {

View File

@@ -410,15 +410,15 @@ SW *glue (AUD_open_, TYPE) (
SW *old_sw = NULL;
#endif
ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
name, as->freq, as->nchannels, as->fmt);
if (audio_bug (AUDIO_FUNC, !card || !name || !callback_fn || !as)) {
dolog ("card=%p name=%p callback_fn=%p as=%p\n",
card, name, callback_fn, as);
goto fail;
}
ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
name, as->freq, as->nchannels, as->fmt);
if (audio_bug (AUDIO_FUNC, audio_validate_settings (as))) {
audio_print_settings (as);
goto fail;

27
block.c
View File

@@ -433,7 +433,11 @@ int get_tmp_filename(char *filename, int size)
return -EOVERFLOW;
}
fd = mkstemp(filename);
if (fd < 0 || close(fd)) {
if (fd < 0) {
return -errno;
}
if (close(fd) != 0) {
unlink(filename);
return -errno;
}
return 0;
@@ -664,7 +668,7 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename,
open_flags |= BDRV_O_RDWR;
}
bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
bs->read_only = !(open_flags & BDRV_O_RDWR);
/* Open the image, either directly or using a protocol */
if (drv->bdrv_file_open) {
@@ -735,7 +739,8 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
BlockDriver *drv)
{
int ret;
char tmp_filename[PATH_MAX];
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
char tmp_filename[PATH_MAX + 1];
if (flags & BDRV_O_SNAPSHOT) {
BlockDriverState *bs1;
@@ -804,6 +809,12 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
goto unlink_and_fail;
}
if (flags & BDRV_O_RDWR) {
flags |= BDRV_O_ALLOW_RDWR;
}
bs->keep_read_only = !(flags & BDRV_O_ALLOW_RDWR);
/* Open the image */
ret = bdrv_open_common(bs, filename, flags, drv);
if (ret < 0) {
@@ -833,12 +844,6 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
bdrv_close(bs);
return ret;
}
if (bs->is_temporary) {
bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);
} else {
/* base image inherits from "parent" */
bs->backing_hd->keep_read_only = bs->keep_read_only;
}
}
if (!bdrv_key_required(bs)) {
@@ -897,10 +902,10 @@ void bdrv_close(BlockDriverState *bs)
bdrv_delete(bs->file);
bs->file = NULL;
}
bdrv_dev_change_media_cb(bs, false);
}
bdrv_dev_change_media_cb(bs, false);
/*throttling disk I/O limits*/
if (bs->io_limits_enabled) {
bdrv_io_limits_disable(bs);

View File

@@ -80,6 +80,7 @@ typedef struct BlockDevOps {
#define BDRV_O_COPY_ON_READ 0x0400 /* copy read backing sectors into image */
#define BDRV_O_INCOMING 0x0800 /* consistency hint for incoming migration */
#define BDRV_O_CHECK 0x1000 /* open solely for consistency check */
#define BDRV_O_ALLOW_RDWR 0x2000 /* allow reopen to change from r/o to r/w */
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH)

View File

@@ -542,8 +542,7 @@ static void curl_close(BlockDriverState *bs)
}
if (s->multi)
curl_multi_cleanup(s->multi);
if (s->url)
free(s->url);
g_free(s->url);
}
static int64_t curl_getlength(BlockDriverState *bs)

View File

@@ -65,13 +65,6 @@ typedef struct IscsiAIOCB {
#endif
} IscsiAIOCB;
struct IscsiTask {
IscsiLun *iscsilun;
BlockDriverState *bs;
int status;
int complete;
};
static void
iscsi_bh_cb(void *p)
{
@@ -167,12 +160,6 @@ iscsi_set_events(IscsiLun *iscsilun)
}
/* If we just added an event, the callback might be delayed
* unless we call qemu_notify_event().
*/
if (ev & ~iscsilun->events) {
qemu_notify_event();
}
iscsilun->events = ev;
}
@@ -390,7 +377,7 @@ iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
*(uint16_t *)&acb->task->cdb[7] = htons(num_sectors);
break;
}
if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
iscsi_aio_read16_cb,
NULL,
@@ -628,9 +615,17 @@ static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
return &acb->common;
}
static void ioctl_cb(void *opaque, int status)
{
int *p_status = opaque;
*p_status = status;
}
static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
{
IscsiLun *iscsilun = bs->opaque;
int status;
switch (req) {
case SG_GET_VERSION_NUM:
@@ -639,6 +634,15 @@ static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
case SG_GET_SCSI_ID:
((struct sg_scsi_id *)buf)->scsi_type = iscsilun->type;
break;
case SG_IO:
status = -EINPROGRESS;
iscsi_aio_ioctl(bs, req, buf, ioctl_cb, &status);
while (status == -EINPROGRESS) {
qemu_aio_wait();
}
return 0;
default:
return -1;
}
@@ -658,163 +662,6 @@ iscsi_getlength(BlockDriverState *bs)
return len;
}
static void
iscsi_readcapacity16_cb(struct iscsi_context *iscsi, int status,
void *command_data, void *opaque)
{
struct IscsiTask *itask = opaque;
struct scsi_readcapacity16 *rc16;
struct scsi_task *task = command_data;
if (status != 0) {
error_report("iSCSI: Failed to read capacity of iSCSI lun. %s",
iscsi_get_error(iscsi));
itask->status = 1;
itask->complete = 1;
scsi_free_scsi_task(task);
return;
}
rc16 = scsi_datain_unmarshall(task);
if (rc16 == NULL) {
error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
itask->status = 1;
itask->complete = 1;
scsi_free_scsi_task(task);
return;
}
itask->iscsilun->block_size = rc16->block_length;
itask->iscsilun->num_blocks = rc16->returned_lba + 1;
itask->bs->total_sectors = itask->iscsilun->num_blocks *
itask->iscsilun->block_size / BDRV_SECTOR_SIZE ;
itask->status = 0;
itask->complete = 1;
scsi_free_scsi_task(task);
}
static void
iscsi_readcapacity10_cb(struct iscsi_context *iscsi, int status,
void *command_data, void *opaque)
{
struct IscsiTask *itask = opaque;
struct scsi_readcapacity10 *rc10;
struct scsi_task *task = command_data;
if (status != 0) {
error_report("iSCSI: Failed to read capacity of iSCSI lun. %s",
iscsi_get_error(iscsi));
itask->status = 1;
itask->complete = 1;
scsi_free_scsi_task(task);
return;
}
rc10 = scsi_datain_unmarshall(task);
if (rc10 == NULL) {
error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
itask->status = 1;
itask->complete = 1;
scsi_free_scsi_task(task);
return;
}
itask->iscsilun->block_size = rc10->block_size;
if (rc10->lba == 0) {
/* blank disk loaded */
itask->iscsilun->num_blocks = 0;
} else {
itask->iscsilun->num_blocks = rc10->lba + 1;
}
itask->bs->total_sectors = itask->iscsilun->num_blocks *
itask->iscsilun->block_size / BDRV_SECTOR_SIZE ;
itask->status = 0;
itask->complete = 1;
scsi_free_scsi_task(task);
}
static void
iscsi_inquiry_cb(struct iscsi_context *iscsi, int status, void *command_data,
void *opaque)
{
struct IscsiTask *itask = opaque;
struct scsi_task *task = command_data;
struct scsi_inquiry_standard *inq;
if (status != 0) {
itask->status = 1;
itask->complete = 1;
scsi_free_scsi_task(task);
return;
}
inq = scsi_datain_unmarshall(task);
if (inq == NULL) {
error_report("iSCSI: Failed to unmarshall inquiry data.");
itask->status = 1;
itask->complete = 1;
scsi_free_scsi_task(task);
return;
}
itask->iscsilun->type = inq->periperal_device_type;
scsi_free_scsi_task(task);
switch (itask->iscsilun->type) {
case TYPE_DISK:
task = iscsi_readcapacity16_task(iscsi, itask->iscsilun->lun,
iscsi_readcapacity16_cb, opaque);
if (task == NULL) {
error_report("iSCSI: failed to send readcapacity16 command.");
itask->status = 1;
itask->complete = 1;
return;
}
break;
case TYPE_ROM:
task = iscsi_readcapacity10_task(iscsi, itask->iscsilun->lun,
0, 0,
iscsi_readcapacity10_cb, opaque);
if (task == NULL) {
error_report("iSCSI: failed to send readcapacity16 command.");
itask->status = 1;
itask->complete = 1;
return;
}
break;
default:
itask->status = 0;
itask->complete = 1;
}
}
static void
iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data,
void *opaque)
{
struct IscsiTask *itask = opaque;
struct scsi_task *task;
if (status != 0) {
itask->status = 1;
itask->complete = 1;
return;
}
task = iscsi_inquiry_task(iscsi, itask->iscsilun->lun,
0, 0, 36,
iscsi_inquiry_cb, opaque);
if (task == NULL) {
error_report("iSCSI: failed to send inquiry command.");
itask->status = 1;
itask->complete = 1;
return;
}
}
static int parse_chap(struct iscsi_context *iscsi, const char *target)
{
QemuOptsList *list;
@@ -927,7 +774,10 @@ static int iscsi_open(BlockDriverState *bs, const char *filename, int flags)
IscsiLun *iscsilun = bs->opaque;
struct iscsi_context *iscsi = NULL;
struct iscsi_url *iscsi_url = NULL;
struct IscsiTask task;
struct scsi_task *task = NULL;
struct scsi_inquiry_standard *inq = NULL;
struct scsi_readcapacity10 *rc10 = NULL;
struct scsi_readcapacity16 *rc16 = NULL;
char *initiator_name = NULL;
int ret;
@@ -940,8 +790,7 @@ static int iscsi_open(BlockDriverState *bs, const char *filename, int flags)
iscsi_url = iscsi_parse_full_url(iscsi, filename);
if (iscsi_url == NULL) {
error_report("Failed to parse URL : %s %s", filename,
iscsi_get_error(iscsi));
error_report("Failed to parse URL : %s", filename);
ret = -EINVAL;
goto out;
}
@@ -991,33 +840,80 @@ static int iscsi_open(BlockDriverState *bs, const char *filename, int flags)
/* check if we got HEADER_DIGEST via the options */
parse_header_digest(iscsi, iscsi_url->target);
task.iscsilun = iscsilun;
task.status = 0;
task.complete = 0;
task.bs = bs;
if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
error_report("iSCSI: Failed to connect to LUN : %s",
iscsi_get_error(iscsi));
ret = -EINVAL;
goto out;
}
iscsilun->iscsi = iscsi;
iscsilun->lun = iscsi_url->lun;
if (iscsi_full_connect_async(iscsi, iscsi_url->portal, iscsi_url->lun,
iscsi_connect_cb, &task)
!= 0) {
error_report("iSCSI: Failed to start async connect.");
task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36);
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
error_report("iSCSI: failed to send inquiry command.");
ret = -EINVAL;
goto out;
}
while (!task.complete) {
iscsi_set_events(iscsilun);
qemu_aio_wait();
}
if (task.status != 0) {
error_report("iSCSI: Failed to connect to LUN : %s",
iscsi_get_error(iscsi));
inq = scsi_datain_unmarshall(task);
if (inq == NULL) {
error_report("iSCSI: Failed to unmarshall inquiry data.");
ret = -EINVAL;
goto out;
}
iscsilun->type = inq->periperal_device_type;
scsi_free_scsi_task(task);
switch (iscsilun->type) {
case TYPE_DISK:
task = iscsi_readcapacity16_sync(iscsi, iscsilun->lun);
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
error_report("iSCSI: failed to send readcapacity16 command.");
ret = -EINVAL;
goto out;
}
rc16 = scsi_datain_unmarshall(task);
if (rc16 == NULL) {
error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
ret = -EINVAL;
goto out;
}
iscsilun->block_size = rc16->block_length;
iscsilun->num_blocks = rc16->returned_lba + 1;
break;
case TYPE_ROM:
task = iscsi_readcapacity10_sync(iscsi, iscsilun->lun, 0, 0);
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
error_report("iSCSI: failed to send readcapacity10 command.");
ret = -EINVAL;
goto out;
}
rc10 = scsi_datain_unmarshall(task);
if (rc10 == NULL) {
error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
ret = -EINVAL;
goto out;
}
iscsilun->block_size = rc10->block_size;
if (rc10->lba == 0) {
/* blank disk loaded */
iscsilun->num_blocks = 0;
} else {
iscsilun->num_blocks = rc10->lba + 1;
}
break;
default:
break;
}
bs->total_sectors = iscsilun->num_blocks *
iscsilun->block_size / BDRV_SECTOR_SIZE ;
/* Medium changer or tape. We dont have any emulation for this so this must
* be sg ioctl compatible. We force it to be sg, otherwise qemu will try
* to read from the device to guess the image format.
@@ -1036,6 +932,9 @@ out:
if (iscsi_url != NULL) {
iscsi_destroy_url(iscsi_url);
}
if (task != NULL) {
scsi_free_scsi_task(task);
}
if (ret) {
if (iscsi != NULL) {
@@ -1056,6 +955,11 @@ static void iscsi_close(BlockDriverState *bs)
memset(iscsilun, 0, sizeof(IscsiLun));
}
static int iscsi_has_zero_init(BlockDriverState *bs)
{
return 0;
}
static BlockDriver bdrv_iscsi = {
.format_name = "iscsi",
.protocol_name = "iscsi",
@@ -1071,6 +975,7 @@ static BlockDriver bdrv_iscsi = {
.bdrv_aio_flush = iscsi_aio_flush,
.bdrv_aio_discard = iscsi_aio_discard,
.bdrv_has_zero_init = iscsi_has_zero_init,
#ifdef __linux__
.bdrv_ioctl = iscsi_ioctl,

View File

@@ -301,7 +301,8 @@ static int alloc_refcount_block(BlockDriverState *bs,
uint64_t last_table_size;
uint64_t blocks_clusters;
do {
uint64_t table_clusters = size_to_clusters(s, table_size);
uint64_t table_clusters =
size_to_clusters(s, table_size * sizeof(uint64_t));
blocks_clusters = 1 +
((table_clusters + refcount_block_clusters - 1)
/ refcount_block_clusters);

View File

@@ -1986,7 +1986,7 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
vdi_index = pos / SD_DATA_OBJ_SIZE;
offset = pos % SD_DATA_OBJ_SIZE;
data_len = MIN(remaining, SD_DATA_OBJ_SIZE);
data_len = MIN(remaining, SD_DATA_OBJ_SIZE - offset);
vmstate_oid = vid_to_vmstate_oid(s->inode.vdi_id, vdi_index);
@@ -2007,6 +2007,7 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
}
pos += data_len;
data += data_len;
remaining -= data_len;
}
ret = size;

View File

@@ -628,7 +628,6 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
VdiHeader header;
size_t i;
size_t bmap_size;
uint32_t *bmap;
logout("\n");
@@ -693,21 +692,21 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
result = -errno;
}
bmap = NULL;
if (bmap_size > 0) {
bmap = (uint32_t *)g_malloc0(bmap_size);
}
for (i = 0; i < blocks; i++) {
if (image_type == VDI_TYPE_STATIC) {
bmap[i] = i;
} else {
bmap[i] = VDI_UNALLOCATED;
uint32_t *bmap = g_malloc0(bmap_size);
for (i = 0; i < blocks; i++) {
if (image_type == VDI_TYPE_STATIC) {
bmap[i] = i;
} else {
bmap[i] = VDI_UNALLOCATED;
}
}
if (write(fd, bmap, bmap_size) < 0) {
result = -errno;
}
g_free(bmap);
}
if (write(fd, bmap, bmap_size) < 0) {
result = -errno;
}
g_free(bmap);
if (image_type == VDI_TYPE_STATIC) {
if (ftruncate(fd, sizeof(header) + bmap_size + blocks * block_size)) {
result = -errno;

View File

@@ -527,6 +527,8 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
if_name[type], mediastr, unit_id);
}
dinfo->bdrv = bdrv_new(dinfo->id);
dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
dinfo->bdrv->read_only = ro;
dinfo->devaddr = devaddr;
dinfo->type = type;
dinfo->bus = bus_id;

View File

@@ -44,6 +44,11 @@
/* Use gnu_printf when supported (qemu uses standard format strings). */
# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2)))
# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
# if defined(_WIN32)
/* Map __printf__ to __gnu_printf__ because we want standard format strings
* even when MinGW or GLib include files use __printf__. */
# define __printf__ __gnu_printf__
# endif
# endif
#if defined(_WIN32)
#define GCC_WEAK __attribute__((weak))

150
configure vendored
View File

@@ -111,14 +111,12 @@ source_path=`dirname "$0"`
cpu=""
interp_prefix="/usr/gnemul/qemu-%M"
static="no"
sparc_cpu=""
cross_prefix=""
audio_drv_list=""
audio_card_list="ac97 es1370 sb16 hda"
audio_possible_cards="ac97 es1370 sb16 cs4231a adlib gus hda"
block_drv_whitelist=""
host_cc="gcc"
helper_cflags=""
libs_softmmu=""
libs_tools=""
audio_pt_int=""
@@ -183,6 +181,7 @@ datadir="\${prefix}/share"
qemu_docdir="\${prefix}/share/doc/qemu"
bindir="\${prefix}/bin"
libdir="\${prefix}/lib"
libexecdir="\${prefix}/libexec"
includedir="\${prefix}/include"
sysconfdir="\${prefix}/etc"
confsuffix="/qemu"
@@ -216,6 +215,7 @@ usb_redir=""
opengl=""
zlib="yes"
guest_agent="yes"
want_tools="yes"
libiscsi=""
coroutine=""
seccomp=""
@@ -240,21 +240,6 @@ for opt do
;;
--disable-debug-info) debug_info="no"
;;
--sparc_cpu=*)
sparc_cpu="$optarg"
case $sparc_cpu in
v7|v8|v8plus|v8plusa)
cpu="sparc"
;;
v9)
cpu="sparc64"
;;
*)
echo "undefined SPARC architecture. Exiting";
exit 1
;;
esac
;;
esac
done
# OS specific
@@ -342,8 +327,6 @@ elif check_define __i386__ ; then
elif check_define __x86_64__ ; then
cpu="x86_64"
elif check_define __sparc__ ; then
# We can't check for 64 bit (when gcc is biarch) or V8PLUSA
# They must be specified using --sparc_cpu
if check_define __arch64__ ; then
cpu="sparc64"
else
@@ -633,6 +616,8 @@ for opt do
;;
--libdir=*) libdir="$optarg"
;;
--libexecdir=*) libexecdir="$optarg"
;;
--includedir=*) includedir="$optarg"
;;
--datadir=*) datadir="$optarg"
@@ -643,7 +628,7 @@ for opt do
;;
--sysconfdir=*) sysconfdir="$optarg"
;;
--sbindir=*|--libexecdir=*|--sharedstatedir=*|--localstatedir=*|\
--sbindir=*|--sharedstatedir=*|--localstatedir=*|\
--oldincludedir=*|--datarootdir=*|--infodir=*|--localedir=*|\
--htmldir=*|--dvidir=*|--pdfdir=*|--psdir=*)
# These switches are silently ignored, for compatibility with
@@ -789,8 +774,6 @@ for opt do
;;
--enable-uname-release=*) uname_release="$optarg"
;;
--sparc_cpu=*)
;;
--enable-werror) werror="yes"
;;
--disable-werror) werror="no"
@@ -865,6 +848,10 @@ for opt do
;;
--disable-guest-agent) guest_agent="no"
;;
--enable-tools) want_tools="yes"
;;
--disable-tools) want_tools="no"
;;
--enable-seccomp) seccomp="yes"
;;
--disable-seccomp) seccomp="no"
@@ -874,36 +861,17 @@ for opt do
esac
done
#
# If cpu ~= sparc and sparc_cpu hasn't been defined, plug in the right
# QEMU_CFLAGS/LDFLAGS (assume sparc_v8plus for 32-bit and sparc_v9 for 64-bit)
#
host_guest_base="no"
case "$cpu" in
sparc) case $sparc_cpu in
v7|v8)
QEMU_CFLAGS="-mcpu=${sparc_cpu} -D__sparc_${sparc_cpu}__ $QEMU_CFLAGS"
;;
v8plus|v8plusa)
QEMU_CFLAGS="-mcpu=ultrasparc -D__sparc_${sparc_cpu}__ $QEMU_CFLAGS"
;;
*) # sparc_cpu not defined in the command line
QEMU_CFLAGS="-mcpu=ultrasparc -D__sparc_v8plus__ $QEMU_CFLAGS"
esac
sparc)
LDFLAGS="-m32 $LDFLAGS"
QEMU_CFLAGS="-m32 -ffixed-g2 -ffixed-g3 $QEMU_CFLAGS"
if test "$solaris" = "no" ; then
QEMU_CFLAGS="-ffixed-g1 -ffixed-g6 $QEMU_CFLAGS"
helper_cflags="-ffixed-i0"
fi
QEMU_CFLAGS="-m32 -mcpu=ultrasparc $QEMU_CFLAGS"
host_guest_base="yes"
;;
sparc64)
QEMU_CFLAGS="-m64 -mcpu=ultrasparc -D__sparc_v9__ $QEMU_CFLAGS"
LDFLAGS="-m64 $LDFLAGS"
QEMU_CFLAGS="-ffixed-g5 -ffixed-g6 -ffixed-g7 $QEMU_CFLAGS"
if test "$solaris" != "no" ; then
QEMU_CFLAGS="-ffixed-g1 $QEMU_CFLAGS"
fi
QEMU_CFLAGS="-m64 -mcpu=ultrasparc $QEMU_CFLAGS"
host_guest_base="yes"
;;
s390)
QEMU_CFLAGS="-m31 -march=z990 $QEMU_CFLAGS"
@@ -919,7 +887,6 @@ case "$cpu" in
QEMU_CFLAGS="-m32 $QEMU_CFLAGS"
LDFLAGS="-m32 $LDFLAGS"
cc_i386='$(CC) -m32'
helper_cflags="-fomit-frame-pointer"
host_guest_base="yes"
;;
x86_64)
@@ -1319,10 +1286,6 @@ if test -z "$target_list" ; then
else
target_list=`echo "$target_list" | sed -e 's/,/ /g'`
fi
if test -z "$target_list" ; then
echo "No targets enabled"
exit 1
fi
# see if system emulation was really requested
case " $target_list " in
*"-softmmu "*) softmmu=yes
@@ -1428,10 +1391,10 @@ if test "$seccomp" != "no" ; then
LIBS=`$pkg_config --libs libseccomp`
seccomp="yes"
else
seccomp="no"
if test "$seccomp" = "yes"; then
feature_not_found "libseccomp"
fi
seccomp="no"
fi
fi
##########################################
@@ -2426,8 +2389,7 @@ cat > $TMPC << EOF
int main(void)
{
int pipefd[2];
pipe2(pipefd, O_CLOEXEC);
return 0;
return pipe2(pipefd, O_CLOEXEC);
}
EOF
if compile_prog "" "" ; then
@@ -2667,18 +2629,45 @@ EOF
fi
##########################################
# Do we need libm
cat > $TMPC << EOF
#include <math.h>
int main(void) { return isnan(sin(0.0)); }
EOF
if compile_prog "" "" ; then
:
elif compile_prog "" "-lm" ; then
LIBS="-lm $LIBS"
libs_qga="-lm $libs_qga"
else
echo
echo "Error: libm check failed"
echo
exit 1
fi
##########################################
# Do we need librt
# uClibc provides 2 versions of clock_gettime(), one with realtime
# support and one without. This means that the clock_gettime() don't
# need -lrt. We still need it for timer_create() so we check for this
# function in addition.
cat > $TMPC <<EOF
#include <signal.h>
#include <time.h>
int main(void) { return clock_gettime(CLOCK_REALTIME, NULL); }
int main(void) {
timer_create(CLOCK_REALTIME, NULL, NULL);
return clock_gettime(CLOCK_REALTIME, NULL);
}
EOF
if compile_prog "" "" ; then
:
elif compile_prog "" "-lrt" ; then
# we need pthread for static linking. use previous pthread test result
elif compile_prog "" "-lrt $pthread_lib" ; then
LIBS="-lrt $LIBS"
libs_qga="-lrt $libs_qga"
fi
if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \
@@ -2701,6 +2690,11 @@ EOF
spice="yes"
libs_softmmu="$libs_softmmu $spice_libs"
QEMU_CFLAGS="$QEMU_CFLAGS $spice_cflags"
spice_protocol_version=$($pkg_config --modversion spice-protocol)
spice_server_version=$($pkg_config --modversion spice-server)
if $pkg_config --atleast-version=0.12.0 spice-protocol >/dev/null 2>&1; then
spice_qxl_io_monitors_config_async="yes"
fi
else
if test "$spice" = "yes" ; then
feature_not_found "spice"
@@ -2755,7 +2749,7 @@ if test "$usb_redir" != "no" ; then
usb_redir_cflags=$($pkg_config --cflags libusbredirparser 2>/dev/null)
usb_redir_libs=$($pkg_config --libs libusbredirparser 2>/dev/null)
QEMU_CFLAGS="$QEMU_CFLAGS $usb_redir_cflags"
LIBS="$LIBS $usb_redir_libs"
libs_softmmu="$libs_softmmu $usb_redir_libs"
else
if test "$usb_redir" = "yes"; then
feature_not_found "usb-redir"
@@ -2963,11 +2957,12 @@ if compile_prog "-Werror" "" ; then
fi
########################################
# check if we have valgrind/valgrind.h
# check if we have valgrind/valgrind.h and valgrind/memcheck.h
valgrind_h=no
cat > $TMPC << EOF
#include <valgrind/valgrind.h>
#include <valgrind/memcheck.h>
int main(void) {
return 0;
}
@@ -3039,9 +3034,14 @@ fi
qemu_confdir=$sysconfdir$confsuffix
qemu_datadir=$datadir$confsuffix
tools=
if test "$softmmu" = yes ; then
tools=""
if test "$want_tools" = "yes" ; then
tools="qemu-img\$(EXESUF) qemu-io\$(EXESUF) $tools"
if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
tools="qemu-nbd\$(EXESUF) $tools"
fi
fi
if test "$softmmu" = yes ; then
if test "$virtfs" != no ; then
if test "$cap" = yes && test "$linux" = yes && test "$attr" = yes ; then
virtfs=yes
@@ -3055,14 +3055,13 @@ if test "$softmmu" = yes ; then
fi
fi
if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
tools="qemu-nbd\$(EXESUF) $tools"
if [ "$guest_agent" = "yes" ]; then
tools="qemu-ga\$(EXESUF) $tools"
fi
fi
fi
if test "$smartcard_nss" = "yes" ; then
tools="vscclient\$(EXESUF) $tools"
if test "$smartcard_nss" = "yes" ; then
tools="vscclient\$(EXESUF) $tools"
fi
fi
# Mac OS X ships with a broken assembler
@@ -3080,6 +3079,7 @@ echo "Install prefix $prefix"
echo "BIOS directory `eval echo $qemu_datadir`"
echo "binary directory `eval echo $bindir`"
echo "library directory `eval echo $libdir`"
echo "libexec directory `eval echo $libexecdir`"
echo "include directory `eval echo $includedir`"
echo "config directory `eval echo $sysconfdir`"
if test "$mingw32" = "no" ; then
@@ -3156,7 +3156,7 @@ echo "libcap-ng support $cap_ng"
echo "vhost-net support $vhost_net"
echo "Trace backend $trace_backend"
echo "Trace output file $trace_file-<pid>"
echo "spice support $spice"
echo "spice support $spice ($spice_protocol_version/$spice_server_version)"
echo "rbd support $rbd"
echo "xfsctl support $xfs"
echo "nss used $smartcard_nss"
@@ -3183,14 +3183,14 @@ echo all: >> $config_host_mak
echo "prefix=$prefix" >> $config_host_mak
echo "bindir=$bindir" >> $config_host_mak
echo "libdir=$libdir" >> $config_host_mak
echo "libexecdir=$libexecdir" >> $config_host_mak
echo "includedir=$includedir" >> $config_host_mak
echo "mandir=$mandir" >> $config_host_mak
echo "sysconfdir=$sysconfdir" >> $config_host_mak
echo "qemu_confdir=$qemu_confdir" >> $config_host_mak
echo "qemu_datadir=$qemu_datadir" >> $config_host_mak
echo "qemu_docdir=$qemu_docdir" >> $config_host_mak
echo "libexecdir=\${prefix}/libexec" >> $config_host_mak
echo "CONFIG_QEMU_HELPERDIR=\"$prefix/libexec\"" >> $config_host_mak
echo "qemu_helperdir=$libexecdir" >> $config_host_mak
echo "ARCH=$ARCH" >> $config_host_mak
if test "$debug_tcg" = "yes" ; then
@@ -3438,6 +3438,10 @@ if test "$spice" = "yes" ; then
echo "CONFIG_SPICE=y" >> $config_host_mak
fi
if test "$spice_qxl_io_monitors_config_async" = "yes" ; then
echo "CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC=y" >> $config_host_mak
fi
if test "$smartcard" = "yes" ; then
echo "CONFIG_SMARTCARD=y" >> $config_host_mak
fi
@@ -3572,7 +3576,6 @@ if test "$sparse" = "yes" ; then
echo "HOST_CC := REAL_CC=\"\$(HOST_CC)\" cgcc" >> $config_host_mak
echo "QEMU_CFLAGS += -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-non-pointer-null" >> $config_host_mak
fi
echo "HELPER_CFLAGS=$helper_cflags" >> $config_host_mak
echo "LDFLAGS=$LDFLAGS" >> $config_host_mak
echo "ARLIBS_BEGIN=$arlibs_begin" >> $config_host_mak
echo "ARLIBS_END=$arlibs_end" >> $config_host_mak
@@ -3827,13 +3830,6 @@ fi
symlink "$source_path/Makefile.target" "$target_dir/Makefile"
case "$target_arch2" in
alpha | i386 | or32 | sparc* | x86_64 | xtensa* | ppc*)
echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
;;
esac
upper() {
echo "$@"| LC_ALL=C tr '[a-z]' '[A-Z]'
}
@@ -4085,10 +4081,6 @@ fi
if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then
case "$ARCH" in
sparc)
# -static is used to avoid g1/g3 usage by the dynamic linker
ldflags="$linker_script -static $ldflags"
;;
alpha | s390x)
# The default placement of the application is fine.
;;

View File

@@ -937,8 +937,11 @@ static void console_putchar(TextConsole *s, int ch)
case TTY_STATE_CSI: /* handle escape sequence parameters */
if (ch >= '0' && ch <= '9') {
if (s->nb_esc_params < MAX_ESC_PARAMS) {
s->esc_params[s->nb_esc_params] =
s->esc_params[s->nb_esc_params] * 10 + ch - '0';
int *param = &s->esc_params[s->nb_esc_params];
int digit = (ch - '0');
*param = (*param <= (INT_MAX - digit) / 10) ?
*param * 10 + digit : INT_MAX;
}
} else {
if (s->nb_esc_params < MAX_ESC_PARAMS)
@@ -1611,7 +1614,7 @@ PixelFormat qemu_different_endianness_pixelformat(int bpp)
memset(&pf, 0x00, sizeof(PixelFormat));
pf.bits_per_pixel = bpp;
pf.bytes_per_pixel = bpp / 8;
pf.bytes_per_pixel = DIV_ROUND_UP(bpp, 8);
pf.depth = bpp == 32 ? 24 : bpp;
switch (bpp) {
@@ -1660,13 +1663,12 @@ PixelFormat qemu_default_pixelformat(int bpp)
memset(&pf, 0x00, sizeof(PixelFormat));
pf.bits_per_pixel = bpp;
pf.bytes_per_pixel = bpp / 8;
pf.bytes_per_pixel = DIV_ROUND_UP(bpp, 8);
pf.depth = bpp == 32 ? 24 : bpp;
switch (bpp) {
case 15:
pf.bits_per_pixel = 16;
pf.bytes_per_pixel = 2;
pf.rmask = 0x00007c00;
pf.gmask = 0x000003E0;
pf.bmask = 0x0000001F;

View File

@@ -260,14 +260,6 @@ extern unsigned long reserved_va;
#define stfl(p, v) stfl_raw(p, v)
#define stfq(p, v) stfq_raw(p, v)
#ifndef CONFIG_TCG_PASS_AREG0
#define ldub_code(p) ldub_raw(p)
#define ldsb_code(p) ldsb_raw(p)
#define lduw_code(p) lduw_raw(p)
#define ldsw_code(p) ldsw_raw(p)
#define ldl_code(p) ldl_raw(p)
#define ldq_code(p) ldq_raw(p)
#else
#define cpu_ldub_code(env1, p) ldub_raw(p)
#define cpu_ldsb_code(env1, p) ldsb_raw(p)
#define cpu_lduw_code(env1, p) lduw_raw(p)
@@ -296,7 +288,6 @@ extern unsigned long reserved_va;
#define cpu_stw_kernel(env, addr, data) stw_raw(addr, data)
#define cpu_stl_kernel(env, addr, data) stl_raw(addr, data)
#define cpu_stq_kernel(env, addr, data) stq_raw(addr, data)
#endif
#define ldub_kernel(p) ldub_raw(p)
#define ldsb_kernel(p) ldsb_raw(p)
@@ -313,7 +304,6 @@ extern unsigned long reserved_va;
#define stfl_kernel(p, v) stfl_raw(p, v)
#define stfq_kernel(p, vt) stfq_raw(p, v)
#ifdef CONFIG_TCG_PASS_AREG0
#define cpu_ldub_data(env, addr) ldub_raw(addr)
#define cpu_lduw_data(env, addr) lduw_raw(addr)
#define cpu_ldl_data(env, addr) ldl_raw(addr)
@@ -321,7 +311,6 @@ extern unsigned long reserved_va;
#define cpu_stb_data(env, addr, data) stb_raw(addr, data)
#define cpu_stw_data(env, addr, data) stw_raw(addr, data)
#define cpu_stl_data(env, addr, data) stl_raw(addr, data)
#endif
#endif /* defined(CONFIG_USER_ONLY) */
/* page related stuff */

View File

@@ -325,11 +325,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
mmu_idx = cpu_mmu_index(env1);
if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code !=
(addr & TARGET_PAGE_MASK))) {
#ifdef CONFIG_TCG_PASS_AREG0
cpu_ldub_code(env1, addr);
#else
ldub_code(addr);
#endif
}
pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
mr = iotlb_to_region(pd);
@@ -348,7 +344,6 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
#define MMUSUFFIX _cmmu
#undef GETPC
#define GETPC() ((uintptr_t)0)
#define env cpu_single_env
#define SOFTMMU_CODE_ACCESS
#define SHIFT 0

View File

@@ -115,7 +115,7 @@ time_t mktimegm(struct tm *tm)
m += 12;
y--;
}
t = 86400 * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 +
t = 86400ULL * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 +
y / 400 - 719469);
t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
return t;

View File

@@ -128,6 +128,8 @@
#define DEF_HELPER_5(name, ret, t1, t2, t3, t4, t5) \
DEF_HELPER_FLAGS_5(name, 0, ret, t1, t2, t3, t4, t5)
/* MAX_OPC_PARAM_IARGS must be set to n if last entry is DEF_HELPER_FLAGS_n. */
#endif /* DEF_HELPER_H */
#ifndef GEN_HELPER

View File

@@ -6,7 +6,6 @@ CONFIG_M48T59=y
CONFIG_PTIMER=y
CONFIG_VGA=y
CONFIG_VGA_PCI=y
CONFIG_VGA_CIRRUS=y
CONFIG_SERIAL=y
CONFIG_PARALLEL=y
CONFIG_PCKBD=y

View File

@@ -316,9 +316,7 @@ void disas(FILE *out, void *code, unsigned long size)
print_insn = print_insn_alpha;
#elif defined(__sparc__)
print_insn = print_insn_sparc;
#if defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
disasm_info.mach = bfd_mach_sparc_v9b;
#endif
#elif defined(__arm__)
print_insn = print_insn_arm;
#elif defined(__MIPSEB__)

View File

@@ -31,7 +31,7 @@ Arguments:
Returns:
H_SUCCESS : Successully called the RTAS function (RTAS result
H_SUCCESS : Successfully called the RTAS function (RTAS result
will have been stored in the parameter block)
H_PARAMETER : Unknown token

View File

@@ -58,11 +58,11 @@ try ...
xhci controller support
-----------------------
There also is xhci host controller support available. It got alot
There is also xhci host controller support available. It got a lot
less testing than ehci and there are a bunch of known limitations, so
ehci may work better for you. On the other hand the xhci hardware
design is much more virtualization-friendly, thus xhci emulation uses
less ressources (especially cpu). If you wanna give xhci a try
less resources (especially cpu). If you want to give xhci a try
use this to add the host controller ...
qemu -device nec-usb-xhci,id=xhci

View File

@@ -1,70 +0,0 @@
/*
* dyngen defines for micro operation code
*
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__DYNGEN_EXEC_H__)
#define __DYNGEN_EXEC_H__
#if defined(CONFIG_TCG_INTERPRETER)
/* The TCG interpreter does not need a special register AREG0,
* but it is possible to use one by defining AREG0.
* On i386, register edi seems to work. */
/* Run without special register AREG0 or use a value defined elsewhere. */
#elif defined(__i386__)
#define AREG0 "ebp"
#elif defined(__x86_64__)
#define AREG0 "r14"
#elif defined(_ARCH_PPC)
#define AREG0 "r27"
#elif defined(__arm__)
#define AREG0 "r6"
#elif defined(__hppa__)
#define AREG0 "r17"
#elif defined(__mips__)
#define AREG0 "s0"
#elif defined(__sparc__)
#ifdef CONFIG_SOLARIS
#define AREG0 "g2"
#else
#ifdef __sparc_v9__
#define AREG0 "g5"
#else
#define AREG0 "g6"
#endif
#endif
#elif defined(__s390__)
#define AREG0 "r10"
#elif defined(__alpha__)
/* Note $15 is the frame pointer, so anything in op-i386.c that would
require a frame pointer, like alloca, would probably loose. */
#define AREG0 "$15"
#elif defined(__mc68000)
#define AREG0 "%a5"
#elif defined(__ia64__)
#define AREG0 "r7"
#else
#error unsupported CPU
#endif
#if defined(AREG0)
register CPUArchState *env asm(AREG0);
#else
/* TODO: Try env = cpu_single_env. */
extern CPUArchState *env;
#endif
#endif /* !defined(__DYNGEN_EXEC_H__) */

View File

@@ -51,7 +51,7 @@ typedef struct TranslationBlock TranslationBlock;
#else
#define MAX_OPC_PARAM_PER_ARG 1
#endif
#define MAX_OPC_PARAM_IARGS 4
#define MAX_OPC_PARAM_IARGS 5
#define MAX_OPC_PARAM_OARGS 1
#define MAX_OPC_PARAM_ARGS (MAX_OPC_PARAM_IARGS + MAX_OPC_PARAM_OARGS)
@@ -132,9 +132,10 @@ static inline void tlb_flush(CPUArchState *env, int flush_global)
#define CODE_GEN_AVG_BLOCK_SIZE 64
#endif
#if defined(_ARCH_PPC) || defined(__x86_64__) || defined(__arm__) || defined(__i386__)
#define USE_DIRECT_JUMP
#elif defined(CONFIG_TCG_INTERPRETER)
#if defined(__arm__) || defined(_ARCH_PPC) \
|| defined(__x86_64__) || defined(__i386__) \
|| defined(__sparc__) \
|| defined(CONFIG_TCG_INTERPRETER)
#define USE_DIRECT_JUMP
#endif
@@ -244,6 +245,8 @@ static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
__asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
#endif
}
#elif defined(__sparc__)
void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr);
#else
#error tb_set_jmp_target1 is missing
#endif
@@ -323,9 +326,6 @@ void tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx,
#define ACCESS_TYPE (NB_MMU_MODES + 1)
#define MEMSUFFIX _code
#ifndef CONFIG_TCG_PASS_AREG0
#define env cpu_single_env
#endif
#define DATA_SIZE 1
#include "softmmu_header.h"
@@ -341,7 +341,6 @@ void tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx,
#undef ACCESS_TYPE
#undef MEMSUFFIX
#undef env
#endif

19
exec.c
View File

@@ -86,7 +86,7 @@ static int nb_tbs;
/* any access to the tbs or the page table must use this lock */
spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
#if defined(__arm__) || defined(__sparc_v9__)
#if defined(__arm__) || defined(__sparc__)
/* The prologue must be reachable with a direct jump. ARM and Sparc64
have limited branch ranges (possibly also PPC) so place it in a
section close to code segment. */
@@ -541,10 +541,9 @@ static void code_gen_alloc(unsigned long tb_size)
/* Cannot map more than that */
if (code_gen_buffer_size > (800 * 1024 * 1024))
code_gen_buffer_size = (800 * 1024 * 1024);
#elif defined(__sparc_v9__)
#elif defined(__sparc__) && HOST_LONG_BITS == 64
// Map the buffer below 2G, so we can use direct calls and branches
flags |= MAP_FIXED;
start = (void *) 0x60000000UL;
start = (void *) 0x40000000UL;
if (code_gen_buffer_size > (512 * 1024 * 1024))
code_gen_buffer_size = (512 * 1024 * 1024);
#elif defined(__arm__)
@@ -582,10 +581,9 @@ static void code_gen_alloc(unsigned long tb_size)
/* Cannot map more than that */
if (code_gen_buffer_size > (800 * 1024 * 1024))
code_gen_buffer_size = (800 * 1024 * 1024);
#elif defined(__sparc_v9__)
#elif defined(__sparc__) && HOST_LONG_BITS == 64
// Map the buffer below 2G, so we can use direct calls and branches
flags |= MAP_FIXED;
addr = (void *) 0x60000000UL;
addr = (void *) 0x40000000UL;
if (code_gen_buffer_size > (512 * 1024 * 1024)) {
code_gen_buffer_size = (512 * 1024 * 1024);
}
@@ -3523,6 +3521,13 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
/* ROM/RAM case */
ptr = qemu_get_ram_ptr(addr1);
memcpy(ptr, buf, l);
if (!cpu_physical_memory_is_dirty(addr1)) {
/* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
/* set dirty bit */
cpu_physical_memory_set_dirty_flags(
addr1, (0xff & ~CODE_DIRTY_FLAG));
}
qemu_put_ram_ptr(ptr);
}
len -= l;

View File

@@ -1238,7 +1238,7 @@ float32 uint64_to_float32( uint64 a STATUS_PARAM )
if ( a == 0 ) return float32_zero;
shiftCount = countLeadingZeros64( a ) - 40;
if ( 0 <= shiftCount ) {
return packFloat32( 1 > 0, 0x95 - shiftCount, a<<shiftCount );
return packFloat32(0, 0x95 - shiftCount, a<<shiftCount);
}
else {
shiftCount += 7;
@@ -1248,7 +1248,7 @@ float32 uint64_to_float32( uint64 a STATUS_PARAM )
else {
a <<= shiftCount;
}
return roundAndPackFloat32( 1 > 0, 0x9C - shiftCount, a STATUS_VAR );
return roundAndPackFloat32(0, 0x9C - shiftCount, a STATUS_VAR);
}
}

148
gdbstub.c
View File

@@ -1226,33 +1226,48 @@ static int cpu_gdb_write_register(CPUOpenRISCState *env,
static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n)
{
if (n < 8) {
switch (n) {
case 0 ... 7:
if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
GET_REGL(env->gregs[n + 16]);
} else {
GET_REGL(env->gregs[n]);
}
} else if (n < 16) {
case 8 ... 15:
GET_REGL(env->gregs[n]);
} else if (n >= 25 && n < 41) {
GET_REGL(env->fregs[(n - 25) + ((env->fpscr & FPSCR_FR) ? 16 : 0)]);
} else if (n >= 43 && n < 51) {
GET_REGL(env->gregs[n - 43]);
} else if (n >= 51 && n < 59) {
GET_REGL(env->gregs[n - (51 - 16)]);
}
switch (n) {
case 16: GET_REGL(env->pc);
case 17: GET_REGL(env->pr);
case 18: GET_REGL(env->gbr);
case 19: GET_REGL(env->vbr);
case 20: GET_REGL(env->mach);
case 21: GET_REGL(env->macl);
case 22: GET_REGL(env->sr);
case 23: GET_REGL(env->fpul);
case 24: GET_REGL(env->fpscr);
case 41: GET_REGL(env->ssr);
case 42: GET_REGL(env->spc);
case 16:
GET_REGL(env->pc);
case 17:
GET_REGL(env->pr);
case 18:
GET_REGL(env->gbr);
case 19:
GET_REGL(env->vbr);
case 20:
GET_REGL(env->mach);
case 21:
GET_REGL(env->macl);
case 22:
GET_REGL(env->sr);
case 23:
GET_REGL(env->fpul);
case 24:
GET_REGL(env->fpscr);
case 25 ... 40:
if (env->fpscr & FPSCR_FR) {
stfl_p(mem_buf, env->fregs[n - 9]);
} else {
stfl_p(mem_buf, env->fregs[n - 25]);
}
return 4;
case 41:
GET_REGL(env->ssr);
case 42:
GET_REGL(env->spc);
case 43 ... 50:
GET_REGL(env->gregs[n - 43]);
case 51 ... 58:
GET_REGL(env->gregs[n - (51 - 16)]);
}
return 0;
@@ -1260,42 +1275,63 @@ static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n)
static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n)
{
uint32_t tmp;
tmp = ldl_p(mem_buf);
if (n < 8) {
if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
env->gregs[n + 16] = tmp;
} else {
env->gregs[n] = tmp;
}
return 4;
} else if (n < 16) {
env->gregs[n] = tmp;
return 4;
} else if (n >= 25 && n < 41) {
env->fregs[(n - 25) + ((env->fpscr & FPSCR_FR) ? 16 : 0)] = tmp;
return 4;
} else if (n >= 43 && n < 51) {
env->gregs[n - 43] = tmp;
return 4;
} else if (n >= 51 && n < 59) {
env->gregs[n - (51 - 16)] = tmp;
return 4;
}
switch (n) {
case 16: env->pc = tmp; break;
case 17: env->pr = tmp; break;
case 18: env->gbr = tmp; break;
case 19: env->vbr = tmp; break;
case 20: env->mach = tmp; break;
case 21: env->macl = tmp; break;
case 22: env->sr = tmp; break;
case 23: env->fpul = tmp; break;
case 24: env->fpscr = tmp; break;
case 41: env->ssr = tmp; break;
case 42: env->spc = tmp; break;
case 0 ... 7:
if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
env->gregs[n + 16] = ldl_p(mem_buf);
} else {
env->gregs[n] = ldl_p(mem_buf);
}
break;
case 8 ... 15:
env->gregs[n] = ldl_p(mem_buf);
break;
case 16:
env->pc = ldl_p(mem_buf);
break;
case 17:
env->pr = ldl_p(mem_buf);
break;
case 18:
env->gbr = ldl_p(mem_buf);
break;
case 19:
env->vbr = ldl_p(mem_buf);
break;
case 20:
env->mach = ldl_p(mem_buf);
break;
case 21:
env->macl = ldl_p(mem_buf);
break;
case 22:
env->sr = ldl_p(mem_buf);
break;
case 23:
env->fpul = ldl_p(mem_buf);
break;
case 24:
env->fpscr = ldl_p(mem_buf);
break;
case 25 ... 40:
if (env->fpscr & FPSCR_FR) {
env->fregs[n - 9] = ldfl_p(mem_buf);
} else {
env->fregs[n - 25] = ldfl_p(mem_buf);
}
break;
case 41:
env->ssr = ldl_p(mem_buf);
break;
case 42:
env->spc = ldl_p(mem_buf);
break;
case 43 ... 50:
env->gregs[n - 43] = ldl_p(mem_buf);
break;
case 51 ... 58:
env->gregs[n - (51 - 16)] = ldl_p(mem_buf);
break;
default: return 0;
}

View File

@@ -512,9 +512,9 @@ STEXI
@item sendkey @var{keys}
@findex sendkey
Send @var{keys} to the emulator. @var{keys} could be the name of the
key or @code{#} followed by the raw value in either decimal or hexadecimal
format. Use @code{-} to press several keys simultaneously. Example:
Send @var{keys} to the guest. @var{keys} could be the name of the
key or the raw value in hexadecimal format. Use @code{-} to press
several keys simultaneously. Example:
@example
sendkey ctrl-alt-f1
@end example

2
hmp.c
View File

@@ -413,6 +413,8 @@ void hmp_info_spice(Monitor *mon)
monitor_printf(mon, " address: %s:%" PRId64 " [tls]\n",
info->host, info->tls_port);
}
monitor_printf(mon, " migrated: %s\n",
info->migrated ? "true" : "false");
monitor_printf(mon, " auth: %s\n", info->auth);
monitor_printf(mon, " compiled: %s\n", info->compiled_version);
monitor_printf(mon, " mouse-mode: %s\n",

View File

@@ -489,7 +489,8 @@ static int armv7m_nvic_init(SysBusDevice *dev)
*/
memory_region_init_alias(&s->gic_iomem_alias, "nvic-gic", &s->gic.iomem,
0x100, 0xc00);
memory_region_add_subregion_overlap(&s->container, 0x100, &s->gic.iomem, 1);
memory_region_add_subregion_overlap(&s->container, 0x100,
&s->gic_iomem_alias, 1);
/* Map the whole thing into system memory at the location required
* by the v7M architecture.
*/

View File

@@ -404,7 +404,7 @@ static uint64_t uart_read(void *opaque, target_phys_addr_t offset,
uint32_t c = 0;
offset >>= 2;
if (offset > R_MAX) {
if (offset >= R_MAX) {
return 0;
} else if (offset == R_TX_RX) {
uart_read_rx_fifo(s, &c);

View File

@@ -59,6 +59,9 @@ static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL);
#define PNPMMIO_SIZE 0x20000
#define MIN_BUF_SIZE 60 /* Min. octets in an ethernet frame sans FCS */
/* this is the size past which hardware will drop packets when setting LPE=0 */
#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
/*
* HW models:
* E1000_DEV_ID_82540EM works with Windows and Linux
@@ -92,7 +95,6 @@ typedef struct E1000State_st {
uint32_t rxbuf_size;
uint32_t rxbuf_min_shift;
int check_rxov;
struct e1000_tx {
unsigned char header[256];
unsigned char vlan_header[4];
@@ -295,6 +297,7 @@ set_rx_control(E1000State *s, int index, uint32_t val)
s->rxbuf_min_shift = ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1;
DBGOUT(RX, "RCTL: %d, mac_reg[RCTL] = 0x%x\n", s->mac_reg[RDT],
s->mac_reg[RCTL]);
qemu_flush_queued_packets(&s->nic->nc);
}
static void
@@ -740,11 +743,11 @@ static bool e1000_has_rxbufs(E1000State *s, size_t total_size)
int bufs;
/* Fast-path short packets */
if (total_size <= s->rxbuf_size) {
return s->mac_reg[RDH] != s->mac_reg[RDT] || !s->check_rxov;
return s->mac_reg[RDH] != s->mac_reg[RDT];
}
if (s->mac_reg[RDH] < s->mac_reg[RDT]) {
bufs = s->mac_reg[RDT] - s->mac_reg[RDH];
} else if (s->mac_reg[RDH] > s->mac_reg[RDT] || !s->check_rxov) {
} else if (s->mac_reg[RDH] > s->mac_reg[RDT]) {
bufs = s->mac_reg[RDLEN] / sizeof(struct e1000_rx_desc) +
s->mac_reg[RDT] - s->mac_reg[RDH];
} else {
@@ -795,6 +798,13 @@ e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size)
size = sizeof(min_buf);
}
/* Discard oversized packets if !LPE and !SBP. */
if (size > MAXIMUM_ETHERNET_VLAN_SIZE
&& !(s->mac_reg[RCTL] & E1000_RCTL_LPE)
&& !(s->mac_reg[RCTL] & E1000_RCTL_SBP)) {
return size;
}
if (!receive_filter(s, buf, size))
return size;
@@ -847,7 +857,6 @@ e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size)
if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
s->mac_reg[RDH] = 0;
s->check_rxov = 1;
/* see comment in start_xmit; same here */
if (s->mac_reg[RDH] == rdh_start) {
DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
@@ -924,8 +933,10 @@ mac_writereg(E1000State *s, int index, uint32_t val)
static void
set_rdt(E1000State *s, int index, uint32_t val)
{
s->check_rxov = 0;
s->mac_reg[index] = val & 0xffff;
if (e1000_has_rxbufs(s, 1)) {
qemu_flush_queued_packets(&s->nic->nc);
}
}
static void

View File

@@ -1036,6 +1036,7 @@ static void eepro100_ru_command(EEPRO100State * s, uint8_t val)
}
set_ru_state(s, ru_ready);
s->ru_offset = e100_read_reg4(s, SCBPointer);
qemu_flush_queued_packets(&s->nic->nc);
TRACE(OTHER, logout("val=0x%02x (rx start)\n", val));
break;
case RX_RESUME:
@@ -1770,7 +1771,8 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size)
if (rfd_command & COMMAND_EL) {
/* EL bit is set, so this was the last frame. */
logout("receive: Running out of frames\n");
set_ru_state(s, ru_suspended);
set_ru_state(s, ru_no_resources);
eepro100_rnr_interrupt(s);
}
if (rfd_command & COMMAND_S) {
/* S bit is set. */

View File

@@ -269,6 +269,17 @@ static int glue(load_elf, SZ)(const char *name, int fd,
addr = ph->p_paddr;
}
/* the entry pointer in the ELF header is a virtual
* address, if the text segments paddr and vaddr differ
* we need to adjust the entry */
if (pentry && !translate_fn &&
ph->p_vaddr != ph->p_paddr &&
ehdr.e_entry >= ph->p_vaddr &&
ehdr.e_entry < ph->p_vaddr + ph->p_filesz &&
ph->p_flags & PF_X) {
*pentry = ehdr.e_entry - ph->p_vaddr + ph->p_paddr;
}
snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
rom_add_blob_fixed(label, data, mem_size, addr);

View File

@@ -1175,7 +1175,6 @@ void ahci_init(AHCIState *s, DeviceState *qdev, DMAContext *dma, int ports)
ad->port_no = i;
ad->port.dma = &ad->dma;
ad->port.dma->ops = &ahci_dma_ops;
ad->port_regs.cmd = PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON;
}
}
@@ -1199,6 +1198,7 @@ void ahci_reset(AHCIState *s)
pr->irq_stat = 0;
pr->irq_mask = 0;
pr->scr_ctl = 0;
pr->cmd = PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON;
ahci_reset_port(s, i);
}
}

View File

@@ -53,8 +53,6 @@ static const int smart_attributes[][12] = {
{ 0x0c, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
/* airflow-temperature-celsius */
{ 190, 0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x32},
/* end of list */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
};
static int ide_handle_rw_error(IDEState *s, int error, int op);
@@ -1468,9 +1466,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
case SMART_READ_THRESH:
memset(s->io_buffer, 0, 0x200);
s->io_buffer[0] = 0x01; /* smart struct version */
for (n=0; n<30; n++) {
if (smart_attributes[n][0] == 0)
break;
for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {
s->io_buffer[2+0+(n*12)] = smart_attributes[n][0];
s->io_buffer[2+1+(n*12)] = smart_attributes[n][11];
}
@@ -1484,10 +1480,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
case SMART_READ_DATA:
memset(s->io_buffer, 0, 0x200);
s->io_buffer[0] = 0x01; /* smart struct version */
for (n=0; n<30; n++) {
if (smart_attributes[n][0] == 0) {
break;
}
for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {
int i;
for(i = 0; i < 11; i++) {
s->io_buffer[2+i+(n*12)] = smart_attributes[n][i];

View File

@@ -125,7 +125,6 @@ static int ioh3420_initfn(PCIDevice *d)
rc = pcie_chassis_add_slot(s);
if (rc < 0) {
goto err_pcie_cap;
return rc;
}
pcie_cap_root_init(d);
rc = pcie_aer_init(d, IOH_EP_AER_OFFSET);

View File

@@ -500,7 +500,7 @@ static int lan9118_filter(lan9118_state *s, const uint8_t *addr)
}
} else {
/* Hash matching */
hash = (crc32(~0, addr, 6) >> 26);
hash = compute_mcast_idx(addr);
if (hash & 0x20) {
return (s->mac_hashh >> (hash & 0x1f)) & 1;
} else {

View File

@@ -224,7 +224,7 @@ uint32_t lm4549_write_samples(lm4549_state *s, uint32_t left, uint32_t right)
This model supports 16-bit playback.
*/
if (s->buffer_level >= LM4549_BUFFER_SIZE) {
if (s->buffer_level > LM4549_BUFFER_SIZE - 2) {
DPRINTF("write_sample Buffer full\n");
return 0;
}

View File

@@ -378,7 +378,7 @@ static uint32_t m5206_mbar_readb(void *opaque, target_phys_addr_t offset)
{
m5206_mbar_state *s = (m5206_mbar_state *)opaque;
offset &= 0x3ff;
if (offset > 0x200) {
if (offset >= 0x200) {
hw_error("Bad MBAR read offset 0x%x", (int)offset);
}
if (m5206_mbar_width[offset >> 2] > 1) {
@@ -397,7 +397,7 @@ static uint32_t m5206_mbar_readw(void *opaque, target_phys_addr_t offset)
m5206_mbar_state *s = (m5206_mbar_state *)opaque;
int width;
offset &= 0x3ff;
if (offset > 0x200) {
if (offset >= 0x200) {
hw_error("Bad MBAR read offset 0x%x", (int)offset);
}
width = m5206_mbar_width[offset >> 2];
@@ -421,7 +421,7 @@ static uint32_t m5206_mbar_readl(void *opaque, target_phys_addr_t offset)
m5206_mbar_state *s = (m5206_mbar_state *)opaque;
int width;
offset &= 0x3ff;
if (offset > 0x200) {
if (offset >= 0x200) {
hw_error("Bad MBAR read offset 0x%x", (int)offset);
}
width = m5206_mbar_width[offset >> 2];
@@ -445,7 +445,7 @@ static void m5206_mbar_writeb(void *opaque, target_phys_addr_t offset,
m5206_mbar_state *s = (m5206_mbar_state *)opaque;
int width;
offset &= 0x3ff;
if (offset > 0x200) {
if (offset >= 0x200) {
hw_error("Bad MBAR write offset 0x%x", (int)offset);
}
width = m5206_mbar_width[offset >> 2];
@@ -469,7 +469,7 @@ static void m5206_mbar_writew(void *opaque, target_phys_addr_t offset,
m5206_mbar_state *s = (m5206_mbar_state *)opaque;
int width;
offset &= 0x3ff;
if (offset > 0x200) {
if (offset >= 0x200) {
hw_error("Bad MBAR write offset 0x%x", (int)offset);
}
width = m5206_mbar_width[offset >> 2];
@@ -497,7 +497,7 @@ static void m5206_mbar_writel(void *opaque, target_phys_addr_t offset,
m5206_mbar_state *s = (m5206_mbar_state *)opaque;
int width;
offset &= 0x3ff;
if (offset > 0x200) {
if (offset >= 0x200) {
hw_error("Bad MBAR write offset 0x%x", (int)offset);
}
width = m5206_mbar_width[offset >> 2];

View File

@@ -860,7 +860,8 @@ void mips_malta_init (ram_addr_t ram_size,
be = 0;
#endif
/* FPGA */
malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[2], serial_hds[2]);
/* The CBUS UART is attached to the MIPS CPU INT2 pin, ie interrupt 4 */
malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[4], serial_hds[2]);
/* Load firmware in flash / BIOS. */
dinfo = drive_get(IF_PFLASH, 0, fl_idx);

View File

@@ -1583,7 +1583,7 @@ static void musicpal_init(ram_addr_t ram_size,
* image is smaller than 32 MB.
*/
#ifdef TARGET_WORDS_BIGENDIAN
pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, NULL,
pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
"musicpal.flash", flash_size,
dinfo->bdrv, 0x10000,
(flash_size + 0xffff) >> 16,
@@ -1591,7 +1591,7 @@ static void musicpal_init(ram_addr_t ram_size,
2, 0x00BF, 0x236D, 0x0000, 0x0000,
0x5555, 0x2AAA, 1);
#else
pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, NULL,
pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
"musicpal.flash", flash_size,
dinfo->bdrv, 0x10000,
(flash_size + 0xffff) >> 16,

View File

@@ -654,7 +654,7 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s)
sector = SECTOR(s->addr);
off = (s->addr & PAGE_MASK) + s->offset;
soff = SECTOR_OFFSET(s->addr);
if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS) == -1) {
if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS) < 0) {
printf("%s: read error in sector %" PRIu64 "\n", __func__, sector);
return;
}
@@ -666,21 +666,23 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s)
MIN(OOB_SIZE, off + s->iolen - PAGE_SIZE));
}
if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS) == -1)
if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS) < 0) {
printf("%s: write error in sector %" PRIu64 "\n", __func__, sector);
}
} else {
off = PAGE_START(s->addr) + (s->addr & PAGE_MASK) + s->offset;
sector = off >> 9;
soff = off & 0x1ff;
if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) == -1) {
if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) < 0) {
printf("%s: read error in sector %" PRIu64 "\n", __func__, sector);
return;
}
mem_and(iobuf + soff, s->io, s->iolen);
if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) == -1)
if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) < 0) {
printf("%s: write error in sector %" PRIu64 "\n", __func__, sector);
}
}
s->offset = 0;
}
@@ -704,31 +706,37 @@ static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s)
i = SECTOR(addr);
page = SECTOR(addr + (ADDR_SHIFT + s->erase_shift));
for (; i < page; i ++)
if (bdrv_write(s->bdrv, i, iobuf, 1) == -1)
if (bdrv_write(s->bdrv, i, iobuf, 1) < 0) {
printf("%s: write error in sector %" PRIu64 "\n", __func__, i);
}
} else {
addr = PAGE_START(addr);
page = addr >> 9;
if (bdrv_read(s->bdrv, page, iobuf, 1) == -1)
if (bdrv_read(s->bdrv, page, iobuf, 1) < 0) {
printf("%s: read error in sector %" PRIu64 "\n", __func__, page);
}
memset(iobuf + (addr & 0x1ff), 0xff, (~addr & 0x1ff) + 1);
if (bdrv_write(s->bdrv, page, iobuf, 1) == -1)
if (bdrv_write(s->bdrv, page, iobuf, 1) < 0) {
printf("%s: write error in sector %" PRIu64 "\n", __func__, page);
}
memset(iobuf, 0xff, 0x200);
i = (addr & ~0x1ff) + 0x200;
for (addr += ((PAGE_SIZE + OOB_SIZE) << s->erase_shift) - 0x200;
i < addr; i += 0x200)
if (bdrv_write(s->bdrv, i >> 9, iobuf, 1) == -1)
if (bdrv_write(s->bdrv, i >> 9, iobuf, 1) < 0) {
printf("%s: write error in sector %" PRIu64 "\n",
__func__, i >> 9);
}
page = i >> 9;
if (bdrv_read(s->bdrv, page, iobuf, 1) == -1)
if (bdrv_read(s->bdrv, page, iobuf, 1) < 0) {
printf("%s: read error in sector %" PRIu64 "\n", __func__, page);
}
memset(iobuf, 0xff, ((addr - 1) & 0x1ff) + 1);
if (bdrv_write(s->bdrv, page, iobuf, 1) == -1)
if (bdrv_write(s->bdrv, page, iobuf, 1) < 0) {
printf("%s: write error in sector %" PRIu64 "\n", __func__, page);
}
}
}
@@ -740,18 +748,20 @@ static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s,
if (s->bdrv) {
if (s->mem_oob) {
if (bdrv_read(s->bdrv, SECTOR(addr), s->io, PAGE_SECTORS) == -1)
if (bdrv_read(s->bdrv, SECTOR(addr), s->io, PAGE_SECTORS) < 0) {
printf("%s: read error in sector %" PRIu64 "\n",
__func__, SECTOR(addr));
}
memcpy(s->io + SECTOR_OFFSET(s->addr) + PAGE_SIZE,
s->storage + (PAGE(s->addr) << OOB_SHIFT),
OOB_SIZE);
s->ioaddr = s->io + SECTOR_OFFSET(s->addr) + offset;
} else {
if (bdrv_read(s->bdrv, PAGE_START(addr) >> 9,
s->io, (PAGE_SECTORS + 2)) == -1)
s->io, (PAGE_SECTORS + 2)) < 0) {
printf("%s: read error in sector %" PRIu64 "\n",
__func__, PAGE_START(addr) >> 9);
}
s->ioaddr = s->io + (PAGE_START(addr) & 0x1ff) + offset;
}
} else {

View File

@@ -351,7 +351,7 @@ static inline int onenand_erase(OneNANDState *s, int sec, int num)
for (; num > 0; num--, sec++) {
if (s->bdrv_cur) {
int erasesec = s->secs_cur + (sec >> 5);
if (bdrv_write(s->bdrv_cur, sec, blankbuf, 1)) {
if (bdrv_write(s->bdrv_cur, sec, blankbuf, 1) < 0) {
goto fail;
}
if (bdrv_read(s->bdrv_cur, erasesec, tmpbuf, 1) < 0) {

View File

@@ -80,7 +80,13 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
SCSIBus *scsibus;
SCSIDevice *scsidev;
scsibus = SCSI_BUS(QLIST_FIRST(&adapter->child_bus));
scsibus = (SCSIBus *)
object_dynamic_cast(OBJECT(QLIST_FIRST(&adapter->child_bus)),
TYPE_SCSI_BUS);
if (!scsibus) {
error_report("Device is not a SCSI adapter");
return -1;
}
/*
* drive_init() tries to find a default for dinfo->unit. Doesn't

View File

@@ -439,7 +439,7 @@ const VMStateDescription vmstate_pci_device = {
};
const VMStateDescription vmstate_pcie_device = {
.name = "PCIDevice",
.name = "PCIEDevice",
.version_id = 2,
.minimum_version_id = 1,
.minimum_version_id_old = 1,

View File

@@ -133,7 +133,6 @@ extern const VMStateDescription vmstate_pcie_device;
#define VMSTATE_PCIE_DEVICE(_field, _state) { \
.name = (stringify(_field)), \
.version_id = 2, \
.size = sizeof(PCIDevice), \
.vmsd = &vmstate_pcie_device, \
.flags = VMS_STRUCT, \

View File

@@ -738,6 +738,11 @@ void pcie_aer_root_init(PCIDevice *dev)
PCI_ERR_ROOT_CMD_EN_MASK);
pci_set_long(dev->w1cmask + pos + PCI_ERR_ROOT_STATUS,
PCI_ERR_ROOT_STATUS_REPORT_MASK);
/* PCI_ERR_ROOT_IRQ is RO but devices change it using a
* device-specific method.
*/
pci_set_long(dev->cmask + pos + PCI_ERR_ROOT_STATUS,
~PCI_ERR_ROOT_IRQ);
}
void pcie_aer_root_reset(PCIDevice *dev)

View File

@@ -320,7 +320,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
}
pfl->wcycle++;
pfl->cmd = cmd;
return;
break;
case 1:
switch (pfl->cmd) {
case 0x10: /* Single Byte Program */
@@ -375,7 +375,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
default:
goto error_flash;
}
return;
break;
case 2:
switch (pfl->cmd) {
case 0xe8: /* Block write */
@@ -406,7 +406,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
default:
goto error_flash;
}
return;
break;
case 3: /* Confirm mode */
switch (pfl->cmd) {
case 0xe8: /* Block write */
@@ -422,7 +422,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
default:
goto error_flash;
}
return;
break;
default:
/* Should never happen */
DPRINTF("%s: invalid write state\n", __func__);
@@ -711,7 +711,7 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base,
pfl->cfi_table[0x33] = 'I';
pfl->cfi_table[0x34] = '1';
pfl->cfi_table[0x35] = '1';
pfl->cfi_table[0x35] = '0';
pfl->cfi_table[0x36] = 0x00;
pfl->cfi_table[0x37] = 0x00;
@@ -723,6 +723,8 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base,
pfl->cfi_table[0x3b] = 0x00;
pfl->cfi_table[0x3c] = 0x00;
pfl->cfi_table[0x3f] = 0x01; /* Number of protection fields */
return pfl;
}

View File

@@ -117,12 +117,18 @@ static uint64_t pl190_read(void *opaque, target_phys_addr_t offset,
return s->protected;
case 12: /* VECTADDR */
/* Read vector address at the start of an ISR. Increases the
current priority level to that of the current interrupt. */
for (i = 0; i < s->priority; i++)
{
if ((s->level | s->soft_level) & s->prio_mask[i])
break;
}
* current priority level to that of the current interrupt.
*
* Since an enabled interrupt X at priority P causes prio_mask[Y]
* to have bit X set for all Y > P, this loop will stop with
* i == the priority of the highest priority set interrupt.
*/
for (i = 0; i < s->priority; i++) {
if ((s->level | s->soft_level) & s->prio_mask[i + 1]) {
break;
}
}
/* Reading this value with no pending interrupts is undefined.
We return the default address. */
if (i == PL190_NUM_PRIO)

View File

@@ -59,7 +59,7 @@ static int bamboo_load_device_tree(target_phys_addr_t addr,
{
int ret = -1;
#ifdef CONFIG_FDT
uint32_t mem_reg_property[] = { 0, 0, ramsize };
uint32_t mem_reg_property[] = { 0, 0, cpu_to_be32(ramsize) };
char *filename;
int fdt_size;
void *fdt;

View File

@@ -99,7 +99,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
{
VGACommonState *vga = &qxl->vga;
int i;
DisplaySurface *surface = vga->ds->surface;
if (qxl->guest_primary.resized) {
qxl->guest_primary.resized = 0;
@@ -112,9 +111,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
qxl->guest_primary.qxl_stride,
qxl->guest_primary.bytes_pp,
qxl->guest_primary.bits_pp);
}
if (surface->width != qxl->guest_primary.surface.width ||
surface->height != qxl->guest_primary.surface.height) {
if (qxl->guest_primary.qxl_stride > 0) {
qemu_free_displaysurface(vga->ds);
qemu_create_displaysurface_from(qxl->guest_primary.surface.width,

138
hw/qxl.c
View File

@@ -27,6 +27,11 @@
#include "qxl.h"
#ifndef CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC
/* spice-protocol is too old, add missing definitions */
#define QXL_IO_MONITORS_CONFIG_ASYNC (QXL_IO_FLUSH_RELEASE + 1)
#endif
/*
* NOTE: SPICE_RING_PROD_ITEM accesses memory on the pci bar and as
* such can be changed by the guest, so to avoid a guest trigerrable
@@ -136,6 +141,7 @@ static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
{
trace_qxl_set_guest_bug(qxl->id);
qxl_send_events(qxl, QXL_INTERRUPT_ERROR);
qxl->guest_bug = 1;
if (qxl->guestdebug) {
@@ -196,6 +202,7 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, (uintptr_t)cookie);
} else {
qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
qxl_spice_destroy_surface_wait_complete(qxl, id);
}
}
@@ -249,6 +256,39 @@ static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
}
}
static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
{
trace_qxl_spice_monitors_config(qxl->id);
/* 0x000b01 == 0.11.1 */
#if SPICE_SERVER_VERSION >= 0x000b01 && \
defined(CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC)
if (replay) {
/*
* don't use QXL_COOKIE_TYPE_IO:
* - we are not running yet (post_load), we will assert
* in send_events
* - this is not a guest io, but a reply, so async_io isn't set.
*/
spice_qxl_monitors_config_async(&qxl->ssd.qxl,
qxl->guest_monitors_config,
MEMSLOT_GROUP_GUEST,
(uintptr_t)qxl_cookie_new(
QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,
0));
} else {
qxl->guest_monitors_config = qxl->ram->monitors_config;
spice_qxl_monitors_config_async(&qxl->ssd.qxl,
qxl->ram->monitors_config,
MEMSLOT_GROUP_GUEST,
(uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
QXL_IO_MONITORS_CONFIG_ASYNC));
}
#else
fprintf(stderr, "qxl: too old spice-protocol/spice-server for "
"QXL_IO_MONITORS_CONFIG_ASYNC\n");
#endif
}
void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
{
trace_qxl_spice_reset_image_cache(qxl->id);
@@ -538,6 +578,7 @@ static const char *io_port_to_string(uint32_t io_port)
= "QXL_IO_DESTROY_ALL_SURFACES_ASYNC",
[QXL_IO_FLUSH_SURFACES_ASYNC] = "QXL_IO_FLUSH_SURFACES_ASYNC",
[QXL_IO_FLUSH_RELEASE] = "QXL_IO_FLUSH_RELEASE",
[QXL_IO_MONITORS_CONFIG_ASYNC] = "QXL_IO_MONITORS_CONFIG_ASYNC",
};
return io_port_to_string[io_port];
}
@@ -819,6 +860,7 @@ static void interface_async_complete_io(PCIQXLDevice *qxl, QXLCookie *cookie)
case QXL_IO_DESTROY_PRIMARY_ASYNC:
case QXL_IO_UPDATE_AREA_ASYNC:
case QXL_IO_FLUSH_SURFACES_ASYNC:
case QXL_IO_MONITORS_CONFIG_ASYNC:
break;
case QXL_IO_CREATE_PRIMARY_ASYNC:
qxl_create_guest_primary_complete(qxl);
@@ -894,6 +936,8 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
case QXL_COOKIE_TYPE_RENDER_UPDATE_AREA:
qxl_render_update_area_done(qxl, cookie);
break;
case QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG:
break;
default:
fprintf(stderr, "qxl: %s: unexpected cookie type %d\n",
__func__, cookie->type);
@@ -958,9 +1002,10 @@ static void qxl_update_irq(PCIQXLDevice *d)
static void qxl_check_state(PCIQXLDevice *d)
{
QXLRam *ram = d->ram;
int spice_display_running = qemu_spice_display_is_running(&d->ssd);
assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cmd_ring));
assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cursor_ring));
assert(!spice_display_running || SPICE_RING_IS_EMPTY(&ram->cmd_ring));
assert(!spice_display_running || SPICE_RING_IS_EMPTY(&ram->cursor_ring));
}
static void qxl_reset_state(PCIQXLDevice *d)
@@ -1314,6 +1359,13 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
return;
}
if (d->revision <= QXL_REVISION_STABLE_V10 &&
io_port >= QXL_IO_FLUSH_SURFACES_ASYNC) {
qxl_set_guest_bug(d, "unsupported io %d for revision %d\n",
io_port, d->revision);
return;
}
switch (io_port) {
case QXL_IO_RESET:
case QXL_IO_SET_MODE:
@@ -1330,10 +1382,10 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
break;
}
trace_qxl_io_unexpected_vga_mode(d->id,
io_port, io_port_to_string(io_port));
addr, val, io_port_to_string(io_port));
/* be nice to buggy guest drivers */
if (io_port >= QXL_IO_UPDATE_AREA_ASYNC &&
io_port <= QXL_IO_DESTROY_ALL_SURFACES_ASYNC) {
io_port < QXL_IO_RANGE_SIZE) {
qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
}
return;
@@ -1361,6 +1413,7 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
io_port = QXL_IO_DESTROY_ALL_SURFACES;
goto async_common;
case QXL_IO_FLUSH_SURFACES_ASYNC:
case QXL_IO_MONITORS_CONFIG_ASYNC:
async_common:
async = QXL_ASYNC;
qemu_mutex_lock(&d->async_lock);
@@ -1385,6 +1438,25 @@ async_common:
QXLCookie *cookie = NULL;
QXLRect update = d->ram->update_area;
if (d->ram->update_surface > NUM_SURFACES) {
qxl_set_guest_bug(d, "QXL_IO_UPDATE_AREA: invalid surface id %d\n",
d->ram->update_surface);
return;
}
if (update.left >= update.right || update.top >= update.bottom) {
qxl_set_guest_bug(d,
"QXL_IO_UPDATE_AREA: invalid area (%ux%u)x(%ux%u)\n",
update.left, update.top, update.right, update.bottom);
return;
}
if (update.left < 0 || update.top < 0 || update.left >= update.right ||
update.top >= update.bottom) {
qxl_set_guest_bug(d, "QXL_IO_UPDATE_AREA: "
"invalid area(%d,%d,%d,%d)\n", update.left,
update.right, update.top, update.bottom);
break;
}
if (async == QXL_ASYNC) {
cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
QXL_IO_UPDATE_AREA_ASYNC);
@@ -1490,6 +1562,9 @@ async_common:
d->mode = QXL_MODE_UNDEFINED;
qxl_spice_destroy_surfaces(d, async);
break;
case QXL_IO_MONITORS_CONFIG_ASYNC:
qxl_spice_monitors_config_async(d, 0);
break;
default:
qxl_set_guest_bug(d, "%s: unexpected ioport=0x%x\n", __func__, io_port);
}
@@ -1506,9 +1581,9 @@ cancel_async:
static uint64_t ioport_read(void *opaque, target_phys_addr_t addr,
unsigned size)
{
PCIQXLDevice *d = opaque;
PCIQXLDevice *qxl = opaque;
trace_qxl_io_read_unexpected(d->id);
trace_qxl_io_read_unexpected(qxl->id);
return 0xff;
}
@@ -1538,7 +1613,8 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
uint32_t old_pending;
uint32_t le_events = cpu_to_le32(events);
assert(d->ssd.running);
trace_qxl_send_events(d->id, events);
assert(qemu_spice_display_is_running(&d->ssd));
old_pending = __sync_fetch_and_or(&d->ram->int_pending, le_events);
if ((old_pending & le_events) == le_events) {
return;
@@ -1627,7 +1703,7 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
{
intptr_t vram_start;
uintptr_t vram_start;
int i;
if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) {
@@ -1638,7 +1714,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
qxl->shadow_rom.surface0_area_size);
vram_start = (intptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
/* dirty the off-screen surfaces */
for (i = 0; i < NUM_SURFACES; i++) {
@@ -1785,6 +1861,17 @@ static int qxl_init_common(PCIQXLDevice *qxl)
io_size = 16;
break;
case 3: /* qxl-3 */
pci_device_rev = QXL_REVISION_STABLE_V10;
io_size = 32; /* PCI region size must be pow2 */
break;
/* 0x000b01 == 0.11.1 */
#if SPICE_SERVER_VERSION >= 0x000b01 && \
defined(CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC)
case 4: /* qxl-4 */
pci_device_rev = QXL_REVISION_STABLE_V12;
io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
break;
#endif
default:
pci_device_rev = QXL_DEFAULT_REVISION;
io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
@@ -1955,6 +2042,7 @@ static int qxl_post_load(void *opaque, int version)
switch (newmode) {
case QXL_MODE_UNDEFINED:
qxl_create_memslots(d);
break;
case QXL_MODE_VGA:
qxl_create_memslots(d);
@@ -1983,7 +2071,9 @@ static int qxl_post_load(void *opaque, int version)
}
qxl_spice_loadvm_commands(d, cmds, out);
g_free(cmds);
if (d->guest_monitors_config) {
qxl_spice_monitors_config_async(d, 1);
}
break;
case QXL_MODE_COMPAT:
/* note: no need to call qxl_create_memslots, qxl_set_mode
@@ -1996,6 +2086,14 @@ static int qxl_post_load(void *opaque, int version)
#define QXL_SAVE_VERSION 21
static bool qxl_monitors_config_needed(void *opaque)
{
PCIQXLDevice *qxl = opaque;
return qxl->guest_monitors_config != 0;
}
static VMStateDescription qxl_memslot = {
.name = "qxl-memslot",
.version_id = QXL_SAVE_VERSION,
@@ -2026,6 +2124,16 @@ static VMStateDescription qxl_surface = {
}
};
static VMStateDescription qxl_vmstate_monitors_config = {
.name = "qxl/monitors-config",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT64(guest_monitors_config, PCIQXLDevice),
VMSTATE_END_OF_LIST()
},
};
static VMStateDescription qxl_vmstate = {
.name = "qxl",
.version_id = QXL_SAVE_VERSION,
@@ -2033,7 +2141,7 @@ static VMStateDescription qxl_vmstate = {
.pre_save = qxl_pre_save,
.pre_load = qxl_pre_load,
.post_load = qxl_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(pci, PCIQXLDevice),
VMSTATE_STRUCT(vga, PCIQXLDevice, 0, vmstate_vga_common, VGACommonState),
VMSTATE_UINT32(shadow_rom.mode, PCIQXLDevice),
@@ -2052,6 +2160,14 @@ static VMStateDescription qxl_vmstate = {
VMSTATE_UINT64(guest_cursor, PCIQXLDevice),
VMSTATE_END_OF_LIST()
},
.subsections = (VMStateSubsection[]) {
{
.vmsd = &qxl_vmstate_monitors_config,
.needed = qxl_monitors_config_needed,
}, {
/* empty */
}
}
};
static Property qxl_properties[] = {

View File

@@ -71,6 +71,8 @@ typedef struct PCIQXLDevice {
} guest_surfaces;
QXLPHYSICAL guest_cursor;
QXLPHYSICAL guest_monitors_config;
QemuMutex track_lock;
/* thread signaling */
@@ -128,7 +130,12 @@ typedef struct PCIQXLDevice {
} \
} while (0)
#if 0
/* spice-server 0.12 is still in development */
#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V12
#else
#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V10
#endif
/* qxl.c */
void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);

View File

@@ -284,8 +284,8 @@ static void s390_init(ram_addr_t my_ram_size,
}
/* we have to overwrite values in the kernel image, which are "rom" */
memcpy(rom_ptr(INITRD_PARM_START), &initrd_offset, 8);
memcpy(rom_ptr(INITRD_PARM_SIZE), &initrd_size, 8);
stq_p(rom_ptr(INITRD_PARM_START), initrd_offset);
stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size);
}
if (rom_ptr(KERN_PARM_AREA)) {

View File

@@ -678,7 +678,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
* is actually implemented, but we're good enough.
*/
outbuf[2] = 5;
outbuf[3] = 2; /* Format 2 */
outbuf[3] = 2 | 0x10; /* Format 2, HiSup */
if (buflen > 36) {
outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */
@@ -1449,6 +1449,22 @@ invalid_field:
return;
}
static inline bool check_lba_range(SCSIDiskState *s,
uint64_t sector_num, uint32_t nb_sectors)
{
/*
* The first line tests that no overflow happens when computing the last
* sector. The second line tests that the last accessed sector is in
* range.
*
* Careful, the computations should not underflow for nb_sectors == 0,
* and a 0-block read to the first LBA beyond the end of device is
* valid.
*/
return (sector_num <= sector_num + nb_sectors &&
sector_num + nb_sectors <= s->qdev.max_lba + 1);
}
typedef struct UnmapCBData {
SCSIDiskReq *r;
uint8_t *inbuf;
@@ -1473,8 +1489,7 @@ static void scsi_unmap_complete(void *opaque, int ret)
if (data->count > 0 && !r->req.io_canceled) {
sector_num = ldq_be_p(&data->inbuf[0]);
nb_sectors = ldl_be_p(&data->inbuf[8]) & 0xffffffffULL;
if (sector_num > sector_num + nb_sectors ||
sector_num + nb_sectors - 1 > s->qdev.max_lba) {
if (!check_lba_range(s, sector_num, nb_sectors)) {
scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
goto done;
}
@@ -1802,8 +1817,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
return 0;
}
if (r->req.cmd.lba > r->req.cmd.lba + nb_sectors ||
r->req.cmd.lba + nb_sectors - 1 > s->qdev.max_lba) {
if (!check_lba_range(s, r->req.cmd.lba, nb_sectors)) {
goto illegal_lba;
}
@@ -1878,8 +1892,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
if (r->req.cmd.buf[1] & 0xe0) {
goto illegal_request;
}
if (r->req.cmd.lba > r->req.cmd.lba + len ||
r->req.cmd.lba + len - 1 > s->qdev.max_lba) {
if (!check_lba_range(s, r->req.cmd.lba, len)) {
goto illegal_lba;
}
r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
@@ -1907,8 +1920,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
if (r->req.cmd.buf[1] & 0xe0) {
goto illegal_request;
}
if (r->req.cmd.lba > r->req.cmd.lba + len ||
r->req.cmd.lba + len - 1 > s->qdev.max_lba) {
if (!check_lba_range(s, r->req.cmd.lba, len)) {
goto illegal_lba;
}
r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);

16
hw/sd.c
View File

@@ -1407,7 +1407,7 @@ static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len)
DPRINTF("sd_blk_read: addr = 0x%08llx, len = %d\n",
(unsigned long long) addr, len);
if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) < 0) {
fprintf(stderr, "sd_blk_read: read error on host side\n");
return;
}
@@ -1415,7 +1415,7 @@ static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len)
if (end > (addr & ~511) + 512) {
memcpy(sd->data, sd->buf + (addr & 511), 512 - (addr & 511));
if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) {
if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) < 0) {
fprintf(stderr, "sd_blk_read: read error on host side\n");
return;
}
@@ -1429,29 +1429,31 @@ static void sd_blk_write(SDState *sd, uint64_t addr, uint32_t len)
uint64_t end = addr + len;
if ((addr & 511) || len < 512)
if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) < 0) {
fprintf(stderr, "sd_blk_write: read error on host side\n");
return;
}
if (end > (addr & ~511) + 512) {
memcpy(sd->buf + (addr & 511), sd->data, 512 - (addr & 511));
if (bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
if (bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) < 0) {
fprintf(stderr, "sd_blk_write: write error on host side\n");
return;
}
if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) {
if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) < 0) {
fprintf(stderr, "sd_blk_write: read error on host side\n");
return;
}
memcpy(sd->buf, sd->data + 512 - (addr & 511), end & 511);
if (bdrv_write(sd->bdrv, end >> 9, sd->buf, 1) == -1)
if (bdrv_write(sd->bdrv, end >> 9, sd->buf, 1) < 0) {
fprintf(stderr, "sd_blk_write: write error on host side\n");
}
} else {
memcpy(sd->buf + (addr & 511), sd->data, len);
if (!sd->bdrv || bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1)
if (!sd->bdrv || bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) < 0) {
fprintf(stderr, "sd_blk_write: write error on host side\n");
}
}
}

View File

@@ -556,7 +556,12 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
static void emulate_spapr_hypercall(CPUPPCState *env)
{
env->gpr[3] = spapr_hypercall(env, env->gpr[3], &env->gpr[4]);
if (msr_pr) {
hcall_dprintf("Hypercall made with MSR[PR]=1\n");
env->gpr[3] = H_PRIVILEGE;
} else {
env->gpr[3] = spapr_hypercall(env, env->gpr[3], &env->gpr[4]);
}
}
static void spapr_reset(void *opaque)

View File

@@ -1,6 +1,5 @@
#include "sysemu.h"
#include "cpu.h"
#include "dyngen-exec.h"
#include "qemu-char.h"
#include "sysemu.h"
#include "qemu-char.h"
@@ -714,11 +713,6 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
target_ulong spapr_hypercall(CPUPPCState *env, target_ulong opcode,
target_ulong *args)
{
if (msr_pr) {
hcall_dprintf("Hypercall made with MSR[PR]=1\n");
return H_PRIVILEGE;
}
if ((opcode <= MAX_HCALL_OPCODE)
&& ((opcode & 0x3) == 0)) {
spapr_hcall_fn fn = papr_hypercall_table[opcode / 4];

View File

@@ -177,13 +177,13 @@ struct srp_tsk_mgmt {
uint8_t reserved1[6];
uint64_t tag;
uint8_t reserved2[4];
uint64_t lun QEMU_PACKED;
uint64_t lun;
uint8_t reserved3[2];
uint8_t tsk_mgmt_func;
uint8_t reserved4;
uint64_t task_tag;
uint8_t reserved5[8];
};
} QEMU_PACKED;
/*
* We need the packed attribute because the SRP spec only aligns the
@@ -198,14 +198,14 @@ struct srp_cmd {
uint8_t data_in_desc_cnt;
uint64_t tag;
uint8_t reserved2[4];
uint64_t lun QEMU_PACKED;
uint64_t lun;
uint8_t reserved3;
uint8_t task_attr;
uint8_t reserved4;
uint8_t add_cdb_len;
uint8_t cdb[16];
uint8_t add_data[0];
};
} QEMU_PACKED;
enum {
SRP_RSP_FLAG_RSPVALID = 1 << 0,

View File

@@ -377,6 +377,8 @@ void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
uint16_t raw);
int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep);
void usb_ep_set_pipeline(USBDevice *dev, int pid, int ep, bool enabled);
USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep,
uint64_t id);
void usb_attach(USBPort *port);
void usb_detach(USBPort *port);

View File

@@ -585,6 +585,13 @@ USBDevice *usbdevice_create(const char *cmdline)
return NULL;
}
if (!bus) {
error_report("Error: no usb bus to attach usbdevice %s, "
"please try -machine usb=on and check that "
"the machine model supports USB", driver);
return NULL;
}
if (!f->usbdevice_init) {
if (*params) {
error_report("usbdevice %s accepts no params", driver);

View File

@@ -398,9 +398,11 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
* When pipelining is enabled usb-devices must always return async,
* otherwise packets can complete out of order!
*/
assert(!p->ep->pipeline);
p->result = ret;
usb_packet_set_state(p, USB_PACKET_COMPLETE);
assert(!p->ep->pipeline || QTAILQ_EMPTY(&p->ep->queue));
if (ret != USB_RET_NAK) {
p->result = ret;
usb_packet_set_state(p, USB_PACKET_COMPLETE);
}
}
} else {
ret = USB_RET_ASYNC;
@@ -724,3 +726,18 @@ void usb_ep_set_pipeline(USBDevice *dev, int pid, int ep, bool enabled)
struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
uep->pipeline = enabled;
}
USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep,
uint64_t id)
{
struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
USBPacket *p;
while ((p = QTAILQ_FIRST(&uep->queue)) != NULL) {
if (p->id == id) {
return p;
}
}
return NULL;
}

View File

@@ -217,7 +217,7 @@ static const USBDescIface desc_iface[] = {
};
static const USBDescDevice desc_device = {
.bcdUSB = 0x0200,
.bcdUSB = 0x0100,
.bMaxPacketSize0 = 64,
.bNumConfigurations = 1,
.confs = (USBDescConfig[]) {

View File

@@ -1001,6 +1001,13 @@ static int rndis_keepalive_response(USBNetState *s,
return 0;
}
/* Prepare to receive the next packet */
static void usb_net_reset_in_buf(USBNetState *s)
{
s->in_ptr = s->in_len = 0;
qemu_flush_queued_packets(&s->nic->nc);
}
static int rndis_parse(USBNetState *s, uint8_t *data, int length)
{
uint32_t msg_type;
@@ -1025,7 +1032,8 @@ static int rndis_parse(USBNetState *s, uint8_t *data, int length)
case RNDIS_RESET_MSG:
rndis_clear_responsequeue(s);
s->out_ptr = s->in_ptr = s->in_len = 0;
s->out_ptr = 0;
usb_net_reset_in_buf(s);
return rndis_reset_response(s, (rndis_reset_msg_type *) data);
case RNDIS_KEEPALIVE_MSG:
@@ -1135,7 +1143,7 @@ static int usb_net_handle_datain(USBNetState *s, USBPacket *p)
int ret = USB_RET_NAK;
if (s->in_ptr > s->in_len) {
s->in_ptr = s->in_len = 0;
usb_net_reset_in_buf(s);
ret = USB_RET_NAK;
return ret;
}
@@ -1152,7 +1160,7 @@ static int usb_net_handle_datain(USBNetState *s, USBPacket *p)
if (s->in_ptr >= s->in_len &&
(is_rndis(s) || (s->in_len & (64 - 1)) || !ret)) {
/* no short packet necessary */
s->in_ptr = s->in_len = 0;
usb_net_reset_in_buf(s);
}
#ifdef TRAFFIC_DEBUG
@@ -1250,20 +1258,32 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p)
static ssize_t usbnet_receive(NetClientState *nc, const uint8_t *buf, size_t size)
{
USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
struct rndis_packet_msg_type *msg;
uint8_t *in_buf = s->in_buf;
size_t total_size = size;
if (is_rndis(s)) {
msg = (struct rndis_packet_msg_type *) s->in_buf;
if (s->rndis_state != RNDIS_DATA_INITIALIZED) {
return -1;
}
if (size + sizeof(struct rndis_packet_msg_type) > sizeof(s->in_buf))
return -1;
total_size += sizeof(struct rndis_packet_msg_type);
}
if (total_size > sizeof(s->in_buf)) {
return -1;
}
/* Only accept packet if input buffer is empty */
if (s->in_len > 0) {
return 0;
}
if (is_rndis(s)) {
struct rndis_packet_msg_type *msg;
msg = (struct rndis_packet_msg_type *)in_buf;
memset(msg, 0, sizeof(struct rndis_packet_msg_type));
msg->MessageType = cpu_to_le32(RNDIS_PACKET_MSG);
msg->MessageLength = cpu_to_le32(size + sizeof(struct rndis_packet_msg_type));
msg->DataOffset = cpu_to_le32(sizeof(struct rndis_packet_msg_type) - 8);
msg->MessageLength = cpu_to_le32(size + sizeof(*msg));
msg->DataOffset = cpu_to_le32(sizeof(*msg) - 8);
msg->DataLength = cpu_to_le32(size);
/* msg->OOBDataOffset;
* msg->OOBDataLength;
@@ -1273,14 +1293,11 @@ static ssize_t usbnet_receive(NetClientState *nc, const uint8_t *buf, size_t siz
* msg->VcHandle;
* msg->Reserved;
*/
memcpy(msg + 1, buf, size);
s->in_len = size + sizeof(struct rndis_packet_msg_type);
} else {
if (size > sizeof(s->in_buf))
return -1;
memcpy(s->in_buf, buf, size);
s->in_len = size;
in_buf += sizeof(*msg);
}
memcpy(in_buf, buf, size);
s->in_len = total_size;
s->in_ptr = 0;
return size;
}

View File

@@ -113,7 +113,7 @@ enum {
static const USBDescStrings desc_strings = {
[STR_MANUFACTURER] = "QEMU",
[STR_PRODUCT_SERIAL] = "QEMU USB SERIAL",
[STR_PRODUCT_BRAILLE] = "QEMU USB BRAILLE",
[STR_PRODUCT_BRAILLE] = "QEMU USB BAUM BRAILLE",
[STR_SERIALNUMBER] = "1",
};

View File

@@ -2,6 +2,11 @@
* QEMU USB EHCI Emulation
*
* Copyright(c) 2008 Emutex Ltd. (address@hidden)
* Copyright(c) 2011-2012 Red Hat, Inc.
*
* Red Hat Authors:
* Gerd Hoffmann <kraxel@redhat.com>
* Hans de Goede <hdegoede@redhat.com>
*
* EHCI project was started by Mark Burkley, with contributions by
* Niels de Vos. David S. Ahern continued working on it. Kevin Wolf,
@@ -29,6 +34,7 @@
#include "monitor.h"
#include "trace.h"
#include "dma.h"
#include "sysemu.h"
#define EHCI_DEBUG 0
@@ -134,6 +140,7 @@
#define NB_PORTS 6 // Number of downstream ports
#define BUFF_SIZE 5*4096 // Max bytes to transfer per transaction
#define MAX_QH 100 // Max allowable queue heads in a chain
#define MIN_FR_PER_TICK 3 // Min frames to process when catching up
/* Internal periodic / asynchronous schedule state machine states
*/
@@ -340,6 +347,7 @@ typedef struct EHCIState EHCIState;
enum async_state {
EHCI_ASYNC_NONE = 0,
EHCI_ASYNC_INITIALIZED,
EHCI_ASYNC_INFLIGHT,
EHCI_ASYNC_FINISHED,
};
@@ -365,7 +373,6 @@ struct EHCIQueue {
uint32_t seen;
uint64_t ts;
int async;
int revalidate;
/* cached data from guest - needs to be flushed
* when guest removes an entry (doorbell, handshake sequence)
@@ -384,6 +391,9 @@ struct EHCIState {
USBBus bus;
qemu_irq irq;
MemoryRegion mem;
MemoryRegion mem_caps;
MemoryRegion mem_opreg;
MemoryRegion mem_ports;
int companion_count;
/* properties */
@@ -393,10 +403,10 @@ struct EHCIState {
* EHCI spec version 1.0 Section 2.3
* Host Controller Operational Registers
*/
uint8_t caps[OPREGBASE];
union {
uint8_t mmio[MMIO_SIZE];
uint32_t opreg[(PORTSC_BEGIN-OPREGBASE)/sizeof(uint32_t)];
struct {
uint8_t cap[OPREGBASE];
uint32_t usbcmd;
uint32_t usbsts;
uint32_t usbintr;
@@ -406,9 +416,9 @@ struct EHCIState {
uint32_t asynclistaddr;
uint32_t notused[9];
uint32_t configflag;
uint32_t portsc[NB_PORTS];
};
};
uint32_t portsc[NB_PORTS];
/*
* Internal states, shadow registers, etc
@@ -466,25 +476,18 @@ static const char *ehci_state_names[] = {
};
static const char *ehci_mmio_names[] = {
[CAPLENGTH] = "CAPLENGTH",
[HCIVERSION] = "HCIVERSION",
[HCSPARAMS] = "HCSPARAMS",
[HCCPARAMS] = "HCCPARAMS",
[USBCMD] = "USBCMD",
[USBSTS] = "USBSTS",
[USBINTR] = "USBINTR",
[FRINDEX] = "FRINDEX",
[PERIODICLISTBASE] = "P-LIST BASE",
[ASYNCLISTADDR] = "A-LIST ADDR",
[PORTSC_BEGIN] = "PORTSC #0",
[PORTSC_BEGIN + 4] = "PORTSC #1",
[PORTSC_BEGIN + 8] = "PORTSC #2",
[PORTSC_BEGIN + 12] = "PORTSC #3",
[PORTSC_BEGIN + 16] = "PORTSC #4",
[PORTSC_BEGIN + 20] = "PORTSC #5",
[CONFIGFLAG] = "CONFIGFLAG",
};
static int ehci_state_executing(EHCIQueue *q);
static int ehci_state_writeback(EHCIQueue *q);
static const char *nr2str(const char **n, size_t len, uint32_t nr)
{
if (nr < len && n[nr] != NULL) {
@@ -501,7 +504,8 @@ static const char *state2str(uint32_t state)
static const char *addr2str(target_phys_addr_t addr)
{
return nr2str(ehci_mmio_names, ARRAY_SIZE(ehci_mmio_names), addr);
return nr2str(ehci_mmio_names, ARRAY_SIZE(ehci_mmio_names),
addr + OPREGBASE);
}
static void ehci_trace_usbsts(uint32_t mask, int state)
@@ -709,6 +713,12 @@ static void ehci_trace_sitd(EHCIState *s, target_phys_addr_t addr,
(bool)(sitd->results & SITD_RESULTS_ACTIVE));
}
static void ehci_trace_guest_bug(EHCIState *s, const char *message)
{
trace_usb_ehci_guest_bug(message);
fprintf(stderr, "ehci warning: %s\n", message);
}
static inline bool ehci_enabled(EHCIState *s)
{
return s->usbcmd & USBCMD_RUNSTOP;
@@ -740,9 +750,25 @@ static EHCIPacket *ehci_alloc_packet(EHCIQueue *q)
static void ehci_free_packet(EHCIPacket *p)
{
if (p->async == EHCI_ASYNC_FINISHED) {
int state = ehci_get_state(p->queue->ehci, p->queue->async);
/* This is a normal, but rare condition (cancel racing completion) */
fprintf(stderr, "EHCI: Warning packet completed but not processed\n");
ehci_state_executing(p->queue);
ehci_state_writeback(p->queue);
ehci_set_state(p->queue->ehci, p->queue->async, state);
/* state_writeback recurses into us with async == EHCI_ASYNC_NONE!! */
return;
}
trace_usb_ehci_packet_action(p->queue, p, "free");
if (p->async == EHCI_ASYNC_INITIALIZED) {
usb_packet_unmap(&p->packet, &p->sgl);
qemu_sglist_destroy(&p->sgl);
}
if (p->async == EHCI_ASYNC_INFLIGHT) {
usb_cancel_packet(&p->packet);
usb_packet_unmap(&p->packet, &p->sgl);
qemu_sglist_destroy(&p->sgl);
}
QTAILQ_REMOVE(&p->queue->packets, p, next);
usb_packet_cleanup(&p->packet);
@@ -766,27 +792,45 @@ static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, uint32_t addr, int async)
return q;
}
static void ehci_cancel_queue(EHCIQueue *q)
static int ehci_cancel_queue(EHCIQueue *q)
{
EHCIPacket *p;
int packets = 0;
p = QTAILQ_FIRST(&q->packets);
if (p == NULL) {
return;
return 0;
}
trace_usb_ehci_queue_action(q, "cancel");
do {
ehci_free_packet(p);
packets++;
} while ((p = QTAILQ_FIRST(&q->packets)) != NULL);
return packets;
}
static void ehci_free_queue(EHCIQueue *q)
static int ehci_reset_queue(EHCIQueue *q)
{
int packets;
trace_usb_ehci_queue_action(q, "reset");
packets = ehci_cancel_queue(q);
q->dev = NULL;
q->qtdaddr = 0;
return packets;
}
static void ehci_free_queue(EHCIQueue *q, const char *warn)
{
EHCIQueueHead *head = q->async ? &q->ehci->aqueues : &q->ehci->pqueues;
int cancelled;
trace_usb_ehci_queue_action(q, "free");
ehci_cancel_queue(q);
cancelled = ehci_cancel_queue(q);
if (warn && cancelled > 0) {
ehci_trace_guest_bug(q->ehci, warn);
}
QTAILQ_REMOVE(head, q, next);
g_free(q);
}
@@ -805,20 +849,10 @@ static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr,
return NULL;
}
static void ehci_queues_tag_unused_async(EHCIState *ehci)
{
EHCIQueue *q;
QTAILQ_FOREACH(q, &ehci->aqueues, next) {
if (!q->seen) {
q->revalidate = 1;
}
}
}
static void ehci_queues_rip_unused(EHCIState *ehci, int async)
{
EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
const char *warn = async ? "guest unlinked busy QH" : NULL;
uint64_t maxage = FRAME_TIMER_NS * ehci->maxframes * 4;
EHCIQueue *q, *tmp;
@@ -831,7 +865,19 @@ static void ehci_queues_rip_unused(EHCIState *ehci, int async)
if (ehci->last_run_ns < q->ts + maxage) {
continue;
}
ehci_free_queue(q);
ehci_free_queue(q, warn);
}
}
static void ehci_queues_rip_unseen(EHCIState *ehci, int async)
{
EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
EHCIQueue *q, *tmp;
QTAILQ_FOREACH_SAFE(q, head, next, tmp) {
if (!q->seen) {
ehci_free_queue(q, NULL);
}
}
}
@@ -844,17 +890,18 @@ static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev, int async)
if (q->dev != dev) {
continue;
}
ehci_free_queue(q);
ehci_free_queue(q, NULL);
}
}
static void ehci_queues_rip_all(EHCIState *ehci, int async)
{
EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
const char *warn = async ? "guest stopped busy async schedule" : NULL;
EHCIQueue *q, *tmp;
QTAILQ_FOREACH_SAFE(q, head, next, tmp) {
ehci_free_queue(q);
ehci_free_queue(q, warn);
}
}
@@ -979,7 +1026,7 @@ static int ehci_register_companion(USBBus *bus, USBPort *ports[],
}
s->companion_count++;
s->mmio[0x05] = (s->companion_count << 4) | portcount;
s->caps[0x05] = (s->companion_count << 4) | portcount;
return 0;
}
@@ -1024,7 +1071,8 @@ static void ehci_reset(void *opaque)
}
}
memset(&s->mmio[OPREGBASE], 0x00, MMIO_SIZE - OPREGBASE);
memset(&s->opreg, 0x00, sizeof(s->opreg));
memset(&s->portsc, 0x00, sizeof(s->portsc));
s->usbcmd = NB_MAXINTRATE << USBCMD_ITC_SH;
s->usbsts = USBSTS_HALT;
@@ -1051,50 +1099,35 @@ static void ehci_reset(void *opaque)
qemu_bh_cancel(s->async_bh);
}
static uint32_t ehci_mem_readb(void *ptr, target_phys_addr_t addr)
static uint64_t ehci_caps_read(void *ptr, target_phys_addr_t addr,
unsigned size)
{
EHCIState *s = ptr;
return s->caps[addr];
}
static uint64_t ehci_opreg_read(void *ptr, target_phys_addr_t addr,
unsigned size)
{
EHCIState *s = ptr;
uint32_t val;
val = s->mmio[addr];
val = s->opreg[addr >> 2];
trace_usb_ehci_opreg_read(addr + OPREGBASE, addr2str(addr), val);
return val;
}
static uint32_t ehci_mem_readw(void *ptr, target_phys_addr_t addr)
static uint64_t ehci_port_read(void *ptr, target_phys_addr_t addr,
unsigned size)
{
EHCIState *s = ptr;
uint32_t val;
val = s->mmio[addr] | (s->mmio[addr+1] << 8);
val = s->portsc[addr >> 2];
trace_usb_ehci_portsc_read(addr + PORTSC_BEGIN, addr >> 2, val);
return val;
}
static uint32_t ehci_mem_readl(void *ptr, target_phys_addr_t addr)
{
EHCIState *s = ptr;
uint32_t val;
val = s->mmio[addr] | (s->mmio[addr+1] << 8) |
(s->mmio[addr+2] << 16) | (s->mmio[addr+3] << 24);
trace_usb_ehci_mmio_readl(addr, addr2str(addr), val);
return val;
}
static void ehci_mem_writeb(void *ptr, target_phys_addr_t addr, uint32_t val)
{
fprintf(stderr, "EHCI doesn't handle byte writes to MMIO\n");
exit(1);
}
static void ehci_mem_writew(void *ptr, target_phys_addr_t addr, uint32_t val)
{
fprintf(stderr, "EHCI doesn't handle 16-bit writes to MMIO\n");
exit(1);
}
static void handle_port_owner_write(EHCIState *s, int port, uint32_t owner)
{
USBDevice *dev = s->ports[port].dev;
@@ -1123,11 +1156,17 @@ static void handle_port_owner_write(EHCIState *s, int port, uint32_t owner)
}
}
static void handle_port_status_write(EHCIState *s, int port, uint32_t val)
static void ehci_port_write(void *ptr, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
EHCIState *s = ptr;
int port = addr >> 2;
uint32_t *portsc = &s->portsc[port];
uint32_t old = *portsc;
USBDevice *dev = s->ports[port].dev;
trace_usb_ehci_portsc_write(addr + PORTSC_BEGIN, addr >> 2, val);
/* Clear rwc bits */
*portsc &= ~(val & PORTSC_RWC_MASK);
/* The guest may clear, but not set the PED bit */
@@ -1159,39 +1198,20 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val)
*portsc &= ~PORTSC_RO_MASK;
*portsc |= val;
trace_usb_ehci_portsc_change(addr + PORTSC_BEGIN, addr >> 2, *portsc, old);
}
static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
static void ehci_opreg_write(void *ptr, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
EHCIState *s = ptr;
uint32_t *mmio = (uint32_t *)(&s->mmio[addr]);
uint32_t *mmio = s->opreg + (addr >> 2);
uint32_t old = *mmio;
int i;
trace_usb_ehci_mmio_writel(addr, addr2str(addr), val);
trace_usb_ehci_opreg_write(addr + OPREGBASE, addr2str(addr), val);
/* Only aligned reads are allowed on OHCI */
if (addr & 3) {
fprintf(stderr, "usb-ehci: Mis-aligned write to addr 0x"
TARGET_FMT_plx "\n", addr);
return;
}
if (addr >= PORTSC && addr < PORTSC + 4 * NB_PORTS) {
handle_port_status_write(s, (addr-PORTSC)/4, val);
trace_usb_ehci_mmio_change(addr, addr2str(addr), *mmio, old);
return;
}
if (addr < OPREGBASE) {
fprintf(stderr, "usb-ehci: write attempt to read-only register"
TARGET_FMT_plx "\n", addr);
return;
}
/* Do any register specific pre-write processing here. */
switch(addr) {
switch (addr + OPREGBASE) {
case USBCMD:
if (val & USBCMD_HCRESET) {
ehci_reset(s);
@@ -1202,7 +1222,7 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
/* not supporting dynamic frame list size at the moment */
if ((val & USBCMD_FLS) && !(s->usbcmd & USBCMD_FLS)) {
fprintf(stderr, "attempt to set frame list size -- value %d\n",
val & USBCMD_FLS);
(int)val & USBCMD_FLS);
val &= ~USBCMD_FLS;
}
@@ -1213,6 +1233,7 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
*/
s->async_stepdown = 0;
qemu_bh_schedule(s->async_bh);
trace_usb_ehci_doorbell_ring();
}
if (((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & val) !=
@@ -1268,7 +1289,7 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
}
*mmio = val;
trace_usb_ehci_mmio_change(addr, addr2str(addr), *mmio, old);
trace_usb_ehci_opreg_change(addr + OPREGBASE, addr2str(addr), *mmio, old);
}
@@ -1450,8 +1471,8 @@ static void ehci_execute_complete(EHCIQueue *q)
assert(p != NULL);
assert(p->qtdaddr == q->qtdaddr);
assert(p->async != EHCI_ASYNC_INFLIGHT);
p->async = EHCI_ASYNC_NONE;
assert(p->async == EHCI_ASYNC_INITIALIZED ||
p->async == EHCI_ASYNC_FINISHED);
DPRINTF("execute_complete: qhaddr 0x%x, next %x, qtdaddr 0x%x, status %d\n",
q->qhaddr, q->qh.next, q->qtdaddr, q->usb_status);
@@ -1481,10 +1502,6 @@ static void ehci_execute_complete(EHCIQueue *q)
assert(0);
break;
}
} else if ((p->usb_status > p->tbytes) && (p->pid == USB_TOKEN_IN)) {
p->usb_status = USB_RET_BABBLE;
q->qh.token |= (QTD_TOKEN_HALT | QTD_TOKEN_BABBLE);
ehci_raise_irq(q->ehci, USBSTS_ERRINT);
} else {
// TODO check 4.12 for splits
@@ -1500,6 +1517,7 @@ static void ehci_execute_complete(EHCIQueue *q)
ehci_finish_transfer(q, p->usb_status);
usb_packet_unmap(&p->packet, &p->sgl);
qemu_sglist_destroy(&p->sgl);
p->async = EHCI_ASYNC_NONE;
q->qh.token ^= QTD_TOKEN_DTOGGLE;
q->qh.token &= ~QTD_TOKEN_ACTIVE;
@@ -1517,6 +1535,9 @@ static int ehci_execute(EHCIPacket *p, const char *action)
int ret;
int endp;
assert(p->async == EHCI_ASYNC_NONE ||
p->async == EHCI_ASYNC_INITIALIZED);
if (!(p->qtd.token & QTD_TOKEN_ACTIVE)) {
fprintf(stderr, "Attempting to execute inactive qtd\n");
return USB_RET_PROCERR;
@@ -1524,7 +1545,8 @@ static int ehci_execute(EHCIPacket *p, const char *action)
p->tbytes = (p->qtd.token & QTD_TOKEN_TBYTES_MASK) >> QTD_TOKEN_TBYTES_SH;
if (p->tbytes > BUFF_SIZE) {
fprintf(stderr, "Request for more bytes than allowed\n");
ehci_trace_guest_bug(p->queue->ehci,
"guest requested more bytes than allowed");
return USB_RET_PROCERR;
}
@@ -1544,15 +1566,18 @@ static int ehci_execute(EHCIPacket *p, const char *action)
break;
}
if (ehci_init_transfer(p) != 0) {
return USB_RET_PROCERR;
}
endp = get_field(p->queue->qh.epchar, QH_EPCHAR_EP);
ep = usb_ep_get(p->queue->dev, p->pid, endp);
usb_packet_setup(&p->packet, p->pid, ep, p->qtdaddr);
usb_packet_map(&p->packet, &p->sgl);
if (p->async == EHCI_ASYNC_NONE) {
if (ehci_init_transfer(p) != 0) {
return USB_RET_PROCERR;
}
usb_packet_setup(&p->packet, p->pid, ep, p->qtdaddr);
usb_packet_map(&p->packet, &p->sgl);
p->async = EHCI_ASYNC_INITIALIZED;
}
trace_usb_ehci_packet_action(p->queue, p, action);
ret = usb_handle_packet(p->queue->dev, &p->packet);
@@ -1771,7 +1796,7 @@ out:
static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
{
EHCIPacket *p;
uint32_t entry, devaddr;
uint32_t entry, devaddr, endp;
EHCIQueue *q;
EHCIqh qh;
@@ -1792,26 +1817,26 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
get_dwords(ehci, NLPTR_GET(q->qhaddr),
(uint32_t *) &qh, sizeof(EHCIqh) >> 2);
if (q->revalidate && (q->qh.epchar != qh.epchar ||
q->qh.epcap != qh.epcap ||
q->qh.current_qtd != qh.current_qtd)) {
ehci_free_queue(q);
q = ehci_alloc_queue(ehci, entry, async);
q->seen++;
ehci_trace_qh(q, NLPTR_GET(q->qhaddr), &qh);
/*
* The overlay area of the qh should never be changed by the guest,
* except when idle, in which case the reset is a nop.
*/
devaddr = get_field(qh.epchar, QH_EPCHAR_DEVADDR);
endp = get_field(qh.epchar, QH_EPCHAR_EP);
if ((devaddr != get_field(q->qh.epchar, QH_EPCHAR_DEVADDR)) ||
(endp != get_field(q->qh.epchar, QH_EPCHAR_EP)) ||
(memcmp(&qh.current_qtd, &q->qh.current_qtd,
9 * sizeof(uint32_t)) != 0) ||
(q->dev != NULL && q->dev->addr != devaddr)) {
if (ehci_reset_queue(q) > 0) {
ehci_trace_guest_bug(ehci, "guest updated active QH");
}
p = NULL;
}
q->qh = qh;
q->revalidate = 0;
ehci_trace_qh(q, NLPTR_GET(q->qhaddr), &q->qh);
devaddr = get_field(q->qh.epchar, QH_EPCHAR_DEVADDR);
if (q->dev != NULL && q->dev->addr != devaddr) {
if (!QTAILQ_EMPTY(&q->packets)) {
/* should not happen (guest bug) */
ehci_cancel_queue(q);
}
q->dev = NULL;
}
if (q->dev == NULL) {
q->dev = ehci_find_device(q->ehci, devaddr);
}
@@ -1969,8 +1994,8 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
(!NLPTR_TBIT(p->qtd.next) && (p->qtd.next != qtd.next)) ||
(!NLPTR_TBIT(p->qtd.altnext) && (p->qtd.altnext != qtd.altnext)) ||
p->qtd.bufptr[0] != qtd.bufptr[0]) {
/* guest bug: guest updated active QH or qTD underneath us */
ehci_cancel_queue(q);
ehci_trace_guest_bug(q->ehci, "guest updated active QH or qTD");
p = NULL;
} else {
p->qtd = qtd;
@@ -1989,15 +2014,22 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
} else if (p != NULL) {
switch (p->async) {
case EHCI_ASYNC_NONE:
/* Should never happen packet should at least be initialized */
assert(0);
break;
case EHCI_ASYNC_INITIALIZED:
/* Previously nacked packet (likely interrupt ep) */
ehci_set_state(q->ehci, q->async, EST_EXECUTE);
break;
ehci_set_state(q->ehci, q->async, EST_EXECUTE);
break;
case EHCI_ASYNC_INFLIGHT:
/* Unfinyshed async handled packet, go horizontal */
/* Unfinished async handled packet, go horizontal */
ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
break;
case EHCI_ASYNC_FINISHED:
/* Should never happen, as this case is caught by fetchqh */
/*
* We get here when advqueue moves to a packet which is already
* finished, which can happen with packets queued up by fill_queue
*/
ehci_set_state(q->ehci, q->async, EST_EXECUTING);
break;
}
@@ -2028,7 +2060,7 @@ static int ehci_state_horizqh(EHCIQueue *q)
return again;
}
static void ehci_fill_queue(EHCIPacket *p)
static int ehci_fill_queue(EHCIPacket *p)
{
EHCIQueue *q = p->queue;
EHCIqtd qtd = p->qtd;
@@ -2052,9 +2084,13 @@ static void ehci_fill_queue(EHCIPacket *p)
p->qtdaddr = qtdaddr;
p->qtd = qtd;
p->usb_status = ehci_execute(p, "queue");
if (p->usb_status == USB_RET_PROCERR) {
break;
}
assert(p->usb_status == USB_RET_ASYNC);
p->async = EHCI_ASYNC_INFLIGHT;
}
return p->usb_status;
}
static int ehci_state_execute(EHCIQueue *q)
@@ -2096,8 +2132,7 @@ static int ehci_state_execute(EHCIQueue *q)
trace_usb_ehci_packet_action(p->queue, p, "async");
p->async = EHCI_ASYNC_INFLIGHT;
ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
again = 1;
ehci_fill_queue(p);
again = (ehci_fill_queue(p) == USB_RET_PROCERR) ? -1 : 1;
goto out;
}
@@ -2310,8 +2345,8 @@ static void ehci_advance_async_state(EHCIState *ehci)
*/
if (ehci->usbcmd & USBCMD_IAAD) {
/* Remove all unseen qhs from the async qhs queue */
ehci_queues_tag_unused_async(ehci);
DPRINTF("ASYNC: doorbell request acknowledged\n");
ehci_queues_rip_unseen(ehci, async);
trace_usb_ehci_doorbell_ack();
ehci->usbcmd &= ~USBCMD_IAAD;
ehci_raise_irq(ehci, USBSTS_IAA);
}
@@ -2392,7 +2427,7 @@ static void ehci_update_frindex(EHCIState *ehci, int frames)
if (ehci->frindex == 0x00004000) {
ehci_raise_irq(ehci, USBSTS_FLR);
ehci->frindex = 0;
if (ehci->usbsts_frindex > 0x00004000) {
if (ehci->usbsts_frindex >= 0x00004000) {
ehci->usbsts_frindex -= 0x00004000;
} else {
ehci->usbsts_frindex = 0;
@@ -2427,6 +2462,19 @@ static void ehci_frame_timer(void *opaque)
}
for (i = 0; i < frames; i++) {
/*
* If we're running behind schedule, we should not catch up
* too fast, as that will make some guests unhappy:
* 1) We must process a minimum of MIN_FR_PER_TICK frames,
* otherwise we will never catch up
* 2) Process frames until the guest has requested an irq (IOC)
*/
if (i >= MIN_FR_PER_TICK) {
ehci_commit_irq(ehci);
if ((ehci->usbsts & USBINTR_MASK) & ehci->usbintr) {
break;
}
}
ehci_update_frindex(ehci, 1);
ehci_advance_periodic_state(ehci);
ehci->last_run_ns += FRAME_TIMER_NS;
@@ -2466,11 +2514,28 @@ static void ehci_async_bh(void *opaque)
ehci_advance_async_state(ehci);
}
static const MemoryRegionOps ehci_mem_ops = {
.old_mmio = {
.read = { ehci_mem_readb, ehci_mem_readw, ehci_mem_readl },
.write = { ehci_mem_writeb, ehci_mem_writew, ehci_mem_writel },
},
static const MemoryRegionOps ehci_mmio_caps_ops = {
.read = ehci_caps_read,
.valid.min_access_size = 1,
.valid.max_access_size = 4,
.impl.min_access_size = 1,
.impl.max_access_size = 1,
.endianness = DEVICE_LITTLE_ENDIAN,
};
static const MemoryRegionOps ehci_mmio_opreg_ops = {
.read = ehci_opreg_read,
.write = ehci_opreg_write,
.valid.min_access_size = 4,
.valid.max_access_size = 4,
.endianness = DEVICE_LITTLE_ENDIAN,
};
static const MemoryRegionOps ehci_mmio_port_ops = {
.read = ehci_port_read,
.write = ehci_port_write,
.valid.min_access_size = 4,
.valid.max_access_size = 4,
.endianness = DEVICE_LITTLE_ENDIAN,
};
@@ -2508,6 +2573,32 @@ static int usb_ehci_post_load(void *opaque, int version_id)
return 0;
}
static void usb_ehci_vm_state_change(void *opaque, int running, RunState state)
{
EHCIState *ehci = opaque;
/*
* We don't migrate the EHCIQueue-s, instead we rebuild them for the
* schedule in guest memory. We must do the rebuilt ASAP, so that
* USB-devices which have async handled packages have a packet in the
* ep queue to match the completion with.
*/
if (state == RUN_STATE_RUNNING) {
ehci_advance_async_state(ehci);
}
/*
* The schedule rebuilt from guest memory could cause the migration dest
* to miss a QH unlink, and fail to cancel packets, since the unlinked QH
* will never have existed on the destination. Therefor we must flush the
* async schedule on savevm to catch any not yet noticed unlinks.
*/
if (state == RUN_STATE_SAVE_VM) {
ehci_advance_async_state(ehci);
ehci_queues_rip_unseen(ehci, 1);
}
}
static const VMStateDescription vmstate_ehci = {
.name = "ehci",
.version_id = 2,
@@ -2627,19 +2718,19 @@ static int usb_ehci_initfn(PCIDevice *dev)
pci_conf[0x6e] = 0x00;
pci_conf[0x6f] = 0xc0; // USBLEFCTLSTS
// 2.2 host controller interface version
s->mmio[0x00] = (uint8_t) OPREGBASE;
s->mmio[0x01] = 0x00;
s->mmio[0x02] = 0x00;
s->mmio[0x03] = 0x01; // HC version
s->mmio[0x04] = NB_PORTS; // Number of downstream ports
s->mmio[0x05] = 0x00; // No companion ports at present
s->mmio[0x06] = 0x00;
s->mmio[0x07] = 0x00;
s->mmio[0x08] = 0x80; // We can cache whole frame, not 64-bit capable
s->mmio[0x09] = 0x68; // EECP
s->mmio[0x0a] = 0x00;
s->mmio[0x0b] = 0x00;
/* 2.2 host controller interface version */
s->caps[0x00] = (uint8_t) OPREGBASE;
s->caps[0x01] = 0x00;
s->caps[0x02] = 0x00;
s->caps[0x03] = 0x01; /* HC version */
s->caps[0x04] = NB_PORTS; /* Number of downstream ports */
s->caps[0x05] = 0x00; /* No companion ports at present */
s->caps[0x06] = 0x00;
s->caps[0x07] = 0x00;
s->caps[0x08] = 0x80; /* We can cache whole frame, no 64-bit */
s->caps[0x09] = 0x68; /* EECP */
s->caps[0x0a] = 0x00;
s->caps[0x0b] = 0x00;
s->irq = s->dev.irq[3];
@@ -2657,8 +2748,20 @@ static int usb_ehci_initfn(PCIDevice *dev)
usb_packet_init(&s->ipacket);
qemu_register_reset(ehci_reset, s);
qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s);
memory_region_init(&s->mem, "ehci", MMIO_SIZE);
memory_region_init_io(&s->mem_caps, &ehci_mmio_caps_ops, s,
"capabilities", OPREGBASE);
memory_region_init_io(&s->mem_opreg, &ehci_mmio_opreg_ops, s,
"operational", PORTSC_BEGIN - OPREGBASE);
memory_region_init_io(&s->mem_ports, &ehci_mmio_port_ops, s,
"ports", PORTSC_END - PORTSC_BEGIN);
memory_region_add_subregion(&s->mem, 0, &s->mem_caps);
memory_region_add_subregion(&s->mem, OPREGBASE, &s->mem_opreg);
memory_region_add_subregion(&s->mem, PORTSC_BEGIN, &s->mem_ports);
memory_region_init_io(&s->mem, &ehci_mem_ops, s, "ehci", MMIO_SIZE);
pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
return 0;

View File

@@ -729,11 +729,6 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_
*int_mask |= 0x01;
if (pid == USB_TOKEN_IN) {
if (len > max_len) {
ret = USB_RET_BABBLE;
goto out;
}
if ((td->ctrl & TD_CTRL_SPD) && len < max_len) {
*int_mask |= 0x02;
/* short packet: do not update QH */
@@ -831,8 +826,16 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td,
USBEndpoint *ep;
/* Is active ? */
if (!(td->ctrl & TD_CTRL_ACTIVE))
if (!(td->ctrl & TD_CTRL_ACTIVE)) {
/*
* ehci11d spec page 22: "Even if the Active bit in the TD is already
* cleared when the TD is fetched ... an IOC interrupt is generated"
*/
if (td->ctrl & TD_CTRL_IOC) {
*int_mask |= 0x01;
}
return TD_RESULT_NEXT_QH;
}
async = uhci_async_find_td(s, addr, td);
if (async) {
@@ -1005,6 +1008,9 @@ static void uhci_fill_queue(UHCIState *s, UHCI_TD *td)
}
assert(ret == TD_RESULT_ASYNC_START);
assert(int_mask == 0);
if (ptd.ctrl & TD_CTRL_SPD) {
break;
}
plink = ptd.link;
}
}
@@ -1102,7 +1108,7 @@ static void uhci_process_frame(UHCIState *s)
case TD_RESULT_ASYNC_START:
trace_usb_uhci_td_async(curr_qh & ~0xf, link & ~0xf);
if (is_valid(td.link)) {
if (is_valid(td.link) && !(td.ctrl & TD_CTRL_SPD)) {
uhci_fill_queue(s, &td);
}
link = curr_qh ? qh.link : td.link;

View File

@@ -45,8 +45,6 @@
#define MAXPORTS (USB2_PORTS+USB3_PORTS)
#define TD_QUEUE 24
#define BG_XFERS 8
#define BG_PKTS 8
/* Very pessimistic, let's hope it's enough for all cases */
#define EV_QUEUE (((3*TD_QUEUE)+16)*MAXSLOTS)
@@ -307,26 +305,21 @@ typedef struct XHCIState XHCIState;
typedef struct XHCITransfer {
XHCIState *xhci;
USBPacket packet;
QEMUSGList sgl;
bool running_async;
bool running_retry;
bool cancelled;
bool complete;
bool backgrounded;
unsigned int iso_pkts;
unsigned int slotid;
unsigned int epid;
bool in_xfer;
bool iso_xfer;
bool bg_xfer;
unsigned int trb_count;
unsigned int trb_alloced;
XHCITRB *trbs;
unsigned int data_length;
unsigned int data_alloced;
uint8_t *data;
TRBCCode status;
unsigned int pkts;
@@ -340,14 +333,9 @@ typedef struct XHCIEPContext {
unsigned int comp_xfer;
XHCITransfer transfers[TD_QUEUE];
XHCITransfer *retry;
bool bg_running;
bool bg_updating;
unsigned int next_bg;
XHCITransfer bg_transfers[BG_XFERS];
EPType type;
dma_addr_t pctx;
unsigned int max_psize;
bool has_bg;
uint32_t state;
} XHCIEPContext;
@@ -866,10 +854,6 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
epctx->pctx = pctx;
epctx->max_psize = ctx[1]>>16;
epctx->max_psize *= 1+((ctx[1]>>8)&0xff);
epctx->has_bg = false;
if (epctx->type == ET_ISO_IN) {
epctx->has_bg = true;
}
DPRINTF("xhci: endpoint %d.%d max transaction (burst) size is %d\n",
epid/2, epid%2, epctx->max_psize);
for (i = 0; i < ARRAY_SIZE(epctx->transfers); i++) {
@@ -916,41 +900,14 @@ static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid,
t->running_retry = 0;
epctx->retry = NULL;
}
if (t->backgrounded) {
t->backgrounded = 0;
}
if (t->trbs) {
g_free(t->trbs);
}
if (t->data) {
g_free(t->data);
}
t->trbs = NULL;
t->data = NULL;
t->trb_count = t->trb_alloced = 0;
t->data_length = t->data_alloced = 0;
xferi = (xferi + 1) % TD_QUEUE;
}
if (epctx->has_bg) {
xferi = epctx->next_bg;
for (i = 0; i < BG_XFERS; i++) {
XHCITransfer *t = &epctx->bg_transfers[xferi];
if (t->running_async) {
usb_cancel_packet(&t->packet);
t->running_async = 0;
t->cancelled = 1;
DPRINTF("xhci: cancelling bg transfer %d, waiting for it to complete...\n", i);
killed++;
}
if (t->data) {
g_free(t->data);
}
t->data = NULL;
xferi = (xferi + 1) % BG_XFERS;
}
}
return killed;
}
@@ -1107,24 +1064,13 @@ static TRBCCode xhci_set_ep_dequeue(XHCIState *xhci, unsigned int slotid,
return CC_SUCCESS;
}
static int xhci_xfer_data(XHCITransfer *xfer, uint8_t *data,
unsigned int length, bool in_xfer, bool out_xfer,
bool report)
static int xhci_xfer_map(XHCITransfer *xfer)
{
int i;
uint32_t edtla = 0;
unsigned int transferred = 0;
unsigned int left = length;
bool reported = 0;
bool shortpkt = 0;
XHCIEvent event = {ER_TRANSFER, CC_SUCCESS};
int in_xfer = (xfer->packet.pid == USB_TOKEN_IN);
XHCIState *xhci = xfer->xhci;
int i;
DPRINTF("xhci_xfer_data(len=%d, in_xfer=%d, out_xfer=%d, report=%d)\n",
length, in_xfer, out_xfer, report);
assert(!(in_xfer && out_xfer));
pci_dma_sglist_init(&xfer->sgl, &xhci->pci_dev, xfer->trb_count);
for (i = 0; i < xfer->trb_count; i++) {
XHCITRB *trb = &xfer->trbs[i];
dma_addr_t addr;
@@ -1134,54 +1080,70 @@ static int xhci_xfer_data(XHCITransfer *xfer, uint8_t *data,
case TR_DATA:
if ((!(trb->control & TRB_TR_DIR)) != (!in_xfer)) {
fprintf(stderr, "xhci: data direction mismatch for TR_DATA\n");
xhci_die(xhci);
return transferred;
goto err;
}
/* fallthrough */
case TR_NORMAL:
case TR_ISOCH:
addr = xhci_mask64(trb->parameter);
chunk = trb->status & 0x1ffff;
if (trb->control & TRB_TR_IDT) {
if (chunk > 8 || in_xfer) {
fprintf(stderr, "xhci: invalid immediate data TRB\n");
goto err;
}
qemu_sglist_add(&xfer->sgl, trb->addr, chunk);
} else {
qemu_sglist_add(&xfer->sgl, addr, chunk);
}
break;
}
}
usb_packet_map(&xfer->packet, &xfer->sgl);
return 0;
err:
qemu_sglist_destroy(&xfer->sgl);
xhci_die(xhci);
return -1;
}
static void xhci_xfer_unmap(XHCITransfer *xfer)
{
usb_packet_unmap(&xfer->packet, &xfer->sgl);
qemu_sglist_destroy(&xfer->sgl);
}
static void xhci_xfer_report(XHCITransfer *xfer)
{
uint32_t edtla = 0;
unsigned int left;
bool reported = 0;
bool shortpkt = 0;
XHCIEvent event = {ER_TRANSFER, CC_SUCCESS};
XHCIState *xhci = xfer->xhci;
int i;
left = xfer->packet.result < 0 ? 0 : xfer->packet.result;
for (i = 0; i < xfer->trb_count; i++) {
XHCITRB *trb = &xfer->trbs[i];
unsigned int chunk = 0;
switch (TRB_TYPE(*trb)) {
case TR_DATA:
case TR_NORMAL:
case TR_ISOCH:
chunk = trb->status & 0x1ffff;
if (chunk > left) {
chunk = left;
shortpkt = 1;
}
if (in_xfer || out_xfer) {
if (trb->control & TRB_TR_IDT) {
uint64_t idata;
if (chunk > 8 || in_xfer) {
fprintf(stderr, "xhci: invalid immediate data TRB\n");
xhci_die(xhci);
return transferred;
}
idata = le64_to_cpu(trb->parameter);
memcpy(data, &idata, chunk);
} else {
DPRINTF("xhci_xfer_data: r/w(%d) %d bytes at "
DMA_ADDR_FMT "\n", in_xfer, chunk, addr);
if (in_xfer) {
pci_dma_write(&xhci->pci_dev, addr, data, chunk);
} else {
pci_dma_read(&xhci->pci_dev, addr, data, chunk);
}
#ifdef DEBUG_DATA
unsigned int count = chunk;
int i;
if (count > 16) {
count = 16;
}
DPRINTF(" ::");
for (i = 0; i < count; i++) {
DPRINTF(" %02x", data[i]);
}
DPRINTF("\n");
#endif
if (xfer->status == CC_SUCCESS) {
shortpkt = 1;
}
}
left -= chunk;
data += chunk;
edtla += chunk;
transferred += chunk;
break;
case TR_STATUS:
reported = 0;
@@ -1189,8 +1151,9 @@ static int xhci_xfer_data(XHCITransfer *xfer, uint8_t *data,
break;
}
if (report && !reported && (trb->control & TRB_TR_IOC ||
(shortpkt && (trb->control & TRB_TR_ISP)))) {
if (!reported && ((trb->control & TRB_TR_IOC) ||
(shortpkt && (trb->control & TRB_TR_ISP)) ||
(xfer->status != CC_SUCCESS))) {
event.slotid = xfer->slotid;
event.epid = xfer->epid;
event.length = (trb->status & 0x1ffff) - chunk;
@@ -1210,9 +1173,11 @@ static int xhci_xfer_data(XHCITransfer *xfer, uint8_t *data,
}
xhci_event(xhci, &event);
reported = 1;
if (xfer->status != CC_SUCCESS) {
return;
}
}
}
return transferred;
}
static void xhci_stall_ep(XHCITransfer *xfer)
@@ -1231,160 +1196,6 @@ static void xhci_stall_ep(XHCITransfer *xfer)
static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer,
XHCIEPContext *epctx);
static void xhci_bg_update(XHCIState *xhci, XHCIEPContext *epctx)
{
if (epctx->bg_updating) {
return;
}
DPRINTF("xhci_bg_update(%p, %p)\n", xhci, epctx);
assert(epctx->has_bg);
DPRINTF("xhci: fg=%d bg=%d\n", epctx->comp_xfer, epctx->next_bg);
epctx->bg_updating = 1;
while (epctx->transfers[epctx->comp_xfer].backgrounded &&
epctx->bg_transfers[epctx->next_bg].complete) {
XHCITransfer *fg = &epctx->transfers[epctx->comp_xfer];
XHCITransfer *bg = &epctx->bg_transfers[epctx->next_bg];
#if 0
DPRINTF("xhci: completing fg %d from bg %d.%d (stat: %d)\n",
epctx->comp_xfer, epctx->next_bg, bg->cur_pkt,
bg->usbxfer->iso_packet_desc[bg->cur_pkt].status
);
#endif
assert(epctx->type == ET_ISO_IN);
assert(bg->iso_xfer);
assert(bg->in_xfer);
uint8_t *p = bg->data + bg->cur_pkt * bg->pktsize;
#if 0
int len = bg->usbxfer->iso_packet_desc[bg->cur_pkt].actual_length;
fg->status = libusb_to_ccode(bg->usbxfer->iso_packet_desc[bg->cur_pkt].status);
#else
int len = 0;
FIXME();
#endif
fg->complete = 1;
fg->backgrounded = 0;
if (fg->status == CC_STALL_ERROR) {
xhci_stall_ep(fg);
}
xhci_xfer_data(fg, p, len, 1, 0, 1);
epctx->comp_xfer++;
if (epctx->comp_xfer == TD_QUEUE) {
epctx->comp_xfer = 0;
}
DPRINTF("next fg xfer: %d\n", epctx->comp_xfer);
bg->cur_pkt++;
if (bg->cur_pkt == bg->pkts) {
bg->complete = 0;
if (xhci_submit(xhci, bg, epctx) < 0) {
fprintf(stderr, "xhci: bg resubmit failed\n");
}
epctx->next_bg++;
if (epctx->next_bg == BG_XFERS) {
epctx->next_bg = 0;
}
DPRINTF("next bg xfer: %d\n", epctx->next_bg);
xhci_kick_ep(xhci, fg->slotid, fg->epid);
}
}
epctx->bg_updating = 0;
}
#if 0
static void xhci_xfer_cb(struct libusb_transfer *transfer)
{
XHCIState *xhci;
XHCITransfer *xfer;
xfer = (XHCITransfer *)transfer->user_data;
xhci = xfer->xhci;
DPRINTF("xhci_xfer_cb(slot=%d, ep=%d, status=%d)\n", xfer->slotid,
xfer->epid, transfer->status);
assert(xfer->slotid >= 1 && xfer->slotid <= MAXSLOTS);
assert(xfer->epid >= 1 && xfer->epid <= 31);
if (xfer->cancelled) {
DPRINTF("xhci: transfer cancelled, not reporting anything\n");
xfer->running = 0;
return;
}
XHCIEPContext *epctx;
XHCISlot *slot;
slot = &xhci->slots[xfer->slotid-1];
assert(slot->eps[xfer->epid-1]);
epctx = slot->eps[xfer->epid-1];
if (xfer->bg_xfer) {
DPRINTF("xhci: background transfer, updating\n");
xfer->complete = 1;
xfer->running = 0;
xhci_bg_update(xhci, epctx);
return;
}
if (xfer->iso_xfer) {
transfer->status = transfer->iso_packet_desc[0].status;
transfer->actual_length = transfer->iso_packet_desc[0].actual_length;
}
xfer->status = libusb_to_ccode(transfer->status);
xfer->complete = 1;
xfer->running = 0;
if (transfer->status == LIBUSB_TRANSFER_STALL)
xhci_stall_ep(xhci, epctx, xfer);
DPRINTF("xhci: transfer actual length = %d\n", transfer->actual_length);
if (xfer->in_xfer) {
if (xfer->epid == 1) {
xhci_xfer_data(xhci, xfer, xfer->data + 8,
transfer->actual_length, 1, 0, 1);
} else {
xhci_xfer_data(xhci, xfer, xfer->data,
transfer->actual_length, 1, 0, 1);
}
} else {
xhci_xfer_data(xhci, xfer, NULL, transfer->actual_length, 0, 0, 1);
}
xhci_kick_ep(xhci, xfer->slotid, xfer->epid);
}
static int xhci_hle_control(XHCIState *xhci, XHCITransfer *xfer,
uint8_t bmRequestType, uint8_t bRequest,
uint16_t wValue, uint16_t wIndex, uint16_t wLength)
{
uint16_t type_req = (bmRequestType << 8) | bRequest;
switch (type_req) {
case 0x0000 | USB_REQ_SET_CONFIGURATION:
DPRINTF("xhci: HLE switch configuration\n");
return xhci_switch_config(xhci, xfer->slotid, wValue) == 0;
case 0x0100 | USB_REQ_SET_INTERFACE:
DPRINTF("xhci: HLE set interface altsetting\n");
return xhci_set_iface_alt(xhci, xfer->slotid, wIndex, wValue) == 0;
case 0x0200 | USB_REQ_CLEAR_FEATURE:
if (wValue == 0) { // endpoint halt
DPRINTF("xhci: HLE clear halt\n");
return xhci_clear_halt(xhci, xfer->slotid, wIndex);
}
case 0x0000 | USB_REQ_SET_ADDRESS:
fprintf(stderr, "xhci: warn: illegal SET_ADDRESS request\n");
return 0;
default:
return 0;
}
}
#endif
static int xhci_setup_packet(XHCITransfer *xfer, USBDevice *dev)
{
USBEndpoint *ep;
@@ -1393,7 +1204,7 @@ static int xhci_setup_packet(XHCITransfer *xfer, USBDevice *dev)
dir = xfer->in_xfer ? USB_TOKEN_IN : USB_TOKEN_OUT;
ep = usb_ep_get(dev, dir, xfer->epid >> 1);
usb_packet_setup(&xfer->packet, dir, ep, xfer->trbs[0].addr);
usb_packet_addbuf(&xfer->packet, xfer->data, xfer->data_length);
xhci_xfer_map(xfer);
DPRINTF("xhci: setup packet pid 0x%x addr %d ep %d\n",
xfer->packet.pid, dev->addr, ep->nr);
return 0;
@@ -1419,12 +1230,13 @@ static int xhci_complete_packet(XHCITransfer *xfer, int ret)
xfer->running_async = 0;
xfer->running_retry = 0;
xfer->complete = 1;
xhci_xfer_unmap(xfer);
}
if (ret >= 0) {
xfer->status = CC_SUCCESS;
xhci_xfer_data(xfer, xfer->data, ret, xfer->in_xfer, 0, 1);
trace_usb_xhci_xfer_success(xfer, ret);
xfer->status = CC_SUCCESS;
xhci_xfer_report(xfer);
return 0;
}
@@ -1433,12 +1245,12 @@ static int xhci_complete_packet(XHCITransfer *xfer, int ret)
switch (ret) {
case USB_RET_NODEV:
xfer->status = CC_USB_TRANSACTION_ERROR;
xhci_xfer_data(xfer, xfer->data, 0, xfer->in_xfer, 0, 1);
xhci_xfer_report(xfer);
xhci_stall_ep(xfer);
break;
case USB_RET_STALL:
xfer->status = CC_STALL_ERROR;
xhci_xfer_data(xfer, xfer->data, 0, xfer->in_xfer, 0, 1);
xhci_xfer_report(xfer);
xhci_stall_ep(xfer);
break;
default:
@@ -1460,7 +1272,6 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
{
XHCITRB *trb_setup, *trb_status;
uint8_t bmRequestType;
uint16_t wLength;
XHCIPort *port;
USBDevice *dev;
int ret;
@@ -1468,8 +1279,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
trb_setup = &xfer->trbs[0];
trb_status = &xfer->trbs[xfer->trb_count-1];
trace_usb_xhci_xfer_start(xfer, xfer->slotid, xfer->epid,
trb_setup->parameter >> 48);
trace_usb_xhci_xfer_start(xfer, xfer->slotid, xfer->epid);
/* at most one Event Data TRB allowed after STATUS */
if (TRB_TYPE(*trb_status) == TR_EVDATA && xfer->trb_count > 2) {
@@ -1498,19 +1308,6 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
}
bmRequestType = trb_setup->parameter;
wLength = trb_setup->parameter >> 48;
if (xfer->data && xfer->data_alloced < wLength) {
xfer->data_alloced = 0;
g_free(xfer->data);
xfer->data = NULL;
}
if (!xfer->data) {
DPRINTF("xhci: alloc %d bytes data\n", wLength);
xfer->data = g_malloc(wLength+1);
xfer->data_alloced = wLength;
}
xfer->data_length = wLength;
port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1];
dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr);
@@ -1525,9 +1322,6 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
xhci_setup_packet(xfer, dev);
xfer->packet.parameter = trb_setup->parameter;
if (!xfer->in_xfer) {
xhci_xfer_data(xfer, xfer->data, wLength, 0, 1, 0);
}
ret = usb_handle_packet(dev, &xfer->packet);
@@ -1548,20 +1342,8 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
xfer->in_xfer = epctx->type>>2;
if (xfer->data && xfer->data_alloced < xfer->data_length) {
xfer->data_alloced = 0;
g_free(xfer->data);
xfer->data = NULL;
}
if (!xfer->data && xfer->data_length) {
DPRINTF("xhci: alloc %d bytes data\n", xfer->data_length);
xfer->data = g_malloc(xfer->data_length);
xfer->data_alloced = xfer->data_length;
}
if (epctx->type == ET_ISO_IN || epctx->type == ET_ISO_OUT) {
if (!xfer->bg_xfer) {
xfer->pkts = 1;
}
xfer->pkts = 1;
} else {
xfer->pkts = 0;
}
@@ -1593,9 +1375,6 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
return -1;
}
if (!xfer->in_xfer) {
xhci_xfer_data(xfer, xfer->data, xfer->data_length, 0, 1, 0);
}
ret = usb_handle_packet(dev, &xfer->packet);
xhci_complete_packet(xfer, ret);
@@ -1607,45 +1386,8 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
static int xhci_fire_transfer(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx)
{
int i;
unsigned int length = 0;
XHCITRB *trb;
for (i = 0; i < xfer->trb_count; i++) {
trb = &xfer->trbs[i];
if (TRB_TYPE(*trb) == TR_NORMAL || TRB_TYPE(*trb) == TR_ISOCH) {
length += trb->status & 0x1ffff;
}
}
trace_usb_xhci_xfer_start(xfer, xfer->slotid, xfer->epid, length);
if (!epctx->has_bg) {
xfer->data_length = length;
xfer->backgrounded = 0;
return xhci_submit(xhci, xfer, epctx);
} else {
if (!epctx->bg_running) {
for (i = 0; i < BG_XFERS; i++) {
XHCITransfer *t = &epctx->bg_transfers[i];
t->xhci = xhci;
t->epid = xfer->epid;
t->slotid = xfer->slotid;
t->pkts = BG_PKTS;
t->pktsize = epctx->max_psize;
t->data_length = t->pkts * t->pktsize;
t->bg_xfer = 1;
if (xhci_submit(xhci, t, epctx) < 0) {
fprintf(stderr, "xhci: bg submit failed\n");
return -1;
}
}
epctx->bg_running = 1;
}
xfer->backgrounded = 1;
xhci_bg_update(xhci, epctx);
return 0;
}
trace_usb_xhci_xfer_start(xfer, xfer->slotid, xfer->epid);
return xhci_submit(xhci, xfer, epctx);
}
static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid)
@@ -1695,7 +1437,7 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid
while (1) {
XHCITransfer *xfer = &epctx->transfers[epctx->next_xfer];
if (xfer->running_async || xfer->running_retry || xfer->backgrounded) {
if (xfer->running_async || xfer->running_retry) {
break;
}
length = xhci_ring_chain_length(xhci, &epctx->ring);
@@ -2356,7 +2098,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
ret = 0x02000402; /* USB 2.0 */
break;
case 0x24: /* Supported Protocol:04 */
ret = 0x20425455; /* "USB " */
ret = 0x20425355; /* "USB " */
break;
case 0x28: /* Supported Protocol:08 */
ret = 0x00000001 | (USB2_PORTS<<8);
@@ -2368,7 +2110,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
ret = 0x03000002; /* USB 3.0 */
break;
case 0x34: /* Supported Protocol:04 */
ret = 0x20425455; /* "USB " */
ret = 0x20425355; /* "USB " */
break;
case 0x38: /* Supported Protocol:08 */
ret = 0x00000000 | (USB2_PORTS+1) | (USB3_PORTS<<8);
@@ -2606,7 +2348,7 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
{
trace_usb_xhci_runtime_read(reg, val);
trace_usb_xhci_runtime_write(reg, val);
switch (reg) {
case 0x20: /* IMAN */
@@ -2732,8 +2474,10 @@ static void xhci_mem_write(void *ptr, target_phys_addr_t addr,
static const MemoryRegionOps xhci_mem_ops = {
.read = xhci_mem_read,
.write = xhci_mem_write,
.valid.min_access_size = 4,
.valid.min_access_size = 1,
.valid.max_access_size = 4,
.impl.min_access_size = 4,
.impl.max_access_size = 4,
.endianness = DEVICE_LITTLE_ENDIAN,
};

View File

@@ -1045,7 +1045,6 @@ static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
/* Note request is (bRequestType << 8) | bRequest */
trace_usb_host_req_control(s->bus_num, s->addr, p, request, value, index);
assert(p->result == 0);
switch (request) {
case DeviceOutRequest | USB_REQ_SET_ADDRESS:
@@ -1074,6 +1073,7 @@ static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
}
/* The rest are asynchronous */
assert(p && p->result == 0);
if (length > sizeof(dev->data_buf)) {
fprintf(stderr, "husb: ctrl buffer too small (%d > %zu)\n",

View File

@@ -1,7 +1,7 @@
/*
* USB redirector usb-guest
*
* Copyright (c) 2011 Red Hat, Inc.
* Copyright (c) 2011-2012 Red Hat, Inc.
*
* Red Hat Authors:
* Hans de Goede <hdegoede@redhat.com>
@@ -43,7 +43,7 @@
#define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
#define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
typedef struct AsyncURB AsyncURB;
typedef struct Cancelled Cancelled;
typedef struct USBRedirDevice USBRedirDevice;
/* Struct to hold buffered packets (iso or int input packets) */
@@ -79,15 +79,14 @@ struct USBRedirDevice {
/* Data passed from chardev the fd_read cb to the usbredirparser read cb */
const uint8_t *read_buf;
int read_buf_size;
/* For async handling of open/close */
QEMUBH *open_close_bh;
/* For async handling of close */
QEMUBH *chardev_close_bh;
/* To delay the usb attach in case of quick chardev close + open */
QEMUTimer *attach_timer;
int64_t next_attach_time;
struct usbredirparser *parser;
struct endp_data endpoint[MAX_ENDPOINTS];
uint32_t packet_id;
QTAILQ_HEAD(, AsyncURB) asyncq;
QTAILQ_HEAD(, Cancelled) cancelled;
/* Data for device filtering */
struct usb_redir_device_connect_header device_info;
struct usb_redir_interface_info_header interface_info;
@@ -95,17 +94,9 @@ struct USBRedirDevice {
int filter_rules_count;
};
struct AsyncURB {
USBRedirDevice *dev;
USBPacket *packet;
uint32_t packet_id;
int get;
union {
struct usb_redir_control_packet_header control_packet;
struct usb_redir_bulk_packet_header bulk_packet;
struct usb_redir_interrupt_packet_header interrupt_packet;
};
QTAILQ_ENTRY(AsyncURB)next;
struct Cancelled {
uint64_t id;
QTAILQ_ENTRY(Cancelled)next;
};
static void usbredir_hello(void *priv, struct usb_redir_hello_header *h);
@@ -143,6 +134,8 @@ static void usbredir_interrupt_packet(void *priv, uint32_t id,
static int usbredir_handle_status(USBRedirDevice *dev,
int status, int actual_len);
#define VERSION "qemu usb-redir guest " QEMU_VERSION
/*
* Logging stuff
*/
@@ -245,58 +238,58 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
}
/*
* Async and buffered packets helpers
* Cancelled and buffered packets helpers
*/
static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
{
AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
aurb->dev = dev;
aurb->packet = p;
aurb->packet_id = dev->packet_id;
QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
dev->packet_id++;
return aurb;
}
static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
{
QTAILQ_REMOVE(&dev->asyncq, aurb, next);
g_free(aurb);
}
static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
{
AsyncURB *aurb;
QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
if (aurb->packet_id == packet_id) {
return aurb;
}
}
DPRINTF("could not find async urb for packet_id %u\n", packet_id);
return NULL;
}
static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
{
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
AsyncURB *aurb;
Cancelled *c;
QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
if (p != aurb->packet) {
continue;
}
DPRINTF("cancel packet id %"PRIu64"\n", p->id);
DPRINTF("async cancel id %u\n", aurb->packet_id);
usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
usbredirparser_do_write(dev->parser);
c = g_malloc0(sizeof(Cancelled));
c->id = p->id;
QTAILQ_INSERT_TAIL(&dev->cancelled, c, next);
/* Mark it as dead */
aurb->packet = NULL;
break;
usbredirparser_send_cancel_data_packet(dev->parser, p->id);
usbredirparser_do_write(dev->parser);
}
static int usbredir_is_cancelled(USBRedirDevice *dev, uint64_t id)
{
Cancelled *c;
if (!dev->dev.attached) {
return 1; /* Treat everything as cancelled after a disconnect */
}
QTAILQ_FOREACH(c, &dev->cancelled, next) {
if (c->id == id) {
QTAILQ_REMOVE(&dev->cancelled, c, next);
g_free(c);
return 1;
}
}
return 0;
}
static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev,
uint8_t ep, uint64_t id)
{
USBPacket *p;
if (usbredir_is_cancelled(dev, id)) {
return NULL;
}
p = usb_ep_find_packet_by_id(&dev->dev,
(ep & USB_DIR_IN) ? USB_TOKEN_IN : USB_TOKEN_OUT,
ep & 0x0f, id);
if (p == NULL) {
ERROR("could not find packet with id %"PRIu64"\n", id);
}
return p;
}
static void bufp_alloc(USBRedirDevice *dev,
@@ -492,25 +485,22 @@ static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
uint8_t ep)
{
AsyncURB *aurb = async_alloc(dev, p);
struct usb_redir_bulk_packet_header bulk_packet;
DPRINTF("bulk-out ep %02X len %zd id %u\n", ep,
p->iov.size, aurb->packet_id);
DPRINTF("bulk-out ep %02X len %zd id %"PRIu64"\n", ep, p->iov.size, p->id);
bulk_packet.endpoint = ep;
bulk_packet.length = p->iov.size;
bulk_packet.stream_id = 0;
aurb->bulk_packet = bulk_packet;
if (ep & USB_DIR_IN) {
usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
usbredirparser_send_bulk_packet(dev->parser, p->id,
&bulk_packet, NULL, 0);
} else {
uint8_t buf[p->iov.size];
usb_packet_copy(p, buf, p->iov.size);
usbredir_log_data(dev, "bulk data out:", buf, p->iov.size);
usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
usbredirparser_send_bulk_packet(dev->parser, p->id,
&bulk_packet, buf, p->iov.size);
}
usbredirparser_do_write(dev->parser);
@@ -573,20 +563,18 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
return len;
} else {
/* Output interrupt endpoint, normal async operation */
AsyncURB *aurb = async_alloc(dev, p);
struct usb_redir_interrupt_packet_header interrupt_packet;
uint8_t buf[p->iov.size];
DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,
aurb->packet_id);
DPRINTF("interrupt-out ep %02X len %zd id %"PRIu64"\n", ep,
p->iov.size, p->id);
interrupt_packet.endpoint = ep;
interrupt_packet.length = p->iov.size;
aurb->interrupt_packet = interrupt_packet;
usb_packet_copy(p, buf, p->iov.size);
usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
usbredirparser_send_interrupt_packet(dev->parser, p->id,
&interrupt_packet, buf, p->iov.size);
usbredirparser_do_write(dev->parser);
return USB_RET_ASYNC;
@@ -640,10 +628,9 @@ static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
int config)
{
struct usb_redir_set_configuration_header set_config;
AsyncURB *aurb = async_alloc(dev, p);
int i;
DPRINTF("set config %d id %u\n", config, aurb->packet_id);
DPRINTF("set config %d id %"PRIu64"\n", config, p->id);
for (i = 0; i < MAX_ENDPOINTS; i++) {
switch (dev->endpoint[i].type) {
@@ -660,20 +647,16 @@ static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
}
set_config.configuration = config;
usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
&set_config);
usbredirparser_send_set_configuration(dev->parser, p->id, &set_config);
usbredirparser_do_write(dev->parser);
return USB_RET_ASYNC;
}
static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
{
AsyncURB *aurb = async_alloc(dev, p);
DPRINTF("get config id %"PRIu64"\n", p->id);
DPRINTF("get config id %u\n", aurb->packet_id);
aurb->get = 1;
usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
usbredirparser_send_get_configuration(dev->parser, p->id);
usbredirparser_do_write(dev->parser);
return USB_RET_ASYNC;
}
@@ -682,11 +665,9 @@ static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
int interface, int alt)
{
struct usb_redir_set_alt_setting_header set_alt;
AsyncURB *aurb = async_alloc(dev, p);
int i;
DPRINTF("set interface %d alt %d id %u\n", interface, alt,
aurb->packet_id);
DPRINTF("set interface %d alt %d id %"PRIu64"\n", interface, alt, p->id);
for (i = 0; i < MAX_ENDPOINTS; i++) {
if (dev->endpoint[i].interface == interface) {
@@ -706,8 +687,7 @@ static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
set_alt.interface = interface;
set_alt.alt = alt;
usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
&set_alt);
usbredirparser_send_set_alt_setting(dev->parser, p->id, &set_alt);
usbredirparser_do_write(dev->parser);
return USB_RET_ASYNC;
}
@@ -716,14 +696,11 @@ static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
int interface)
{
struct usb_redir_get_alt_setting_header get_alt;
AsyncURB *aurb = async_alloc(dev, p);
DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
DPRINTF("get interface %d id %"PRIu64"\n", interface, p->id);
get_alt.interface = interface;
aurb->get = 1;
usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
&get_alt);
usbredirparser_send_get_alt_setting(dev->parser, p->id, &get_alt);
usbredirparser_do_write(dev->parser);
return USB_RET_ASYNC;
}
@@ -733,7 +710,6 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
{
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
struct usb_redir_control_packet_header control_packet;
AsyncURB *aurb;
/* Special cases for certain standard device requests */
switch (request) {
@@ -751,13 +727,10 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
return usbredir_get_interface(dev, p, index);
}
/* "Normal" ctrl requests */
aurb = async_alloc(dev, p);
/* Note request is (bRequestType << 8) | bRequest */
DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
request >> 8, request & 0xff, value, index, length,
aurb->packet_id);
/* Normal ctrl requests, note request is (bRequestType << 8) | bRequest */
DPRINTF(
"ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %"PRIu64"\n",
request >> 8, request & 0xff, value, index, length, p->id);
control_packet.request = request & 0xFF;
control_packet.requesttype = request >> 8;
@@ -765,14 +738,13 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
control_packet.value = value;
control_packet.index = index;
control_packet.length = length;
aurb->control_packet = control_packet;
if (control_packet.requesttype & USB_DIR_IN) {
usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
usbredirparser_send_control_packet(dev->parser, p->id,
&control_packet, NULL, 0);
} else {
usbredir_log_data(dev, "ctrl data out:", data, length);
usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
usbredirparser_send_control_packet(dev->parser, p->id,
&control_packet, data, length);
}
usbredirparser_do_write(dev->parser);
@@ -784,18 +756,11 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
* from within the USBDevice data / control packet callbacks and doing a
* usb_detach from within these callbacks is not a good idea.
*
* So we use a bh handler to take care of close events. We also handle
* open events from this callback to make sure that a close directly followed
* by an open gets handled in the right order.
* So we use a bh handler to take care of close events.
*/
static void usbredir_open_close_bh(void *opaque)
static void usbredir_chardev_close_bh(void *opaque)
{
USBRedirDevice *dev = opaque;
uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
char version[32];
strcpy(version, "qemu usb-redir guest ");
pstrcat(version, sizeof(version), qemu_get_version());
usbredir_device_disconnect(dev);
@@ -803,36 +768,44 @@ static void usbredir_open_close_bh(void *opaque)
usbredirparser_destroy(dev->parser);
dev->parser = NULL;
}
}
if (dev->cs->opened) {
dev->parser = qemu_oom_check(usbredirparser_create());
dev->parser->priv = dev;
dev->parser->log_func = usbredir_log;
dev->parser->read_func = usbredir_read;
dev->parser->write_func = usbredir_write;
dev->parser->hello_func = usbredir_hello;
dev->parser->device_connect_func = usbredir_device_connect;
dev->parser->device_disconnect_func = usbredir_device_disconnect;
dev->parser->interface_info_func = usbredir_interface_info;
dev->parser->ep_info_func = usbredir_ep_info;
dev->parser->configuration_status_func = usbredir_configuration_status;
dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
dev->parser->interrupt_receiving_status_func =
usbredir_interrupt_receiving_status;
dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
dev->parser->control_packet_func = usbredir_control_packet;
dev->parser->bulk_packet_func = usbredir_bulk_packet;
dev->parser->iso_packet_func = usbredir_iso_packet;
dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
dev->read_buf = NULL;
dev->read_buf_size = 0;
static void usbredir_chardev_open(USBRedirDevice *dev)
{
uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
char version[32];
usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
usbredirparser_do_write(dev->parser);
}
/* Make sure any pending closes are handled (no-op if none pending) */
usbredir_chardev_close_bh(dev);
qemu_bh_cancel(dev->chardev_close_bh);
dev->parser = qemu_oom_check(usbredirparser_create());
dev->parser->priv = dev;
dev->parser->log_func = usbredir_log;
dev->parser->read_func = usbredir_read;
dev->parser->write_func = usbredir_write;
dev->parser->hello_func = usbredir_hello;
dev->parser->device_connect_func = usbredir_device_connect;
dev->parser->device_disconnect_func = usbredir_device_disconnect;
dev->parser->interface_info_func = usbredir_interface_info;
dev->parser->ep_info_func = usbredir_ep_info;
dev->parser->configuration_status_func = usbredir_configuration_status;
dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
dev->parser->interrupt_receiving_status_func =
usbredir_interrupt_receiving_status;
dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
dev->parser->control_packet_func = usbredir_control_packet;
dev->parser->bulk_packet_func = usbredir_bulk_packet;
dev->parser->iso_packet_func = usbredir_iso_packet;
dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
dev->read_buf = NULL;
dev->read_buf_size = 0;
usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0);
usbredirparser_do_write(dev->parser);
}
static void usbredir_do_attach(void *opaque)
@@ -856,13 +829,13 @@ static int usbredir_chardev_can_read(void *opaque)
{
USBRedirDevice *dev = opaque;
if (dev->parser) {
/* usbredir_parser_do_read will consume *all* data we give it */
return 1024 * 1024;
} else {
/* usbredir_open_close_bh hasn't handled the open event yet */
if (!dev->parser) {
WARNING("chardev_can_read called on non open chardev!\n");
return 0;
}
/* usbredir_parser_do_read will consume *all* data we give it */
return 1024 * 1024;
}
static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
@@ -886,8 +859,10 @@ static void usbredir_chardev_event(void *opaque, int event)
switch (event) {
case CHR_EVENT_OPENED:
usbredir_chardev_open(dev);
break;
case CHR_EVENT_CLOSED:
qemu_bh_schedule(dev->open_close_bh);
qemu_bh_schedule(dev->chardev_close_bh);
break;
}
}
@@ -917,10 +892,10 @@ static int usbredir_initfn(USBDevice *udev)
}
}
dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
QTAILQ_INIT(&dev->asyncq);
QTAILQ_INIT(&dev->cancelled);
for (i = 0; i < MAX_ENDPOINTS; i++) {
QTAILQ_INIT(&dev->endpoint[i].bufpq);
}
@@ -939,11 +914,12 @@ static int usbredir_initfn(USBDevice *udev)
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
{
AsyncURB *aurb, *next_aurb;
Cancelled *c, *next_c;
int i;
QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
async_free(dev, aurb);
QTAILQ_FOREACH_SAFE(c, &dev->cancelled, next, next_c) {
QTAILQ_REMOVE(&dev->cancelled, c, next);
g_free(c);
}
for (i = 0; i < MAX_ENDPOINTS; i++) {
usbredir_free_bufpq(dev, I2EP(i));
@@ -957,7 +933,7 @@ static void usbredir_handle_destroy(USBDevice *udev)
qemu_chr_fe_close(dev->cs);
qemu_chr_delete(dev->cs);
/* Note must be done after qemu_chr_close, as that causes a close event */
qemu_bh_delete(dev->open_close_bh);
qemu_bh_delete(dev->chardev_close_bh);
qemu_del_timer(dev->attach_timer);
qemu_free_timer(dev->attach_timer);
@@ -1028,11 +1004,14 @@ static int usbredir_handle_status(USBRedirDevice *dev,
case usb_redir_stall:
return USB_RET_STALL;
case usb_redir_cancelled:
WARNING("returning cancelled packet to HC?\n");
return USB_RET_NAK;
/*
* When the usbredir-host unredirects a device, it will report a status
* of cancelled for all pending packets, followed by a disconnect msg.
*/
return USB_RET_IOERROR;
case usb_redir_inval:
WARNING("got invalid param error from usb-host?\n");
return USB_RET_NAK;
return USB_RET_IOERROR;
case usb_redir_babble:
return USB_RET_BABBLE;
case usb_redir_ioerror:
@@ -1206,33 +1185,28 @@ static void usbredir_configuration_status(void *priv, uint32_t id,
struct usb_redir_configuration_status_header *config_status)
{
USBRedirDevice *dev = priv;
AsyncURB *aurb;
USBPacket *p;
int len = 0;
DPRINTF("set config status %d config %d id %u\n", config_status->status,
config_status->configuration, id);
aurb = async_find(dev, id);
if (!aurb) {
return;
}
if (aurb->packet) {
if (aurb->get) {
p = usbredir_find_packet_by_id(dev, 0, id);
if (p) {
if (dev->dev.setup_buf[0] & USB_DIR_IN) {
dev->dev.data_buf[0] = config_status->configuration;
len = 1;
}
aurb->packet->result =
usbredir_handle_status(dev, config_status->status, len);
usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
p->result = usbredir_handle_status(dev, config_status->status, len);
usb_generic_async_ctrl_complete(&dev->dev, p);
}
async_free(dev, aurb);
}
static void usbredir_alt_setting_status(void *priv, uint32_t id,
struct usb_redir_alt_setting_status_header *alt_setting_status)
{
USBRedirDevice *dev = priv;
AsyncURB *aurb;
USBPacket *p;
int len = 0;
DPRINTF("alt status %d intf %d alt %d id: %u\n",
@@ -1240,20 +1214,16 @@ static void usbredir_alt_setting_status(void *priv, uint32_t id,
alt_setting_status->interface,
alt_setting_status->alt, id);
aurb = async_find(dev, id);
if (!aurb) {
return;
}
if (aurb->packet) {
if (aurb->get) {
p = usbredir_find_packet_by_id(dev, 0, id);
if (p) {
if (dev->dev.setup_buf[0] & USB_DIR_IN) {
dev->dev.data_buf[0] = alt_setting_status->alt;
len = 1;
}
aurb->packet->result =
p->result =
usbredir_handle_status(dev, alt_setting_status->status, len);
usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
usb_generic_async_ctrl_complete(&dev->dev, p);
}
async_free(dev, aurb);
}
static void usbredir_iso_stream_status(void *priv, uint32_t id,
@@ -1308,27 +1278,14 @@ static void usbredir_control_packet(void *priv, uint32_t id,
uint8_t *data, int data_len)
{
USBRedirDevice *dev = priv;
USBPacket *p;
int len = control_packet->length;
AsyncURB *aurb;
DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
len, id);
aurb = async_find(dev, id);
if (!aurb) {
free(data);
return;
}
aurb->control_packet.status = control_packet->status;
aurb->control_packet.length = control_packet->length;
if (memcmp(&aurb->control_packet, control_packet,
sizeof(*control_packet))) {
ERROR("return control packet mismatch, please report this!\n");
len = USB_RET_NAK;
}
if (aurb->packet) {
p = usbredir_find_packet_by_id(dev, 0, id);
if (p) {
len = usbredir_handle_status(dev, control_packet->status, len);
if (len > 0) {
usbredir_log_data(dev, "ctrl data in:", data, data_len);
@@ -1340,10 +1297,9 @@ static void usbredir_control_packet(void *priv, uint32_t id,
len = USB_RET_STALL;
}
}
aurb->packet->result = len;
usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
p->result = len;
usb_generic_async_ctrl_complete(&dev->dev, p);
}
async_free(dev, aurb);
free(data);
}
@@ -1354,39 +1310,27 @@ static void usbredir_bulk_packet(void *priv, uint32_t id,
USBRedirDevice *dev = priv;
uint8_t ep = bulk_packet->endpoint;
int len = bulk_packet->length;
AsyncURB *aurb;
USBPacket *p;
DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
ep, len, id);
aurb = async_find(dev, id);
if (!aurb) {
free(data);
return;
}
if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
ERROR("return bulk packet mismatch, please report this!\n");
len = USB_RET_NAK;
}
if (aurb->packet) {
p = usbredir_find_packet_by_id(dev, ep, id);
if (p) {
len = usbredir_handle_status(dev, bulk_packet->status, len);
if (len > 0) {
usbredir_log_data(dev, "bulk data in:", data, data_len);
if (data_len <= aurb->packet->iov.size) {
usb_packet_copy(aurb->packet, data, data_len);
if (data_len <= p->iov.size) {
usb_packet_copy(p, data, data_len);
} else {
ERROR("bulk buffer too small (%d > %zd)\n", data_len,
aurb->packet->iov.size);
len = USB_RET_STALL;
ERROR("bulk got more data then requested (%d > %zd)\n",
data_len, p->iov.size);
len = USB_RET_BABBLE;
}
}
aurb->packet->result = len;
usb_packet_complete(&dev->dev, aurb->packet);
p->result = len;
usb_packet_complete(&dev->dev, p);
}
async_free(dev, aurb);
free(data);
}
@@ -1444,22 +1388,12 @@ static void usbredir_interrupt_packet(void *priv, uint32_t id,
} else {
int len = interrupt_packet->length;
AsyncURB *aurb = async_find(dev, id);
if (!aurb) {
return;
}
if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
ERROR("return int packet mismatch, please report this!\n");
len = USB_RET_NAK;
}
if (aurb->packet) {
aurb->packet->result = usbredir_handle_status(dev,
USBPacket *p = usbredir_find_packet_by_id(dev, ep, id);
if (p) {
p->result = usbredir_handle_status(dev,
interrupt_packet->status, len);
usb_packet_complete(&dev->dev, aurb->packet);
usb_packet_complete(&dev->dev, p);
}
async_free(dev, aurb);
}
}

View File

@@ -62,7 +62,6 @@ enum {
VE_COMPACTFLASH,
VE_CLCD,
VE_NORFLASH0,
VE_NORFLASH0ALIAS,
VE_NORFLASH1,
VE_SRAM,
VE_VIDEORAM,
@@ -104,9 +103,8 @@ static target_phys_addr_t motherboard_legacy_map[] = {
};
static target_phys_addr_t motherboard_aseries_map[] = {
/* CS0: 0x00000000 .. 0x0c000000 */
[VE_NORFLASH0] = 0x00000000,
[VE_NORFLASH0ALIAS] = 0x08000000,
/* CS0: 0x08000000 .. 0x0c000000 */
[VE_NORFLASH0] = 0x08000000,
/* CS4: 0x0c000000 .. 0x10000000 */
[VE_NORFLASH1] = 0x0c000000,
/* CS5: 0x10000000 .. 0x14000000 */
@@ -413,7 +411,6 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard,
sysbus_create_simple("pl111", map[VE_CLCD], pic[14]);
/* VE_NORFLASH0: not modelled */
/* VE_NORFLASH0ALIAS: not modelled */
/* VE_NORFLASH1: not modelled */
sram_size = 0x2000000;

View File

@@ -447,10 +447,6 @@ static void virtio_net_handle_rx(VirtIODevice *vdev, VirtQueue *vq)
VirtIONet *n = to_virtio_net(vdev);
qemu_flush_queued_packets(&n->nic->nc);
/* We now have RX buffers, signal to the IO thread to break out of the
* select to re-poll the tap file descriptor */
qemu_notify_event();
}
static int virtio_net_can_receive(NetClientState *nc)

View File

@@ -424,15 +424,17 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
size_t resid)
{
VirtIOSCSIReq *req = r->hba_private;
uint32_t sense_len;
req->resp.cmd->response = VIRTIO_SCSI_S_OK;
req->resp.cmd->status = status;
if (req->resp.cmd->status == GOOD) {
req->resp.cmd->resid = resid;
req->resp.cmd->resid = tswap32(resid);
} else {
req->resp.cmd->resid = 0;
req->resp.cmd->sense_len =
scsi_req_get_sense(r, req->resp.cmd->sense, VIRTIO_SCSI_SENSE_SIZE);
sense_len = scsi_req_get_sense(r, req->resp.cmd->sense,
VIRTIO_SCSI_SENSE_SIZE);
req->resp.cmd->sense_len = tswap32(sense_len);
}
virtio_scsi_complete_req(req);
}
@@ -532,8 +534,8 @@ static void virtio_scsi_get_config(VirtIODevice *vdev,
stl_raw(&scsiconf->event_info_size, sizeof(VirtIOSCSIEvent));
stl_raw(&scsiconf->sense_size, s->sense_size);
stl_raw(&scsiconf->cdb_size, s->cdb_size);
stl_raw(&scsiconf->max_channel, VIRTIO_SCSI_MAX_CHANNEL);
stl_raw(&scsiconf->max_target, VIRTIO_SCSI_MAX_TARGET);
stw_raw(&scsiconf->max_channel, VIRTIO_SCSI_MAX_CHANNEL);
stw_raw(&scsiconf->max_target, VIRTIO_SCSI_MAX_TARGET);
stl_raw(&scsiconf->max_lun, VIRTIO_SCSI_MAX_LUN);
}

View File

@@ -361,10 +361,10 @@ static int wm8750_tx(I2CSlave *i2c, uint8_t data)
uint16_t value;
if (s->i2c_len >= 2) {
printf("%s: long message (%i bytes)\n", __FUNCTION__, s->i2c_len);
#ifdef VERBOSE
return 1;
printf("%s: long message (%i bytes)\n", __func__, s->i2c_len);
#endif
return 1;
}
s->i2c_data[s->i2c_len ++] = data;
if (s->i2c_len != 2)

View File

@@ -415,6 +415,7 @@ static void net_event(struct XenDevice *xendev)
{
struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
net_tx_packets(netdev);
qemu_flush_queued_packets(&netdev->nic->nc);
}
static int net_free(struct XenDevice *xendev)

View File

@@ -96,7 +96,7 @@ typedef struct XenPTRegion {
* - do NOT use ALL F for init_val, otherwise the tbl will not be registered.
*/
/* emulated register infomation */
/* emulated register information */
struct XenPTRegInfo {
uint32_t offset;
uint32_t size;
@@ -140,7 +140,7 @@ typedef int (*xen_pt_reg_size_init_fn)
(XenPCIPassthroughState *, const XenPTRegGroupInfo *,
uint32_t base_offset, uint8_t *size);
/* emulated register group infomation */
/* emulated register group information */
struct XenPTRegGroupInfo {
uint8_t grp_id;
XenPTRegisterGroupType grp_type;

View File

@@ -562,7 +562,7 @@ static int xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,
return 0;
}
/* Header Type0 reg static infomation table */
/* Header Type0 reg static information table */
static XenPTRegInfo xen_pt_emu_reg_header0[] = {
/* Vendor ID reg */
{
@@ -753,7 +753,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
* Vital Product Data Capability
*/
/* Vital Product Data Capability Structure reg static infomation table */
/* Vital Product Data Capability Structure reg static information table */
static XenPTRegInfo xen_pt_emu_reg_vpd[] = {
{
.offset = PCI_CAP_LIST_NEXT,
@@ -775,7 +775,7 @@ static XenPTRegInfo xen_pt_emu_reg_vpd[] = {
* Vendor Specific Capability
*/
/* Vendor Specific Capability Structure reg static infomation table */
/* Vendor Specific Capability Structure reg static information table */
static XenPTRegInfo xen_pt_emu_reg_vendor[] = {
{
.offset = PCI_CAP_LIST_NEXT,
@@ -866,7 +866,7 @@ static int xen_pt_linkctrl2_reg_init(XenPCIPassthroughState *s,
return 0;
}
/* PCI Express Capability Structure reg static infomation table */
/* PCI Express Capability Structure reg static information table */
static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
/* Next Pointer reg */
{
@@ -981,7 +981,7 @@ static int xen_pt_pmcsr_reg_write(XenPCIPassthroughState *s,
return 0;
}
/* Power Management Capability reg static infomation table */
/* Power Management Capability reg static information table */
static XenPTRegInfo xen_pt_emu_reg_pm[] = {
/* Next Pointer reg */
{
@@ -1259,7 +1259,7 @@ static int xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,
return 0;
}
/* MSI Capability Structure reg static infomation table */
/* MSI Capability Structure reg static information table */
static XenPTRegInfo xen_pt_emu_reg_msi[] = {
/* Next Pointer reg */
{
@@ -1396,7 +1396,7 @@ static int xen_pt_msixctrl_reg_write(XenPCIPassthroughState *s,
return 0;
}
/* MSI-X Capability Structure reg static infomation table */
/* MSI-X Capability Structure reg static information table */
static XenPTRegInfo xen_pt_emu_reg_msix[] = {
/* Next Pointer reg */
{

View File

@@ -21,7 +21,7 @@ xilinx_timer_create(target_phys_addr_t base, qemu_irq irq, int oto, int freq)
{
DeviceState *dev;
dev = qdev_create(NULL, "xlnx,xps-timer");
dev = qdev_create(NULL, "xlnx.xps-timer");
qdev_prop_set_uint32(dev, "one-timer-only", oto);
qdev_prop_set_uint32(dev, "frequency", freq);
qdev_init_nofail(dev);
@@ -55,13 +55,16 @@ xilinx_axiethernet_create(NICInfo *nd, StreamSlave *peer,
int txmem, int rxmem)
{
DeviceState *dev;
Error *errp = NULL;
qemu_check_nic_model(nd, "xlnx.axi-ethernet");
dev = qdev_create(NULL, "xlnx.axi-ethernet");
qdev_set_nic_properties(dev, nd);
qdev_prop_set_uint32(dev, "rxmem", rxmem);
qdev_prop_set_uint32(dev, "txmem", txmem);
object_property_set_link(OBJECT(dev), OBJECT(peer), "tx_dev", NULL);
object_property_set_link(OBJECT(dev), OBJECT(peer), "tx_dev", &errp);
assert_no_error(errp);
qdev_init_nofail(dev);
sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
@@ -74,8 +77,11 @@ xilinx_axiethernetdma_init(DeviceState *dev, StreamSlave *peer,
target_phys_addr_t base, qemu_irq irq,
qemu_irq irq2, int freqhz)
{
Error *errp = NULL;
qdev_prop_set_uint32(dev, "freqhz", freqhz);
object_property_set_link(OBJECT(dev), OBJECT(peer), "tx_dev", NULL);
object_property_set_link(OBJECT(dev), OBJECT(peer), "tx_dev", &errp);
assert_no_error(errp);
qdev_init_nofail(dev);
sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);

View File

@@ -24,6 +24,7 @@
#include "sysbus.h"
#include "ptimer.h"
#include "qemu-log.h"
#define D(x)
@@ -119,7 +120,7 @@ timer_read(void *opaque, target_phys_addr_t addr, unsigned int size)
break;
}
D(printf("%s timer=%d %x=%x\n", __func__, timer, addr * 4, r));
D(fprintf(stderr, "%s timer=%d %x=%x\n", __func__, timer, addr * 4, r));
return r;
}
@@ -127,7 +128,7 @@ static void timer_enable(struct xlx_timer *xt)
{
uint64_t count;
D(printf("%s timer=%d down=%d\n", __func__,
D(fprintf(stderr, "%s timer=%d down=%d\n", __func__,
xt->nr, xt->regs[R_TCSR] & TCSR_UDT));
ptimer_stop(xt->ptimer);
@@ -152,7 +153,7 @@ timer_write(void *opaque, target_phys_addr_t addr,
addr >>= 2;
timer = timer_from_addr(addr);
xt = &t->timers[timer];
D(printf("%s addr=%x val=%x (timer=%d off=%d)\n",
D(fprintf(stderr, "%s addr=%x val=%x (timer=%d off=%d)\n",
__func__, addr * 4, value, timer, addr & 3));
/* Further decoding to address a specific timers reg. */
addr &= 3;
@@ -189,7 +190,7 @@ static void timer_hit(void *opaque)
{
struct xlx_timer *xt = opaque;
struct timerblock *t = xt->parent;
D(printf("%s %d\n", __func__, timer));
D(fprintf(stderr, "%s %d\n", __func__, xt->nr));
xt->regs[R_TCSR] |= TCSR_TINT;
if (xt->regs[R_TCSR] & TCSR_ARHT)
@@ -217,7 +218,7 @@ static int xilinx_timer_init(SysBusDevice *dev)
ptimer_set_freq(xt->ptimer, t->freq_hz);
}
memory_region_init_io(&t->mmio, &timer_ops, t, "xlnx,xps-timer",
memory_region_init_io(&t->mmio, &timer_ops, t, "xlnx.xps-timer",
R_MAX * 4 * num_timers(t));
sysbus_init_mmio(dev, &t->mmio);
return 0;
@@ -239,7 +240,7 @@ static void xilinx_timer_class_init(ObjectClass *klass, void *data)
}
static TypeInfo xilinx_timer_info = {
.name = "xlnx,xps-timer",
.name = "xlnx.xps-timer",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct timerblock),
.class_init = xilinx_timer_class_init,

View File

@@ -42,7 +42,7 @@ static inline void ratelimit_set_speed(RateLimit *limit, uint64_t speed,
uint64_t slice_ns)
{
limit->slice_ns = slice_ns;
limit->slice_quota = ((double)speed * 1000000000ULL) / slice_ns;
limit->slice_quota = ((double)speed * slice_ns)/1000000000ULL;
}
#endif

View File

@@ -56,6 +56,8 @@ int qemu_set_fd_handler2(int fd,
{
IOHandlerRecord *ioh;
assert(fd >= 0);
if (!fd_read && !fd_write) {
QLIST_FOREACH(ioh, &io_handlers, next) {
if (ioh->fd == fd) {

View File

@@ -39,6 +39,10 @@
#include <sys/eventfd.h>
#endif
#ifdef CONFIG_VALGRIND_H
#include <valgrind/memcheck.h>
#endif
/* KVM uses PAGE_SIZE in its definition of COALESCED_MMIO_MAX */
#define PAGE_SIZE TARGET_PAGE_SIZE
@@ -1370,13 +1374,11 @@ int kvm_init(void)
return 0;
err:
if (s) {
if (s->vmfd >= 0) {
close(s->vmfd);
}
if (s->fd != -1) {
close(s->fd);
}
if (s->vmfd >= 0) {
close(s->vmfd);
}
if (s->fd != -1) {
close(s->fd);
}
g_free(s);
@@ -1719,6 +1721,9 @@ void *kvm_vmalloc(ram_addr_t size)
void kvm_setup_guest_memory(void *start, size_t size)
{
#ifdef CONFIG_VALGRIND_H
VALGRIND_MAKE_MEM_DEFINED(start, size);
#endif
if (!kvm_has_sync_mmu()) {
int ret = qemu_madvise(start, size, QEMU_MADV_DONTFORK);

View File

@@ -3628,9 +3628,7 @@ static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
unlock_user(argptr, arg, target_size);
}
out:
if (big_buf) {
free(big_buf);
}
g_free(big_buf);
return ret;
}

View File

@@ -538,12 +538,12 @@ static void render_memory_region(FlatView *view,
offset_in_region += int128_get64(now);
int128_subfrom(&remain, now);
}
if (int128_eq(base, view->ranges[i].addr.start)) {
now = int128_min(remain, view->ranges[i].addr.size);
int128_addto(&base, now);
offset_in_region += int128_get64(now);
int128_subfrom(&remain, now);
}
now = int128_sub(int128_min(int128_add(base, remain),
addrrange_end(view->ranges[i].addr)),
base);
int128_addto(&base, now);
offset_in_region += int128_get64(now);
int128_subfrom(&remain, now);
}
if (int128_nz(remain)) {
fr.mr = mr;

View File

@@ -53,54 +53,35 @@ static int tcp_close(MigrationState *s)
return r;
}
static void tcp_wait_for_connect(void *opaque)
static void tcp_wait_for_connect(int fd, void *opaque)
{
MigrationState *s = opaque;
int val, ret;
socklen_t valsize = sizeof(val);
DPRINTF("connect completed\n");
do {
ret = getsockopt(s->fd, SOL_SOCKET, SO_ERROR, (void *) &val, &valsize);
} while (ret == -1 && (socket_error()) == EINTR);
if (ret < 0) {
if (fd < 0) {
DPRINTF("migrate connect error\n");
s->fd = -1;
migrate_fd_error(s);
return;
}
qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
if (val == 0)
} else {
DPRINTF("migrate connect success\n");
s->fd = fd;
migrate_fd_connect(s);
else {
DPRINTF("error connecting %d\n", val);
migrate_fd_error(s);
}
}
int tcp_start_outgoing_migration(MigrationState *s, const char *host_port,
Error **errp)
{
bool in_progress;
s->get_error = socket_errno;
s->write = socket_write;
s->close = tcp_close;
s->fd = inet_connect(host_port, false, &in_progress, errp);
s->fd = inet_nonblocking_connect(host_port, tcp_wait_for_connect, s,
errp);
if (error_is_set(errp)) {
migrate_fd_error(s);
return -1;
}
if (in_progress) {
DPRINTF("connect in progress\n");
qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s);
} else {
migrate_fd_connect(s);
}
return 0;
}

View File

@@ -240,7 +240,9 @@ static int migrate_fd_cleanup(MigrationState *s)
{
int ret = 0;
qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
if (s->fd != -1) {
qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
}
if (s->file) {
DPRINTF("closing file\n");

View File

@@ -455,6 +455,7 @@ static const char *monitor_event_names[] = {
[QEVENT_SUSPEND_DISK] = "SUSPEND_DISK",
[QEVENT_WAKEUP] = "WAKEUP",
[QEVENT_BALLOON_CHANGE] = "BALLOON_CHANGE",
[QEVENT_SPICE_MIGRATE_COMPLETED] = "SPICE_MIGRATE_COMPLETED",
};
QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX)

View File

@@ -43,6 +43,7 @@ typedef enum MonitorEvent {
QEVENT_SUSPEND_DISK,
QEVENT_WAKEUP,
QEVENT_BALLOON_CHANGE,
QEVENT_SPICE_MIGRATE_COMPLETED,
/* Add to 'monitor_event_names' array in monitor.c when
* defining new events here */

25
nbd.c
View File

@@ -162,7 +162,7 @@ int tcp_socket_outgoing(const char *address, uint16_t port)
int tcp_socket_outgoing_spec(const char *address_and_port)
{
return inet_connect(address_and_port, true, NULL, NULL);
return inet_connect(address_and_port, NULL);
}
int tcp_socket_incoming(const char *address, uint16_t port)
@@ -399,24 +399,23 @@ int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize)
return -serrno;
}
if (flags & NBD_FLAG_READ_ONLY) {
int read_only = 1;
TRACE("Setting readonly attribute");
if (ioctl(fd, NBD_SET_FLAGS, flags) < 0) {
if (errno == ENOTTY) {
int read_only = (flags & NBD_FLAG_READ_ONLY) != 0;
TRACE("Setting readonly attribute");
if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) {
if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) {
int serrno = errno;
LOG("Failed setting read-only attribute");
return -serrno;
}
} else {
int serrno = errno;
LOG("Failed setting read-only attribute");
LOG("Failed setting flags");
return -serrno;
}
}
if (ioctl(fd, NBD_SET_FLAGS, flags) < 0
&& errno != ENOTTY) {
int serrno = errno;
LOG("Failed setting flags");
return -serrno;
}
TRACE("Negotiation ended");
return 0;

26
net.c
View File

@@ -357,7 +357,12 @@ void qemu_flush_queued_packets(NetClientState *nc)
{
nc->receive_disabled = 0;
qemu_net_queue_flush(nc->send_queue);
if (qemu_net_queue_flush(nc->send_queue)) {
/* We emptied the queue successfully, signal to the IO thread to repoll
* the file descriptor (for tap, for example).
*/
qemu_notify_event();
}
}
static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
@@ -418,16 +423,27 @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
void *opaque)
{
NetClientState *nc = opaque;
int ret;
if (nc->link_down) {
return iov_size(iov, iovcnt);
}
if (nc->info->receive_iov) {
return nc->info->receive_iov(nc, iov, iovcnt);
} else {
return nc_sendv_compat(nc, iov, iovcnt);
if (nc->receive_disabled) {
return 0;
}
if (nc->info->receive_iov) {
ret = nc->info->receive_iov(nc, iov, iovcnt);
} else {
ret = nc_sendv_compat(nc, iov, iovcnt);
}
if (ret == 0) {
nc->receive_disabled = 1;
}
return ret;
}
ssize_t qemu_sendv_packet_async(NetClientState *sender,

View File

@@ -97,12 +97,12 @@ static int net_hub_port_can_receive(NetClientState *nc)
continue;
}
if (!qemu_can_send_packet(&port->nc)) {
return 0;
if (qemu_can_send_packet(&port->nc)) {
return 1;
}
}
return 1;
return 0;
}
static ssize_t net_hub_port_receive(NetClientState *nc,

View File

@@ -83,12 +83,12 @@ void qemu_del_net_queue(NetQueue *queue)
g_free(queue);
}
static ssize_t qemu_net_queue_append(NetQueue *queue,
NetClientState *sender,
unsigned flags,
const uint8_t *buf,
size_t size,
NetPacketSent *sent_cb)
static void qemu_net_queue_append(NetQueue *queue,
NetClientState *sender,
unsigned flags,
const uint8_t *buf,
size_t size,
NetPacketSent *sent_cb)
{
NetPacket *packet;
@@ -100,16 +100,14 @@ static ssize_t qemu_net_queue_append(NetQueue *queue,
memcpy(packet->data, buf, size);
QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
return size;
}
static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
NetClientState *sender,
unsigned flags,
const struct iovec *iov,
int iovcnt,
NetPacketSent *sent_cb)
static void qemu_net_queue_append_iov(NetQueue *queue,
NetClientState *sender,
unsigned flags,
const struct iovec *iov,
int iovcnt,
NetPacketSent *sent_cb)
{
NetPacket *packet;
size_t max_len = 0;
@@ -133,8 +131,6 @@ static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
}
QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
return packet->size;
}
static ssize_t qemu_net_queue_deliver(NetQueue *queue,
@@ -177,7 +173,8 @@ ssize_t qemu_net_queue_send(NetQueue *queue,
ssize_t ret;
if (queue->delivering || !qemu_can_send_packet(sender)) {
return qemu_net_queue_append(queue, sender, flags, data, size, sent_cb);
qemu_net_queue_append(queue, sender, flags, data, size, sent_cb);
return 0;
}
ret = qemu_net_queue_deliver(queue, sender, flags, data, size);
@@ -201,8 +198,8 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue,
ssize_t ret;
if (queue->delivering || !qemu_can_send_packet(sender)) {
return qemu_net_queue_append_iov(queue, sender, flags,
iov, iovcnt, sent_cb);
qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, sent_cb);
return 0;
}
ret = qemu_net_queue_deliver_iov(queue, sender, flags, iov, iovcnt);
@@ -228,7 +225,7 @@ void qemu_net_queue_purge(NetQueue *queue, NetClientState *from)
}
}
void qemu_net_queue_flush(NetQueue *queue)
bool qemu_net_queue_flush(NetQueue *queue)
{
while (!QTAILQ_EMPTY(&queue->packets)) {
NetPacket *packet;
@@ -244,7 +241,7 @@ void qemu_net_queue_flush(NetQueue *queue)
packet->size);
if (ret == 0) {
QTAILQ_INSERT_HEAD(&queue->packets, packet, entry);
break;
return false;
}
if (packet->sent_cb) {
@@ -253,4 +250,5 @@ void qemu_net_queue_flush(NetQueue *queue)
g_free(packet);
}
return true;
}

View File

@@ -53,6 +53,6 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue,
NetPacketSent *sent_cb);
void qemu_net_queue_purge(NetQueue *queue, NetClientState *from);
void qemu_net_queue_flush(NetQueue *queue);
bool qemu_net_queue_flush(NetQueue *queue);
#endif /* QEMU_NET_QUEUE_H */

View File

@@ -32,6 +32,7 @@
#include "qemu-error.h"
#include "qemu-option.h"
#include "qemu_socket.h"
#include "iov.h"
typedef struct NetSocketState {
NetClientState nc;
@@ -40,29 +41,106 @@ typedef struct NetSocketState {
int state; /* 0 = getting length, 1 = getting data */
unsigned int index;
unsigned int packet_len;
unsigned int send_index; /* number of bytes sent (only SOCK_STREAM) */
uint8_t buf[4096];
struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
IOHandler *send_fn; /* differs between SOCK_STREAM/SOCK_DGRAM */
bool read_poll; /* waiting to receive data? */
bool write_poll; /* waiting to transmit data? */
} NetSocketState;
static void net_socket_accept(void *opaque);
static void net_socket_writable(void *opaque);
/* Only read packets from socket when peer can receive them */
static int net_socket_can_send(void *opaque)
{
NetSocketState *s = opaque;
return qemu_can_send_packet(&s->nc);
}
static void net_socket_update_fd_handler(NetSocketState *s)
{
qemu_set_fd_handler2(s->fd,
s->read_poll ? net_socket_can_send : NULL,
s->read_poll ? s->send_fn : NULL,
s->write_poll ? net_socket_writable : NULL,
s);
}
static void net_socket_read_poll(NetSocketState *s, bool enable)
{
s->read_poll = enable;
net_socket_update_fd_handler(s);
}
static void net_socket_write_poll(NetSocketState *s, bool enable)
{
s->write_poll = enable;
net_socket_update_fd_handler(s);
}
static void net_socket_writable(void *opaque)
{
NetSocketState *s = opaque;
net_socket_write_poll(s, false);
qemu_flush_queued_packets(&s->nc);
}
/* XXX: we consider we can send the whole packet without blocking */
static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, size_t size)
{
NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
uint32_t len;
len = htonl(size);
uint32_t len = htonl(size);
struct iovec iov[] = {
{
.iov_base = &len,
.iov_len = sizeof(len),
}, {
.iov_base = (void *)buf,
.iov_len = size,
},
};
size_t remaining;
ssize_t ret;
send_all(s->fd, (const uint8_t *)&len, sizeof(len));
return send_all(s->fd, buf, size);
remaining = iov_size(iov, 2) - s->send_index;
ret = iov_send(s->fd, iov, 2, s->send_index, remaining);
if (ret == -1 && errno == EAGAIN) {
ret = 0; /* handled further down */
}
if (ret == -1) {
s->send_index = 0;
return -errno;
}
if (ret < (ssize_t)remaining) {
s->send_index += ret;
net_socket_write_poll(s, true);
return 0;
}
s->send_index = 0;
return size;
}
static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf, size_t size)
{
NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
ssize_t ret;
return sendto(s->fd, (const void *)buf, size, 0,
(struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
do {
ret = qemu_sendto(s->fd, buf, size, 0,
(struct sockaddr *)&s->dgram_dst,
sizeof(s->dgram_dst));
} while (ret == -1 && errno == EINTR);
if (ret == -1 && errno == EAGAIN) {
net_socket_write_poll(s, true);
return 0;
}
return ret;
}
static void net_socket_send(void *opaque)
@@ -81,7 +159,8 @@ static void net_socket_send(void *opaque)
} else if (size == 0) {
/* end of connection */
eoc:
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
net_socket_read_poll(s, false);
net_socket_write_poll(s, false);
if (s->listen_fd != -1) {
qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
}
@@ -152,7 +231,8 @@ static void net_socket_send_dgram(void *opaque)
return;
if (size == 0) {
/* end of connection */
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
net_socket_read_poll(s, false);
net_socket_write_poll(s, false);
return;
}
qemu_send_packet(&s->nc, s->buf, size);
@@ -243,7 +323,8 @@ static void net_socket_cleanup(NetClientState *nc)
{
NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
if (s->fd != -1) {
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
net_socket_read_poll(s, false);
net_socket_write_poll(s, false);
close(s->fd);
s->fd = -1;
}
@@ -314,8 +395,8 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
s->fd = fd;
s->listen_fd = -1;
qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
s->send_fn = net_socket_send_dgram;
net_socket_read_poll(s, true);
/* mcast: save bound address as dst */
if (is_connected) {
@@ -332,7 +413,8 @@ err:
static void net_socket_connect(void *opaque)
{
NetSocketState *s = opaque;
qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
s->send_fn = net_socket_send;
net_socket_read_poll(s, true);
}
static NetClientInfo net_socket_info = {

View File

@@ -360,3 +360,8 @@ int qemu_create_pidfile(const char *filename)
/* keep pidfile open & locked forever */
return 0;
}
bool is_daemonized(void)
{
return daemonize;
}

View File

@@ -74,6 +74,30 @@ void qemu_vfree(void *ptr)
VirtualFree(ptr, 0, MEM_RELEASE);
}
/* FIXME: add proper locking */
struct tm *gmtime_r(const time_t *timep, struct tm *result)
{
struct tm *p = gmtime(timep);
memset(result, 0, sizeof(*result));
if (p) {
*result = *p;
p = result;
}
return p;
}
/* FIXME: add proper locking */
struct tm *localtime_r(const time_t *timep, struct tm *result)
{
struct tm *p = localtime(timep);
memset(result, 0, sizeof(*result));
if (p) {
*result = *p;
p = result;
}
return p;
}
void socket_set_block(int fd)
{
unsigned long opt = 0;

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