Compare commits

...
91 Commits
Author SHA1 Message Date
Anthony Liguori 6173d56bdc Merge remote branch 'qemu-kvm/uq/stable-0.12' into stable-0.12 2010-02-23 14:08:31 -06:00
Anthony Liguori f39942d217 Update version and change for 0.12.3 release
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-02-23 14:08:23 -06:00
Kevin Wolf 5dde87088f qcow2: Fix access after end of array
If a write requests crosses a L2 table boundary and all clusters until the
end of the L2 table are usable for the request, we must not look at the next
L2 entry because we already have arrived at the end of the array.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 4805bb6696)
2010-02-23 14:07:58 -06:00
Marcelo Tosatti 3fa017e24b ide save/restore pio/atapi cmd transfer fields and io buffer
Save/restore information necessary to continue in progress PIO/ATAPI CMD
transfers.

This includes the IO buffer.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit ed487bb1d6)
2010-02-23 14:07:58 -06:00
Markus Armbruster 35924dbe8c net: Monitor command set_link finds only VLAN clients, fix
Clients not associated with a VLAN exist since commit d80b9fc6.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2583ba97ef)
2010-02-23 14:07:58 -06:00
Markus Armbruster 88aa905668 net: info network shows only VLAN clients, fix
Clients not associated with a VLAN exist since commit d80b9fc6.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit a0104e0ec7)
2010-02-23 14:07:58 -06:00
Markus Armbruster b93c5c84c8 net: net_check_clients() checks only VLAN clients, fix
Clients not associated with a VLAN exist since commit d80b9fc6.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit efe32fdde1)
2010-02-23 14:07:58 -06:00
Markus Armbruster f203baee5b net: Fix bogus "Warning: vlan 0 with no nics" with -device
net_check_clients() prints this when an VLAN has host devices, but no
guest devices.  It uses VLANState members nb_guest_devs and
nb_host_devs to keep track of these devices.  However, -device does
not update nb_guest_devs, only net_init_nic() does that, for -net nic.

Check the VLAN clients directly, and remove the counters.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 62112d181c)
2010-02-23 14:07:58 -06:00
Markus Armbruster 5e3be62385 net: net_check_clients() runs too early to see -device, fix
Call it right after -device devices get created.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 668680f75f)
2010-02-23 14:07:58 -06:00
Markus Armbruster b391493bc6 net: Remove unused net_client_uninit()
Unused since commit 9ad4531e.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 7f76abe1c9)
2010-02-23 14:07:58 -06:00
Jim Meyering 57f9f4c9f5 don't dereference NULL after failed strdup
Most of these are obvious NULL-deref bug fixes, for example,
the ones in these files:

  block/curl.c
  net.c
  slirp/misc.c

and the first one in block/vvfat.c.
The others in block/vvfat.c may not lead to an immediate segfault, but I
traced the two schedule_rename(..., strdup(path)) uses, and a failed
strdup would appear to trigger this assertion in handle_renames_and_mkdirs:

	    assert(commit->path);

The conversion to use qemu_strdup in envlist_to_environ is not technically
needed, but does avoid a theoretical leak in the caller when strdup fails
for one value, but later succeeds in allocating another buffer(plausible,
if one string length is much larger than the others).  The caller does
not know the length of the returned list, and as such can only free
pointers until it hits the first NULL.  If there are non-NULL pointers
beyond the first, their buffers would be leaked.  This one is admittedly
far-fetched.

The two in linux-user/main.c are worth fixing to ensure that an
OOM error is diagnosed up front, rather than letting it provoke some
harder-to-diagnose secondary error, in case of exec failure, or worse, in
case the exec succeeds but with an invalid list of command line options.
However, considering how unlikely it is to encounter a failed strdup early
in main, this isn't a big deal.  Note that adding the required uses of
qemu_strdup here and in envlist.c induce link failures because qemu_strdup
is not currently in any library they're linked with.  So for now, I've
omitted those changes, as well as the fixes in target-i386/helper.c
and target-sparc/helper.c.

If you'd like to see the above discussion (or anything else)
in the commit log, just let me know and I'll be happy to adjust.

>From 9af42864fd1ea666bd25e2cecfdfae74c20aa8c7 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering@redhat.com>
Date: Mon, 8 Feb 2010 18:29:29 +0100
Subject: [PATCH] don't dereference NULL after failed strdup

Handle failing strdup by replacing each use with qemu_strdup,
so as not to dereference NULL or trigger a failing assertion.
* block/curl.c (curl_open): s/\bstrdup\b/qemu_strdup/
* block/vvfat.c (init_directories): Likewise.
(get_cluster_count_for_direntry, check_directory_consistency): Likewise.
* net.c (parse_host_src_port): Likewise.
* slirp/misc.c (fork_exec): Likewise.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 6265eb26a3)
2010-02-23 14:07:58 -06:00
Tom Lendacky 7ebc79037c virtio-net: fix network stall under load
Fix a race condition where qemu finds that there are not enough virtio
ring buffers available and the guest make more buffers available before
qemu can enable notifications.

Signed-off-by: Tom Lendacky <toml@us.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 06b1297017)
2010-02-23 14:07:58 -06:00
Roy Tam ea299062eb json: fix PRId64 on Win32
OK we are fooled by the json lexer and parser. As we use %I64d to
print 'long long' variables in Win32, but lexer and parser only deal
with %lld but not %I64d, this patch add support for %I64d and solve
'info pci', 'powser_reset' and 'power_powerdown' assert failure in
Win32.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2c0d4b36e7)
2010-02-23 14:07:58 -06:00
Marcelo Tosatti e03dd1a6c2 fix inet_parse typo
qemu_opt_set wants on/off, not yes/no.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2198a62eb2)
2010-02-23 14:07:58 -06:00
Marcelo Tosatti 535d2eb34a iothread: fix vcpu stop with smp tcg
Round robin vcpus in tcg_cpu_next even if the vm stopped. This
allows all cpus to enter stopped state.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit c37cc7b072)
2010-02-23 14:07:57 -06:00
David S. Ahern beb8eab90c segfault due to buffer overrun in usb-serial
This fixes a segfault due to buffer overrun in the usb-serial device.
The memcpy was incrementing the start location by recv_used yet, the
computation of first_size (how much to write at the end of the buffer
before wrapping to the front) was not accounting for it. This causes the
next element after the receive buffer (recv_ptr) to get overwritten with
random data.

Signed-off-by: David Ahern <daahern@cisco.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 4ab4183d76)
2010-02-23 14:07:57 -06:00
Kevin Wolf 8d67694fbf qcow2: Fix signedness bugs
Checking for return codes < 0 isn't really going to work with unsigned
types. Use signed types instead.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f4f0d391b2)
2010-02-23 14:07:57 -06:00
Evgeniy Dushistov 02510b2436 Do not ignore error, if open file failed (-serial /dev/tty)
In case, when qemu is executed with option like
-serial /dev/ttyS0, report if there are problems with
opening of devices. At now errors are silently ignoring.

Signed-off-by: Evgeniy Dushistov <dushistov@mail.ru>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit afc535acb5)
2010-02-23 14:07:57 -06:00
Anthony Liguori b57a2297f2 pc-bios: update to newer version of (stable) seabios
- 9fb3f4d Fix PkgLength calculation for the SSDT.
 - 6d75be2 Go back to using 0xf0000000 for PCI memory start.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-02-23 14:07:57 -06:00
Jan Kiszka 43fab08210 kvm: Fix eflags corruption in kvm mode
This should explain a lot of the weird breakages of upstream KVM we've
seen recently (actually we should have seen it much earlier):

Stop translating eflags into TCG format when in kvm mode as we never
translate it back and rather sync this broken state into the kernel.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2010-02-23 14:07:57 -06:00
Aurelien Jarno 915080e6b1 target-mips: fix ROTR and DROTR by zero
Backported from HEAD (cc3f20fee2c9bea3793bf873c531ae6baf68df3a)

Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2010-02-23 18:31:00 +01:00
Nathan Froyd 9f59ddcc4f target-mips: fix CpU exception for coprocessor 0
When we signal a CpU exception for coprocessor 0, we should indicate
that it's for coprocessor 0 instead of coprocessor 1.

Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 13f160cebd0778113ba8d251aea297286b1666cb)
2010-02-23 18:27:54 +01:00
Jan Kiszka 999ceb2c1d kvm: Fix eflags corruption in kvm mode
This should explain a lot of the weird breakages of upstream KVM we've
seen recently (actually we should have seen it much earlier):

Stop translating eflags into TCG format when in kvm mode as we never
translate it back and rather sync this broken state into the kernel.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2010-02-21 11:13:19 +02:00
Aurelien Jarno 307331a42a tcg/mips: fix crash in tcg_out_qemu_ld()
The address register is overriden when it corresponds to v0 and the fast
path is taken, which leads to a crash. Fix that by using the a0 register
instead.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit cca1af8c4d)
2010-02-09 23:29:44 +01:00
Aurelien Jarno 6728dd464b target-mips: don't call cpu_loop_exit() from helper.c
In helper.c AREG0 may not correspond do env, so it's not possible to
call cpu_loop_exit() here. Call it from op_helper.c instead.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit c36bbb28ad)
2010-02-06 17:25:15 +01:00
Kevin Wolf bb45bcc8de virtio-blk: Fix error cases which ignored rerror/werror
If an I/O request fails right away instead of getting an error only in the
callback, we still need to consider rerror/werror.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 6c510fbf60)
2010-01-29 10:21:29 -06:00
Kevin Wolf 096109c804 virtio-blk: Fix restart after read error
Current code assumes that only write requests are ever going to be restarted.
This is wrong since rerror=stop exists. Instead of directly starting writes,
use the same request processing as used for new requests.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f1b5286803)
2010-01-29 10:21:20 -06:00
Kevin Wolf 7ae1fcc88c virtio_blk: Factor virtio_blk_handle_request out
We need a function that handles a single request. Create one by splitting out
code from virtio_blk_handle_output.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit bc6694d43a)
2010-01-29 10:21:11 -06:00
Jan Kiszka 299e0bc52a cirrus: Properly re-register cirrus_linear_io_addr on vram unmap
This fixes CONFIG_FB_CIRRUS for Linux guests and probably much more:

When switching away from linearly mapped vram, we also have to restore
the I/O handlers for the LFB.

This regression was once introduced by commit 2bec46dc97.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 4516e45f82)
2010-01-29 10:21:00 -06:00
Kevin Wolf 74f0529e24 qcow2: Don't ignore qcow2_alloc_clusters return value
Now that qcow2_alloc_clusters can return error codes, we must handle them in
the callers of qcow2_alloc_clusters.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 5d757b563d)
2010-01-27 07:52:50 -06:00
Kevin Wolf 614971158c qcow2: Don't ignore update_refcount return value
update_refcount can return errors that need to be handled by the callers.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit db3a964fb6)
2010-01-27 07:52:40 -06:00
Kevin Wolf afa328b1b2 qcow2: Allow updating no refcounts
There's absolutely no problem with updating the refcounts of 0 clusters.
At least snapshot code is doing this and would fail once the result of
update_refcount isn't ignored any more.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 7322afe7ea)
2010-01-27 07:52:32 -06:00
Kevin Wolf 868dab5dc2 qcow2: Improve error handling in update_refcount
If update_refcount fails, try to undo any changes made so far to avoid
inconsistencies in the image file.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 09508d13f3)
2010-01-27 07:52:22 -06:00
Kevin Wolf 29bb3bf350 qcow2: Fix error handling in grow_refcount_table
Return the appropriate error code instead of -EIO.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f2b7c8b370)
2010-01-27 07:52:12 -06:00
Kevin Wolf dbf45b44b7 block: Return original error codes in bdrv_pread/write
Don't assume -EIO but return the real error.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 9a8c4cceaf)
2010-01-27 07:51:46 -06:00
Kevin Wolf d0d888bc6d qcow2: Return 0/-errno in qcow2_alloc_cluster_offset
Returning 0/-errno allows it to distingush different errors classes. The
cluster offset of newly allocated clusters is now returned in the QCowL2Meta
struct.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 148da7ea9d)
2010-01-27 07:51:35 -06:00
Kevin Wolf 19abbad0da qcow2: Return 0/-errno in get_cluster_table
Switching to 0/-errno allows it to distinguish different error cases.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 1e3e8f1a43)
2010-01-27 07:51:23 -06:00
Kevin Wolf f48aba6de7 qcow2: Fix error handling in qcow_save_vmstate
Don't assume success but pass the bdrv_pwrite return value on.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 1d36e3aae3)
2010-01-27 07:51:10 -06:00
Kevin Wolf cb2ae96bf6 qcow2: Fix error handling in qcow2_grow_l1_table
Return the appropriate error value instead of always using EIO. Don't free the
L1 table on errors, we still need it.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit fb8fa77ce1)
2010-01-27 07:51:02 -06:00
Herve Poussineau 848f874ca1 win32/sdl: Fix toggle full screen
Toggle full screen on Win32/SDL 1.2.13 was broken by commit
c18a2c360e. Re-add the call to
do_sdl_resize() which was removed in this revision

Signed-off-by: Herve Poussineau <hpoussin@reactos.org>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit a35aed57bf)
2010-01-26 18:09:32 -06:00
Herve Poussineau a1a86bf902 win32: pair qemu_memalign() with qemu_vfree()
Win32 suffers from a very big memory leak when dealing with SCSI devices.
Each read/write request allocates memory with qemu_memalign (ie
VirtualAlloc) but frees it with qemu_free (ie free).
Pair all qemu_memalign() calls with qemu_vfree() to prevent such leaks.

Signed-off-by: Herve Poussineau <hpoussin@reactos.org>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f8a83245d9)
2010-01-26 18:09:22 -06:00
Stefano Stabellini c727a05459 vnc_refresh: calling vnc_update_client might free vs
Hi all,
this patch fixes another bug in vnc_refresh: calling vnc_update_client
might cause vs to be free()ed, in this case we cannot access vs->next
right after to examine the next item on the list.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 6185c5783c)
2010-01-26 18:09:08 -06:00
Jan Kiszka eb05143e24 Musicpal: Fix descriptor walk in eth_send
Commit 930c86820e introduced a regression to eth_send: eth_tx_desc_put
manipulates the host's tx descriptor copy before writing it back, but
two lines down the descriptor is evaluated again, leaving us with an
invalid next address if host and guest endianness differ. So this was
the actual issue commit 2e87c5b937 tried to paper over.

Signed-off-by: Jan Kiszka <jan.kiszka@web.de>
Signed-off-by: malc <av1474@comtv.ru>
(cherry picked from commit 07b064e9de)

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-01-26 16:20:20 -06:00
Jan Kiszka 0c709e6195 Musicpal: Fix wm8750 I2C address
Commit b3a219883e uncovered that we attached the Wolfson with an I2C
address shifted left by one. Fixing this makes sound work again for
the Musicpal.

Signed-off-by: Jan Kiszka <jan.kiszka@web.de>
Signed-off-by: malc <av1474@comtv.ru>
(cherry picked from commit 6425822964)

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-01-26 16:20:12 -06:00
Marcelo Tosatti dc88aa49b4 fix savevm command without id or tag
savevm without id or tag segfaults in:

(gdb) bt
#0  0x00007f600a83bf8a in __strcmp_sse42 () from /lib64/libc.so.6
#1  0x00000000004745b6 in bdrv_snapshot_find (bs=<value optimized out>,
    sn_info=0x7fff996be280, name=0x0) at savevm.c:1631
#2  0x0000000000475c80 in del_existing_snapshots (name=<value optimized out>,
    mon=<value optimized out>) at savevm.c:1654
#3  do_savevm (name=<value optimized out>, mon=<value optimized out>)

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f139a41256)
2010-01-26 15:59:11 -06:00
Gleb Natapov dc2ffbf6d8 reduce number of reinjects on ACK
Windows 7 BSODs under load with HAL_RTC_IRQF_WILL_NOT_CLEAR error.

It happens here:
hal!HalpRtcUnmaskClock:
8281b93a 8bff            mov     edi,edi
8281b93c 56              push    esi
8281b93d 33f6            xor     esi,esi
8281b93f 6a0c            push    0Ch
8281b941 e8b2ffffff      call    hal!CMOS_READ (8281b8f8)
8281b946 84c0            test    al,al
8281b948 7920            jns     hal!HalpRtcUnmaskClock+0x30 (8281b96a)
8281b94a 6a0a            push    0Ah
8281b94c 46              inc     esi
8281b94d e854c8ffff      call    hal!KeStallExecutionProcessor (828181a6)
8281b952 83fe64          cmp     esi,64h
8281b955 72e8            jb      hal!HalpRtcUnmaskClock+0x5 (8281b93f)
8281b957 6a00            push    0
8281b959 6a00            push    0
8281b95b 6a00            push    0
8281b95d 680a010000      push    10Ah
8281b962 6a5c            push    5Ch
8281b964 ff1500c38082    call    dword ptr [hal!_imp__KeBugCheckEx (8280c300)]
8281b96a 5e              pop     esi
8281b96b c3              ret

So it loops for 100(64h) times reading register C before BSOD. Lets
reduce number of immediate reinjection well under this limit.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit dd17765b5f)
2010-01-20 08:54:22 -06:00
Luiz Capitulino d3bf9367f2 QMP: Fix asynchronous events delivery
Commit f039a563f2 introduces
a regression as monitor_protocol_event() will return in
the first user Monitor it finds in the QLIST_FOREACH()
loop.

The right thing to do is to only delivery an asynchronous
event if the 'mon' is a QMP Monitor.

The aforementioned commit was an early version, if it was
applied to stable (it should) this one has to be applied
there too.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 23fabed136)
2010-01-20 08:53:24 -06:00
Stefan Weil c502715a74 Documentation: Add missing documentation for qdev related command line options
The command line options -device, -nodefaults, -readconfig,
-writeconfig had entries for command line help, but
documentation for texi and derived formats (man, html, info)
was missing.

This also required moving "@end table" to the end of
qemu-options.hx again.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 3dbf2c7fc5)
2010-01-20 08:53:02 -06:00
Gerd Hoffmann b9a61d2154 pc: add driver version compat properties
This patch adds compat property entries for ide-disk.ver and
scsi-disk.ver to pc-0.10 and pc-0.11.  With this patch applied
the scsi and ide disks report "0.10" and "0.11" as version when
you start qemu with "-M pc-0.10" or "-M pc-0.11".

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 374ef70452)
2010-01-19 16:42:45 -06:00
Gerd Hoffmann 9525204c5d scsi: device version property
This patch adds a new property named 'ver' to scsi-disk which allows to
specify the version which the virtual disk/cdrom should report to the
guest.  By default this is the qemu version (i.e. 0.12).  usage:

  -drive if=none,id=disk,file=...
  -device lsi
  -device scsi-disk,drive=disk,bus=scsi.0,unit=0,ver=42

You can also switch the version for all scsi drives using:

  -global scsi-disk.ver=42

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 383b4d9b79)
2010-01-19 16:42:37 -06:00
Gerd Hoffmann f79d556b4f ide: device version property
This patch adds a new property named 'ver' to ide-drive which allows to
specify the version which the virtual disk/cdrom should report to the
guest.  By default this is the qemu version (i.e. 0.12).  usage:

  -drive if=none,id=disk,file=...
  -device ide-drive,bus=ide.0,unit=0,drive=disk,ver=42

You can also switch the version for all ide drives using:

  -global ide-drive.ver=42

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 47c0634030)
2010-01-19 16:42:25 -06:00
Adam Litke 41ae9ece21 QMP: Emit asynchronous events on all QMP monitors
When using a control/QMP monitor in tandem with a regular monitor, asynchronous
messages can get lost depending on the order of the QEMU program arguments.
QEMU events issued by monitor_protocol_event() always go to cur_mon.  If the
user monitor was specified on the command line first (or it has ,default), the
message will be directed to the user monitor (not the QMP monitor).
Additionally, only one QMP session is currently able to receive async messages.

To avoid this confusion, scan through the list of monitors and emit the message
on each QMP monitor.

Signed-off-by: Adam Litke <agl@us.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f039a563f2)
2010-01-19 16:42:15 -06:00
Kevin Wolf 40480d2bf4 Fix QEMU_WARN_UNUSED_RESULT
Since commit 747bbdf7 QEMU_WARN_UNUSED_RESULT is never defined as it is
conditional on a define from config-host.h which is included only later.
Include that file earlier to get the warnings back.

Reactivating it unfortunately leads to some warnings about unused qdev_init
results. These calls are changed to qdev_init_nofail to avoid build failures.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit beb6f0de7a)
2010-01-19 16:42:03 -06:00
Anthony Liguori e389e937a7 Update version and changelog for release
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-01-14 08:40:19 -06:00
Anthony Liguori 73b48d914f Update SeaBIOS to 0.5.1
- 5da6833 Update version to 0.5.1
 - 669c991 Fix sign error preventing incorrect memory over 4gig calculation.
 - 7e6bd3e Minor - better indent assembler in int1587.
 - 48cf232 Add comment explaining why mptable is in low memory.
 - 643062f Add int1589 support.
 - 085debd Set FDPT in irq table even for small drives.
 - 7c1b186 Reduce #ifs by weeding out some cross-chunk function definitions.
 - f9b25d3 Fix vgahook sign issue; add warning to build to catch future cases.
 - 3862b2d vgabios: Fix compile error due to fixed prototypes.
 - 1ca05b0 Be sure to add "void" to all function prototypes that take no args.
 - b5bb9db mptable: Reset pinmask on new bus or device.
 - 8918989 Detect latest FC12 gcc -combine breakage.
 - c9d3c2d Minor vga binary cleanups.
 - 9a8609f Make MTRR region 0xc0000-0x100000 be cached.
 - fdca418 Force a link error if a function is used from the wrong code chunk.
 - dad41d9 Add __noreturn define for __attribute__((noreturn)).
 - c003148 Implement native 32bit APM support.
 - 5c99b6c Commit compiled dsdt file; misc comment updates.
 - 29f4b91 prevent acpi from rerouting SCI interrupt
 - 4c94b7e enumerate all PCI buses in mptable
 - 871e0a0 Add support for 32bit PCI BIOS entry.
 - eda2c83 Only add "addr32" to memory accesses that require them.
 - 52a300f Introduce MODESEGMENT define; rename VISIBLE32 to VISIBLE32FLAT.
 - fe2c3ee Allocate smbios in temp space and copy into final location.
 - b164d2c Clear user reserved interrupts (0x60-0x66).
 - d9104ff Remove pci_bios_bigmem_addr; set pci_bios_mem_addr=0xe0000000
 - 14021f2 Add initial support for ATA DMA.
 - 8362699 Allocate mptable in temp space and copy into final location.
 - 979862e Also report memory over 4G during init.
 - 928d4df provide correct pci routing information in mptable
 - afc02da Add symbolic definitions for MTRR code.
 - fb214dc Fix yield() so it works from boot code.
 - 2ceeec9 Fix potential build failure due to text16 section being too large.
 - a2195e4 Increase version in preparation for next release.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-01-14 08:40:11 -06:00
Milan Plzik 3999bf3244 Qemu's internal TFTP server breaks lock-step-iness of TFTP
According to RFC 1350 and RFC 2347, TFTP server should answer RRQ by
either OACK or DATA packet. Qemu's internal TFTP server answers RRQ with
additional options by sending both OACK and DATA packet, thus breaking
the "lock-step" feature of the protocol, and also confuses client.

  Proposed solution would be to, in case of OACK packet, wait for ACK
from client and just then start sending data. Attached patch implements
this.

Signed-off-by: Thomas Horsten <thomas@horsten.com>
Signed-off-by: Milan Plzik <milan.plzik@gmail.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 1cb1a66aed)
2010-01-13 17:22:57 -06:00
Kevin Wolf a3441a43a6 osdep.c: Fix accept4 fallback
Commit 3a03bfa5 added a fallback in case the Linux kernel running qemu is older
than the kernel of the build system. Unfortunately, v1 was committed instead of
v2, so the code has a bug that was revealed in the review (checking for the
wrong error code).

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 347ed55cd1)
2010-01-13 17:22:33 -06:00
Gerd Hoffmann 49a3aaac4a pc: add rombar to compat properties for pc-0.10 and pc-0.11
So '-M pc-0.10' and '-M pc-0.11' will use the fw_cfg rom load method
by default.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 20a86364c9)
2010-01-12 14:48:35 -06:00
Gerd Hoffmann 027866ce23 pci: allow loading roms via fw_cfg.
This patch adds a pci bus property 'rombar' which specifies whenever
the pci rom should be loaded via pci rom bar (default) or via fw_cfg.
The later can be used for compatibility with older qemu versions where
no pci rom bar is present.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 88169ddf82)
2010-01-12 14:48:27 -06:00
Gerd Hoffmann 04babf6c6f roms: rework rom loading via fw
This patch changes the way rom loading via fw_cfg is handled.
Instead of having pc_init1() call a function which passed all
roms to the firmware config we simply pass a pointer to fw_cfg
to the rom loader.

Advantage: loading roms via firmware works also for devices which
are initialized after pc_init1(), i.e. everyting added via -device.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 8832cb805d)
2010-01-12 14:48:19 -06:00
Gerd Hoffmann d2b8117310 fw_cfg: rom loader tweaks.
Changes:
 - make dir argument mandatory, we allways have one anyway
   (vgaroms or genroms).
 - check for duplicates, skip loading if found.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit de9352bcae)
2010-01-12 14:48:07 -06:00
Gerd Hoffmann 0c4b9aef7b roms: minor fixes and cleanups.
Changes:
  - Drop extra file argument from rom_add_file().
  - Drop fw_dir check in do_info_roms, we allways have a dir name.
  - code style fixes.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit bdb5ee3064)
2010-01-12 14:48:00 -06:00
Gerd Hoffmann 431c829f33 pc: add machine type for 0.12
Add a new machine type for qemu 0.12.

Also fixup the 0.11 machine type: msi for virtio-blk-pci was enabled
after the 0.11 release, so turn it off in the 0.11 machine type.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2cae6f5e34)
2010-01-12 14:47:53 -06:00
Aurelien Jarno be7398ec06 loader: more ignores for rom intended to be loaded by the bios
Similarly to what has been done in e405a2ba91,
ignore rom intended to be loaded by the bios in find_rom() and rom_copy().

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit f21a59c224)
2010-01-12 14:44:50 -06:00
Stefano Stabellini be59ce1f48 vnc_refresh: return if vd->timer is NULL
Hi all,
calling vnc_update_client in vnc_refresh might have the unlikely side
effect of setting vd->timer = NULL, if the last vnc client disconnected.
In this case we have to return from vnc_refresh without updating the
timer, otherwise we cause a segfault.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 83755c173f)
2010-01-12 13:34:48 -06:00
Luiz Capitulino eacad66dbe QMP: Don't free async event's 'data'
The monitor_protocol_event() function will free the
event's data, this is wrong as 'data' management is up
to the caller.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 3d72f9a2be)
2010-01-12 13:33:13 -06:00
Thomas Horsten 66dbb62824 Handle TFTP ERROR from client
If a PXE client only wants to find out the size of a file, it will
open the file and then abort the transfer by sending a TFTP ERROR packet.

The ERROR packet should cause qemu to terminate the session. If not,
the sessions will soon run out and cause timeouts in the client.

Also, if a TFTP session already exists with same IP/UDP port, it
should be terminated when a new RRQ is received, instead of creating a
duplicate (which will never be used).

A patch for gPXE to send the ERROR packet is also being submitted to
gPXE. Together they resolve slowness/hanging when booting pxegrub from
qemu's internal TFTP server. The patch from Milan Plzik to return
after sending OACK is also required for a complete fix.

Signed-off-by: Thomas Horsten <thomas@horsten.com>
Signed-off-by: Milan Plzik <milan.plzik@gmail.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit bfe4e17242)
2010-01-12 13:31:51 -06:00
Christoph Hellwig d47d251286 dmg: fix ->open failure
Currently the dmg image format driver simply opens the images as raw
if any kind of failure happens.  This is contrarty to the behaviour
of all other image formats which just return an error and let the
block core deal with it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 1559ca00bc)
2010-01-12 13:31:21 -06:00
Michael S. Tsirkin 348af56fae virtio-pci: thinko fix
Since patch ed757e140c0ada220f213036e4497315d24ca8bct, virtio will
sometimes clear all status registers on bus master disable, which loses
information such as VIRTIO_CONFIG_S_FAILED bit.  This is a result of
a patch being misapplied: code uses !  instead of ~ for bit
operations as in Yan's original patch.  This obviously does not make
sense.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 49e75cf388)
2010-01-12 13:30:08 -06:00
Stefan Weil 09866b9baa pc-bios: Update README (SeaBIOS)
The PC BIOS no longer comes from Bochs.
This patch updates the related entry.

V2 - Modify SeaBIOS description and URL
     (Thanks to Gleb Natapov for the hint).

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit c0ced0f3a7)
2010-01-12 13:29:48 -06:00
Roland Dreier e1daf40e3e vmware_vga: Check cursor dimensions passed from guest to avoid buffer overflow
Check that the cursor dimensions passed from the guest for the
DEFINE_CURSOR command don't overflow the available space in the
cursor.image[] or cursor.mask[] arrays before copying data from the
guest into those arrays.

Signed-off-by: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f2d928d44e)
2010-01-11 10:03:39 -06:00
Gleb Natapov de3ea06d59 remove pending exception on vcpu reset.
Without this qemu can even start on kvm modules with events support
since default value of exception_injected in zero and this is #DE
exception.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit e73223a584)
2010-01-11 10:03:30 -06:00
Jiri Denemark fe46a160ce Fix CPU topology initialization
Late initialization of CPU topology in CPUState prevents KVM guests to
actually see the topology.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 3f7638ec40)
2010-01-11 10:03:18 -06:00
Huang Ying 8033c42abd MCE: Fix bug of IA32_MCG_STATUS after system reset
Now, if we inject a fatal MCE into guest OS, for example Linux, Linux
will go panic and then reboot. But if we inject another MCE now,
system will reset directly instead of go panic firstly, because
MCG_STATUS.MCIP is set to 1 and not cleared after reboot. This is does
not follow the behavior in real hardware.

This patch fixes this via set env->mcg_status to 0 during system reset.

Signed-off-by: Huang Ying <ying.huang@intel.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit af364b418c)
2010-01-11 10:02:55 -06:00
Avi Kivity 4713c69fa2 linuxboot: fix gdt address calculation
The gdt address calculation in linuxboot.bin is broken in two ways: first
it loads %cs into %eax, but that instruction leaves the high bits of %eax
undefined and we did not clear them.  Secondly, we completely ignore the
incorrect %eax, and use the undefined %ebx instead.

With these issues fixed, linuxboot works again.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d0652aa8ac)
2010-01-08 10:01:39 -06:00
Luiz Capitulino d68bf60838 QMP: Drop wrong assert()
Some commands return a QList of QDicts, which is valid,
but will trig the assert().

Just drop it.

Reported-by: Nathan Baum <nathan@parenthephobia.org.uk>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 810f49b56a)
2010-01-08 10:01:26 -06:00
Anthony Liguori 57fa5ca551 vnc: Fix artifacts in hextile decoding
02c2b87 introduced a regression whereas the foreground color in a hextile
update was not being properly invalidated leading to artifacts.

It's still necessary to explicitly invalidate the foreground color with a
SubrectColoured tile even though we no longer send a foreground color as
part of the tile.

Reported-by: Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 18cb1d8557)
2010-01-07 07:59:28 -06:00
Anthony Liguori 8610774f79 Merge remote branch 'mst/stable-0.12' into stable-0.12 2010-01-06 09:17:53 -06:00
Aurelien Jarno 76ba04832b target-i386: Fix "call im" on x86_64 when executing 32-bit code
Similarly to what is done in 32938e127f
for "jmp im", trunc the immediate to 32-bit when not running in 64-bit
mode.

Reported-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2010-01-03 03:16:59 +01:00
Michael Tokarev 644f5de21b Add missing newline at the end of options list
In qemu-kvm this place looks even more "interesting":

 -runas user     Change to user id user just before starting the VM.
 -readconfig <file>
 -writeconfig <file>
                read/write config file-no-kvm         disable KVM hardware virtualization
 -no-kvm-irqchip disable KVM kernel mode PIC/IOAPIC/LAPIC
 -no-kvm-pit     disable KVM kernel mode PIT

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 19e65b47f6)
2009-12-30 13:46:40 +01:00
Avi Kivity dcc0da8297 Don't load options roms intended to be loaded by the bios in qemu
The first such option rom will load at address 0, which isn't very nice,
and the second will report a conflict and abort, which is horrible.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit e405a2ba91)
2009-12-24 19:35:24 +01:00
Scott Tsai 41193c50fa USB: Improve usbdevice error messages
When an non-existent USB device is specified on the command line,
print "qemu: could not add USB device 'X'".
Likewise for the usb_{add,del} monitor commands.

Signed-off-by: Scott Tsai <scottt.tw@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 59d1c1c2d7)
2009-12-23 07:42:38 +01:00
Aurelien Jarno da0266005a cpu-all.h: fix cpu_get_real_ticks() #ifdef
Reported-by: Hervé Poussineau <hpoussin@reactos.org>

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 9706c06d9c)
2009-12-20 21:47:03 +01:00
Blue Swirl eacdccbb3e alpha: fix compile
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2009-12-20 10:27:44 +00:00
Kirill A. Shutemov 65e8c51928 user_only: compile everything with -fpie
We really need compile _all_ sources for user target with -fpie when
use --enable-user-pie.

It's regression introduced by commit add16157d7.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
[blauwirbel@gmail.com: combined 299060a0 and 58faa1a6 to avoid breakage]
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2009-12-20 11:35:57 +02:00
Artyom Tarasenko e470436f19 fdc/sparc32: don't hang on detection under OBP
Stepping through the SS-5's OBP initialization routines
it looks like reading fdc main status register should
clear the fd interrupt.
The patch doesn't fix problems with fdc on sparc platform,
it only fixes fdc detection.

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2009-12-20 11:35:48 +02:00
Artyom Tarasenko b60c2c74f3 scsi-disk: Inquiry with allocation length of CDB < 36 (v4)
According to the SCSI-2 specification,
http://ldkelley.com/SCSI2/SCSI2/SCSI2/SCSI2-08.html#8.2.5 ,
"if the allocation length of the command descriptor block (CDB) is too
small to transfer all of the parameters, the additional length shall
not be adjusted to reflect the truncation."
The 36 mandatory bytes of response are written to outbuf, and then
only the length requested in CDB is transferred.

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2009-12-20 11:35:28 +02:00
Anthony Liguori fe1b69708c Update version and changelog for 0.12.1
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-19 19:31:18 -06:00
Kevin Wolf a1678e85db Multiboot support: Fix rom_copy
ROMs need to be loaded if they are anywhere in the requested area, not
only at the very beginning. This fixes Multiboot with ELF kernels that
have more than one program header.

Signed-off-by: Kevin Wolf <mail@kevin-wolf.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 935effc2bb)
2009-12-19 21:51:10 +01:00
Aurelien Jarno 8212d18cf5 roms: allow roms to be loaded at address 0
It was possible to load roms at address 0, but commit
632cf034b4 started to forbid that, which
broke at least ARM versatile.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit f9e69bd9cf)
2009-12-19 19:46:10 +01:00
Michael S. Tsirkin c56651312b e1000: fix init values for command register
Command register for e1000 was initialized to
values out of spec: all of bus master,
io, memory and interrupt disable bits were set.

This breaks the device now that we actually respect
the interrupt disable bit, unless the guest
happens to clear it. Fix, and make the device
more spec compliant, by not touching
the default.

There are implications for migration
from old qemu as well, will be addressed
separately.

Reported-by: Luiz Capitulino <lcapitulino@redhat.com>
Tested-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2009-12-15 13:55:20 +02:00
74 changed files with 849 additions and 345 deletions

No files matched your search

+90
View File
@@ -1,3 +1,93 @@
version 0.12.3
- kvm: Fix eflags corruption in kvm mode (Jan Kiszka)
- qcow2: Fix access after end of array (Kevin Wolf)
- ide save/restore pio/atapi cmd transfer fields and io buffer (Marcelo Tosatti)
- net: Monitor command set_link finds only VLAN clients, fix (Markus Armbruster)
- net: info network shows only VLAN clients, fix (Markus Armbruster)
- net: net_check_clients() checks only VLAN clients, fix (Markus Armbruster)
- net: Fix bogus "Warning: vlan 0 with no nics" with -device (Markus Armbruster)
- net: net_check_clients() runs too early to see -device, fix (Markus Armbruster)
- net: Remove unused net_client_uninit() (Markus Armbruster)
- don't dereference NULL after failed strdup (Jim Meyering)
- virtio-net: fix network stall under load (Tom Lendacky)
- json: fix PRId64 on Win32 (Roy Tam)
- fix inet_parse typo (Marcelo Tosatti)
- iothread: fix vcpu stop with smp tcg (Marcelo Tosatti)
- segfault due to buffer overrun in usb-serial (David S. Ahern)
- qcow2: Fix signedness bugs (Kevin Wolf)
- Do not ignore error, if open file failed (-serial /dev/tty) (Evgeniy Dushistov)
- pc-bios: update to newer version of (stable) seabios (Anthony Liguori)
- target-mips: fix ROTR and DROTR by zero (Aurelien Jarno)
- target-mips: fix CpU exception for coprocessor 0 (Nathan Froyd)
- tcg/mips: fix crash in tcg_out_qemu_ld() (Aurelien Jarno)
- target-mips: don't call cpu_loop_exit() from helper.c (Aurelien Jarno)
- virtio-blk: Fix error cases which ignored rerror/werror (Kevin Wolf)
- virtio-blk: Fix restart after read error (Kevin Wolf)
- virtio_blk: Factor virtio_blk_handle_request out (Kevin Wolf)
- cirrus: Properly re-register cirrus_linear_io_addr on vram unmap (Jan Kiszka)
- qcow2: Don't ignore qcow2_alloc_clusters return value (Kevin Wolf)
- qcow2: Don't ignore update_refcount return value (Kevin Wolf)
- qcow2: Allow updating no refcounts (Kevin Wolf)
- qcow2: Improve error handling in update_refcount (Kevin Wolf)
- qcow2: Fix error handling in grow_refcount_table (Kevin Wolf)
- block: Return original error codes in bdrv_pread/write (Kevin Wolf)
- qcow2: Return 0/-errno in qcow2_alloc_cluster_offset (Kevin Wolf)
- qcow2: Return 0/-errno in get_cluster_table (Kevin Wolf)
- qcow2: Fix error handling in qcow_save_vmstate (Kevin Wolf)
- qcow2: Fix error handling in qcow2_grow_l1_table (Kevin Wolf)
- win32/sdl: Fix toggle full screen (Herve Poussineau)
- win32: pair qemu_memalign() with qemu_vfree() (Herve Poussineau)
- vnc_refresh: calling vnc_update_client might free vs (Stefano Stabellini)
- Musicpal: Fix descriptor walk in eth_send (Jan Kiszka)
- Musicpal: Fix wm8750 I2C address (Jan Kiszka)
- fix savevm command without id or tag (Marcelo Tosatti)
- reduce number of reinjects on ACK (Gleb Natapov)
- QMP: Fix asynchronous events delivery (Luiz Capitulino)
- Documentation: Add missing documentation for qdev related command line options (Stefan Weil)
- pc: add driver version compat properties (Gerd Hoffmann)
- scsi: device version property (Gerd Hoffmann)
- ide: device version property (Gerd Hoffmann)
- QMP: Emit asynchronous events on all QMP monitors (Adam Litke)
- Fix QEMU_WARN_UNUSED_RESULT (Kevin Wolf)
version 0.12.2:
- Qemu's internal TFTP server breaks lock-step-iness of TFTP (Milan Plzik)
- osdep.c: Fix accept4 fallback (Kevin Wolf)
- pc: add rombar to compat properties for pc-0.10 and pc-0.11 (Gerd Hoffmann)
- pci: allow loading roms via fw_cfg. (Gerd Hoffmann)
- roms: rework rom loading via fw (Gerd Hoffmann)
- fw_cfg: rom loader tweaks. (Gerd Hoffmann)
- roms: minor fixes and cleanups. (Gerd Hoffmann)
- pc: add machine type for 0.12 (Gerd Hoffmann)
- loader: more ignores for rom intended to be loaded by the bios (Aurelien Jarno)
- vnc_refresh: return if vd->timer is NULL (Stefano Stabellini)
- QMP: Don't free async event's 'data' (Luiz Capitulino)
- Handle TFTP ERROR from client (Thomas Horsten)
- dmg: fix ->open failure (Christoph Hellwig)
- virtio-pci: thinko fix (Michael S. Tsirkin)
- pc-bios: Update README (SeaBIOS) (Stefan Weil)
- vmware_vga: Check cursor dimensions passed from guest to avoid buffer overflow (Roland Dreier)
- remove pending exception on vcpu reset. (Gleb Natapov)
- Fix CPU topology initialization (Jiri Denemark)
- MCE: Fix bug of IA32_MCG_STATUS after system reset (Huang Ying)
- linuxboot: fix gdt address calculation (Avi Kivity)
- QMP: Drop wrong assert() (Luiz Capitulino)
- vnc: Fix artifacts in hextile decoding (Anthony Liguori)
- target-i386: Fix "call im" on x86_64 when executing 32-bit code (Aurelien Jarno)
- Add missing newline at the end of options list (Michael Tokarev)
- Don't load options roms intended to be loaded by the bios in qemu (Avi Kivity)
- USB: Improve usbdevice error messages (Scott Tsai)
- cpu-all.h: fix cpu_get_real_ticks() #ifdef (Aurelien Jarno)
- alpha: fix compile (Blue Swirl)
- user_only: compile everything with -fpie (Kirill A. Shutemov)
- fdc/sparc32: don't hang on detection under OBP (Artyom Tarasenko)
- scsi-disk: Inquiry with allocation length of CDB < 36 (v4) (Artyom Tarasenko)
- e1000: fix init values for command register (Michael S. Tsirkin)
version 0.12.1:
- loader: fix rom loading at address 0 (fixes target-arm) (Aurelien Jarno)
- loader: fix rom_copy (fixes multiboot) (Kevin Wolf)
version 0.12.0:
- Update to SeaBIOS 0.5.0
+6 -1
View File
@@ -2,10 +2,15 @@
include ../config-host.mak
include $(SRC_PATH)/rules.mak
-include config.mak
.PHONY: all
VPATH=$(SRC_PATH)
# Do not take %.o from $(SRC_PATH), only %.c and %.h
# All %.o for user targets should be built with -fpie, when
# configured with --enable-user-pie, so we don't want to
# take %.o from $(SRC_PATH), since they built without -fpie
vpath %.c %.h $(SRC_PATH)
QEMU_CFLAGS+=-I..
+1 -1
View File
@@ -1 +1 @@
0.12.0
0.12.3
+19 -17
View File
@@ -691,6 +691,7 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset,
uint8_t tmp_buf[BDRV_SECTOR_SIZE];
int len, nb_sectors, count;
int64_t sector_num;
int ret;
count = count1;
/* first read to align to sector start */
@@ -699,8 +700,8 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset,
len = count;
sector_num = offset >> BDRV_SECTOR_BITS;
if (len > 0) {
if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
return -EIO;
if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
return ret;
memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len);
count -= len;
if (count == 0)
@@ -712,8 +713,8 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset,
/* read the sectors "in place" */
nb_sectors = count >> BDRV_SECTOR_BITS;
if (nb_sectors > 0) {
if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
return -EIO;
if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0)
return ret;
sector_num += nb_sectors;
len = nb_sectors << BDRV_SECTOR_BITS;
buf += len;
@@ -722,8 +723,8 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset,
/* add data from the last sector */
if (count > 0) {
if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
return -EIO;
if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
return ret;
memcpy(buf, tmp_buf, count);
}
return count1;
@@ -735,6 +736,7 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
uint8_t tmp_buf[BDRV_SECTOR_SIZE];
int len, nb_sectors, count;
int64_t sector_num;
int ret;
count = count1;
/* first write to align to sector start */
@@ -743,11 +745,11 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
len = count;
sector_num = offset >> BDRV_SECTOR_BITS;
if (len > 0) {
if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
return -EIO;
if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
return ret;
memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
return -EIO;
if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
return ret;
count -= len;
if (count == 0)
return count1;
@@ -758,8 +760,8 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
/* write the sectors "in place" */
nb_sectors = count >> BDRV_SECTOR_BITS;
if (nb_sectors > 0) {
if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
return -EIO;
if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0)
return ret;
sector_num += nb_sectors;
len = nb_sectors << BDRV_SECTOR_BITS;
buf += len;
@@ -768,11 +770,11 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
/* add data from the last sector */
if (count > 0) {
if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
return -EIO;
if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
return ret;
memcpy(tmp_buf, buf, count);
if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
return -EIO;
if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
return ret;
}
return count1;
}
@@ -1607,7 +1609,7 @@ static void multiwrite_user_cb(MultiwriteCB *mcb)
for (i = 0; i < mcb->num_callbacks; i++) {
mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error);
qemu_free(mcb->callbacks[i].free_qiov);
qemu_free(mcb->callbacks[i].free_buf);
qemu_vfree(mcb->callbacks[i].free_buf);
}
}
+1 -1
View File
@@ -309,7 +309,7 @@ static int curl_open(BlockDriverState *bs, const char *filename, int flags)
static int inited = 0;
file = strdup(filename);
file = qemu_strdup(filename);
s->readahead_size = READ_AHEAD_SIZE;
/* Parse a trailing ":readahead=#:" param, if present. */
+14 -14
View File
@@ -90,24 +90,21 @@ static int dmg_open(BlockDriverState *bs, const char *filename, int flags)
/* read offset of info blocks */
if(lseek(s->fd,-0x1d8,SEEK_END)<0) {
dmg_close:
close(s->fd);
/* open raw instead */
bs->drv=bdrv_find_format("raw");
return bs->drv->bdrv_open(bs, filename, flags);
goto fail;
}
info_begin=read_off(s->fd);
if(info_begin==0)
goto dmg_close;
goto fail;
if(lseek(s->fd,info_begin,SEEK_SET)<0)
goto dmg_close;
goto fail;
if(read_uint32(s->fd)!=0x100)
goto dmg_close;
goto fail;
if((count = read_uint32(s->fd))==0)
goto dmg_close;
goto fail;
info_end = info_begin+count;
if(lseek(s->fd,0xf8,SEEK_CUR)<0)
goto dmg_close;
goto fail;
/* read offsets */
last_in_offset = last_out_offset = 0;
@@ -116,14 +113,14 @@ dmg_close:
count = read_uint32(s->fd);
if(count==0)
goto dmg_close;
goto fail;
type = read_uint32(s->fd);
if(type!=0x6d697368 || count<244)
lseek(s->fd,count-4,SEEK_CUR);
else {
int new_size, chunk_count;
if(lseek(s->fd,200,SEEK_CUR)<0)
goto dmg_close;
goto fail;
chunk_count = (count-204)/40;
new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
s->types = qemu_realloc(s->types, new_size/2);
@@ -142,7 +139,7 @@ dmg_close:
chunk_count--;
i--;
if(lseek(s->fd,36,SEEK_CUR)<0)
goto dmg_close;
goto fail;
continue;
}
read_uint32(s->fd);
@@ -163,11 +160,14 @@ dmg_close:
s->compressed_chunk = qemu_malloc(max_compressed_size+1);
s->uncompressed_chunk = qemu_malloc(512*max_sectors_per_chunk);
if(inflateInit(&s->zstream) != Z_OK)
goto dmg_close;
goto fail;
s->current_chunk = s->n_chunks;
return 0;
fail:
close(s->fd);
return -1;
}
static inline int is_sector_in_chunk(BDRVDMGState* s,
+71 -36
View File
@@ -33,7 +33,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
BDRVQcowState *s = bs->opaque;
int new_l1_size, new_l1_size2, ret, i;
uint64_t *new_l1_table;
uint64_t new_l1_table_offset;
int64_t new_l1_table_offset;
uint8_t data[12];
new_l1_size = s->l1_size;
@@ -55,6 +55,10 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
/* write new table (align to cluster) */
new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2);
if (new_l1_table_offset < 0) {
qemu_free(new_l1_table);
return new_l1_table_offset;
}
for(i = 0; i < s->l1_size; i++)
new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
@@ -67,9 +71,10 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
/* set new table */
cpu_to_be32w((uint32_t*)data, new_l1_size);
cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset);
if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size), data,
sizeof(data)) != sizeof(data))
ret = bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size), data,sizeof(data));
if (ret != sizeof(data)) {
goto fail;
}
qemu_free(s->l1_table);
qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t));
s->l1_table_offset = new_l1_table_offset;
@@ -77,8 +82,9 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
s->l1_size = new_l1_size;
return 0;
fail:
qemu_free(s->l1_table);
return -EIO;
qemu_free(new_l1_table);
qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2);
return ret < 0 ? ret : -EIO;
}
void qcow2_l2_cache_reset(BlockDriverState *bs)
@@ -213,13 +219,17 @@ static uint64_t *l2_allocate(BlockDriverState *bs, int l1_index)
BDRVQcowState *s = bs->opaque;
int min_index;
uint64_t old_l2_offset;
uint64_t *l2_table, l2_offset;
uint64_t *l2_table;
int64_t l2_offset;
old_l2_offset = s->l1_table[l1_index];
/* allocate a new l2 entry */
l2_offset = qcow2_alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
if (l2_offset < 0) {
return NULL;
}
/* update the L1 entry */
@@ -479,8 +489,8 @@ out:
* the l2 table offset in the qcow2 file and the cluster index
* in the l2 table are given to the caller.
*
* Returns 0 on success, -errno in failure case
*/
static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
uint64_t **new_l2_table,
uint64_t *new_l2_offset,
@@ -496,8 +506,9 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
l1_index = offset >> (s->l2_bits + s->cluster_bits);
if (l1_index >= s->l1_size) {
ret = qcow2_grow_l1_table(bs, l1_index + 1);
if (ret < 0)
return 0;
if (ret < 0) {
return ret;
}
}
l2_offset = s->l1_table[l1_index];
@@ -507,14 +518,16 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
/* load the l2 table in memory */
l2_offset &= ~QCOW_OFLAG_COPIED;
l2_table = l2_load(bs, l2_offset);
if (l2_table == NULL)
return 0;
if (l2_table == NULL) {
return -EIO;
}
} else {
if (l2_offset)
qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));
l2_table = l2_allocate(bs, l1_index);
if (l2_table == NULL)
return 0;
if (l2_table == NULL) {
return -EIO;
}
l2_offset = s->l1_table[l1_index] & ~QCOW_OFLAG_COPIED;
}
@@ -526,7 +539,7 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
*new_l2_offset = l2_offset;
*new_l2_index = l2_index;
return 1;
return 0;
}
/*
@@ -548,12 +561,14 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
{
BDRVQcowState *s = bs->opaque;
int l2_index, ret;
uint64_t l2_offset, *l2_table, cluster_offset;
uint64_t l2_offset, *l2_table;
int64_t cluster_offset;
int nb_csectors;
ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
if (ret == 0)
if (ret < 0) {
return 0;
}
cluster_offset = be64_to_cpu(l2_table[l2_index]);
if (cluster_offset & QCOW_OFLAG_COPIED)
@@ -563,6 +578,10 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
qcow2_free_any_clusters(bs, cluster_offset, 1);
cluster_offset = qcow2_alloc_bytes(bs, compressed_size);
if (cluster_offset < 0) {
return 0;
}
nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
(cluster_offset >> 9);
@@ -605,12 +624,12 @@ static int write_l2_entries(BDRVQcowState *s, uint64_t *l2_table,
return 0;
}
int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, uint64_t cluster_offset,
QCowL2Meta *m)
int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
{
BDRVQcowState *s = bs->opaque;
int i, j = 0, l2_index, ret;
uint64_t *old_cluster, start_sect, l2_offset, *l2_table;
uint64_t cluster_offset = m->cluster_offset;
if (m->nb_clusters == 0)
return 0;
@@ -633,10 +652,11 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, uint64_t cluster_offset,
goto err;
}
ret = -EIO;
/* update L2 table */
if (!get_cluster_table(bs, m->offset, &l2_table, &l2_offset, &l2_index))
ret = get_cluster_table(bs, m->offset, &l2_table, &l2_offset, &l2_index);
if (ret < 0) {
goto err;
}
for (i = 0; i < m->nb_clusters; i++) {
/* if two concurrent writes happen to the same unallocated cluster
@@ -670,30 +690,36 @@ err:
/*
* alloc_cluster_offset
*
* For a given offset of the disk image, return cluster offset in
* qcow2 file.
*
* For a given offset of the disk image, return cluster offset in qcow2 file.
* If the offset is not found, allocate a new cluster.
*
* Return the cluster offset if successful,
* Return 0, otherwise.
* If the cluster was already allocated, m->nb_clusters is set to 0,
* m->depends_on is set to NULL and the other fields in m are meaningless.
*
* If the cluster is newly allocated, m->nb_clusters is set to the number of
* contiguous clusters that have been allocated. This may be 0 if the request
* conflict with another write request in flight; in this case, m->depends_on
* is set and the remaining fields of m are meaningless.
*
* If m->nb_clusters is non-zero, the other fields of m are valid and contain
* information about the first allocated cluster.
*
* Return 0 on success and -errno in error cases
*/
uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs,
uint64_t offset,
int n_start, int n_end,
int *num, QCowL2Meta *m)
int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
int n_start, int n_end, int *num, QCowL2Meta *m)
{
BDRVQcowState *s = bs->opaque;
int l2_index, ret;
uint64_t l2_offset, *l2_table, cluster_offset;
uint64_t l2_offset, *l2_table;
int64_t cluster_offset;
unsigned int nb_clusters, i = 0;
QCowL2Meta *old_alloc;
ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
if (ret == 0)
return 0;
if (ret < 0) {
return ret;
}
nb_clusters = size_to_clusters(s, n_end << 9);
@@ -709,6 +735,7 @@ uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs,
cluster_offset &= ~QCOW_OFLAG_COPIED;
m->nb_clusters = 0;
m->depends_on = NULL;
goto out;
}
@@ -723,12 +750,15 @@ uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs,
while (i < nb_clusters) {
i += count_contiguous_clusters(nb_clusters - i, s->cluster_size,
&l2_table[l2_index], i, 0);
if(be64_to_cpu(l2_table[l2_index + i]))
if ((i >= nb_clusters) || be64_to_cpu(l2_table[l2_index + i])) {
break;
}
i += count_contiguous_free_clusters(nb_clusters - i,
&l2_table[l2_index + i]);
if (i >= nb_clusters) {
break;
}
cluster_offset = be64_to_cpu(l2_table[l2_index + i]);
@@ -736,6 +766,7 @@ uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs,
(cluster_offset & QCOW_OFLAG_COMPRESSED))
break;
}
assert(i <= nb_clusters);
nb_clusters = i;
/*
@@ -779,6 +810,9 @@ uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs,
/* allocate a new cluster */
cluster_offset = qcow2_alloc_clusters(bs, nb_clusters * s->cluster_size);
if (cluster_offset < 0) {
return cluster_offset;
}
/* save info needed for meta data update */
m->offset = offset;
@@ -787,10 +821,11 @@ uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs,
out:
m->nb_available = MIN(nb_clusters << (s->cluster_bits - 9), n_end);
m->cluster_offset = cluster_offset;
*num = m->nb_available - n_start;
return cluster_offset;
return 0;
}
static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
+65 -19
View File
@@ -168,9 +168,12 @@ static int grow_refcount_table(BlockDriverState *bs, int min_size)
cpu_to_be64w((uint64_t*)data, table_offset);
cpu_to_be32w((uint32_t*)(data + 8), refcount_table_clusters);
if (bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_offset),
data, sizeof(data)) != sizeof(data))
ret = bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_offset),
data, sizeof(data));
if (ret != sizeof(data)) {
goto fail;
}
qemu_free(s->refcount_table);
old_table_offset = s->refcount_table_offset;
old_table_size = s->refcount_table_size;
@@ -183,7 +186,7 @@ static int grow_refcount_table(BlockDriverState *bs, int min_size)
return 0;
fail:
qemu_free(new_table);
return -EIO;
return ret < 0 ? ret : -EIO;
}
@@ -266,22 +269,26 @@ static int write_refcount_block_entries(BDRVQcowState *s,
}
/* XXX: cache several refcount block clusters ? */
static int update_refcount(BlockDriverState *bs,
int64_t offset, int64_t length,
int addend)
static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
int64_t offset, int64_t length, int addend)
{
BDRVQcowState *s = bs->opaque;
int64_t start, last, cluster_offset;
int64_t refcount_block_offset = 0;
int64_t table_index = -1, old_table_index;
int first_index = -1, last_index = -1;
int ret;
#ifdef DEBUG_ALLOC2
printf("update_refcount: offset=%" PRId64 " size=%" PRId64 " addend=%d\n",
offset, length, addend);
#endif
if (length <= 0)
if (length < 0) {
return -EINVAL;
} else if (length == 0) {
return 0;
}
start = offset & ~(s->cluster_size - 1);
last = (offset + length - 1) & ~(s->cluster_size - 1);
for(cluster_offset = start; cluster_offset <= last;
@@ -289,6 +296,7 @@ static int update_refcount(BlockDriverState *bs,
{
int block_index, refcount;
int64_t cluster_index = cluster_offset >> s->cluster_bits;
int64_t new_block;
/* Only write refcount block to disk when we are done with it */
old_table_index = table_index;
@@ -306,10 +314,12 @@ static int update_refcount(BlockDriverState *bs,
}
/* Load the refcount block and allocate it if needed */
refcount_block_offset = alloc_refcount_block(bs, cluster_index);
if (refcount_block_offset < 0) {
return refcount_block_offset;
new_block = alloc_refcount_block(bs, cluster_index);
if (new_block < 0) {
ret = new_block;
goto fail;
}
refcount_block_offset = new_block;
/* we can update the count and save it */
block_index = cluster_index &
@@ -323,24 +333,38 @@ static int update_refcount(BlockDriverState *bs,
refcount = be16_to_cpu(s->refcount_block_cache[block_index]);
refcount += addend;
if (refcount < 0 || refcount > 0xffff)
return -EINVAL;
if (refcount < 0 || refcount > 0xffff) {
ret = -EINVAL;
goto fail;
}
if (refcount == 0 && cluster_index < s->free_cluster_index) {
s->free_cluster_index = cluster_index;
}
s->refcount_block_cache[block_index] = cpu_to_be16(refcount);
}
ret = 0;
fail:
/* Write last changed block to disk */
if (refcount_block_offset != 0) {
if (write_refcount_block_entries(s, refcount_block_offset,
first_index, last_index) < 0)
{
return -EIO;
return ret < 0 ? ret : -EIO;
}
}
return 0;
/*
* Try do undo any updates if an error is returned (This may succeed in
* some cases like ENOSPC for allocating a new refcount block)
*/
if (ret < 0) {
int dummy;
dummy = update_refcount(bs, offset, cluster_offset - offset, -addend);
}
return ret;
}
/* addend must be 1 or -1 */
@@ -390,9 +414,13 @@ retry:
int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size)
{
int64_t offset;
int ret;
offset = alloc_clusters_noref(bs, size);
update_refcount(bs, offset, size, 1);
ret = update_refcount(bs, offset, size, 1);
if (ret < 0) {
return ret;
}
return offset;
}
@@ -407,6 +435,9 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
assert(size > 0 && size <= s->cluster_size);
if (s->free_byte_offset == 0) {
s->free_byte_offset = qcow2_alloc_clusters(bs, s->cluster_size);
if (s->free_byte_offset < 0) {
return s->free_byte_offset;
}
}
redo:
free_in_cluster = s->cluster_size -
@@ -422,6 +453,9 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
update_cluster_refcount(bs, offset >> s->cluster_bits, 1);
} else {
offset = qcow2_alloc_clusters(bs, s->cluster_size);
if (offset < 0) {
return offset;
}
cluster_offset = s->free_byte_offset & ~(s->cluster_size - 1);
if ((cluster_offset + s->cluster_size) == offset) {
/* we are lucky: contiguous data */
@@ -439,7 +473,13 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
void qcow2_free_clusters(BlockDriverState *bs,
int64_t offset, int64_t size)
{
update_refcount(bs, offset, size, -1);
int ret;
ret = update_refcount(bs, offset, size, -1);
if (ret < 0) {
fprintf(stderr, "qcow2_free_clusters failed: %s\n", strerror(-ret));
abort();
}
}
/*
@@ -549,9 +589,15 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
if (offset & QCOW_OFLAG_COMPRESSED) {
nb_csectors = ((offset >> s->csize_shift) &
s->csize_mask) + 1;
if (addend != 0)
update_refcount(bs, (offset & s->cluster_offset_mask) & ~511,
nb_csectors * 512, addend);
if (addend != 0) {
int ret;
ret = update_refcount(bs,
(offset & s->cluster_offset_mask) & ~511,
nb_csectors * 512, addend);
if (ret < 0) {
goto fail;
}
}
/* compressed clusters are never modified */
refcount = 2;
} else {
+10 -1
View File
@@ -139,6 +139,9 @@ static int qcow_write_snapshots(BlockDriverState *bs)
snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size);
offset = snapshots_offset;
if (offset < 0) {
return offset;
}
for(i = 0; i < s->nb_snapshots; i++) {
sn = s->snapshots + i;
@@ -235,6 +238,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
QCowSnapshot *snapshots1, sn1, *sn = &sn1;
int i, ret;
uint64_t *l1_table = NULL;
int64_t l1_table_offset;
memset(sn, 0, sizeof(*sn));
@@ -263,7 +267,12 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
goto fail;
/* create the L1 table of the snapshot */
sn->l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t));
l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t));
if (l1_table_offset < 0) {
goto fail;
}
sn->l1_table_offset = l1_table_offset;
sn->l1_size = s->l1_size;
if (s->l1_size != 0) {
+22 -19
View File
@@ -561,7 +561,7 @@ static void qcow_aio_write_cb(void *opaque, int ret)
acb->hd_aiocb = NULL;
if (ret >= 0) {
ret = qcow2_alloc_cluster_link_l2(bs, acb->cluster_offset, &acb->l2meta);
ret = qcow2_alloc_cluster_link_l2(bs, &acb->l2meta);
}
run_dependent_requests(&acb->l2meta);
@@ -585,21 +585,23 @@ static void qcow_aio_write_cb(void *opaque, int ret)
n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors)
n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
acb->cluster_offset = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9,
index_in_cluster,
n_end, &acb->n, &acb->l2meta);
ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9,
index_in_cluster, n_end, &acb->n, &acb->l2meta);
if (ret < 0) {
goto done;
}
acb->cluster_offset = acb->l2meta.cluster_offset;
/* Need to wait for another request? If so, we are done for now. */
if (!acb->cluster_offset && acb->l2meta.depends_on != NULL) {
if (acb->l2meta.nb_clusters == 0 && acb->l2meta.depends_on != NULL) {
QLIST_INSERT_HEAD(&acb->l2meta.depends_on->dependent_requests,
acb, next_depend);
return;
}
if (!acb->cluster_offset || (acb->cluster_offset & 511) != 0) {
ret = -EIO;
goto done;
}
assert((acb->cluster_offset & 511) == 0);
if (s->crypt_method) {
if (!acb->cluster_data) {
acb->cluster_data = qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS *
@@ -683,27 +685,27 @@ static int get_bits_from_size(size_t size)
static int preallocate(BlockDriverState *bs)
{
BDRVQcowState *s = bs->opaque;
uint64_t cluster_offset = 0;
uint64_t nb_sectors;
uint64_t offset;
int num;
int ret;
QCowL2Meta meta;
nb_sectors = bdrv_getlength(bs) >> 9;
offset = 0;
QLIST_INIT(&meta.dependent_requests);
meta.cluster_offset = 0;
while (nb_sectors) {
num = MIN(nb_sectors, INT_MAX >> 9);
cluster_offset = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num,
&meta);
ret = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num, &meta);
if (cluster_offset == 0) {
if (ret < 0) {
return -1;
}
if (qcow2_alloc_cluster_link_l2(bs, cluster_offset, &meta) < 0) {
qcow2_free_any_clusters(bs, cluster_offset, meta.nb_clusters);
if (qcow2_alloc_cluster_link_l2(bs, &meta) < 0) {
qcow2_free_any_clusters(bs, meta.cluster_offset, meta.nb_clusters);
return -1;
}
@@ -722,10 +724,10 @@ static int preallocate(BlockDriverState *bs)
* all of the allocated clusters (otherwise we get failing reads after
* EOF). Extend the image to the last allocated sector.
*/
if (cluster_offset != 0) {
if (meta.cluster_offset != 0) {
uint8_t buf[512];
memset(buf, 0, 512);
bdrv_write(s->hd, (cluster_offset >> 9) + num - 1, buf, 1);
bdrv_write(s->hd, (meta.cluster_offset >> 9) + num - 1, buf, 1);
}
return 0;
@@ -1056,12 +1058,13 @@ static int qcow_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
{
BDRVQcowState *s = bs->opaque;
int growable = bs->growable;
int ret;
bs->growable = 1;
bdrv_pwrite(bs, qcow_vm_state_offset(s) + pos, buf, size);
ret = bdrv_pwrite(bs, qcow_vm_state_offset(s) + pos, buf, size);
bs->growable = growable;
return size;
return ret;
}
static int qcow_load_vmstate(BlockDriverState *bs, uint8_t *buf,
+4 -6
View File
@@ -135,6 +135,7 @@ struct QCowAIOCB;
typedef struct QCowL2Meta
{
uint64_t offset;
uint64_t cluster_offset;
int n_start;
int nb_available;
int nb_clusters;
@@ -191,16 +192,13 @@ void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
uint64_t qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
int *num);
uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs,
uint64_t offset,
int n_start, int n_end,
int *num, QCowL2Meta *m);
int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
int n_start, int n_end, int *num, QCowL2Meta *m);
uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
uint64_t offset,
int compressed_size);
int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, uint64_t cluster_offset,
QCowL2Meta *m);
int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
/* qcow2-snapshot.c functions */
int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info);
+1 -1
View File
@@ -595,7 +595,7 @@ static void raw_close(BlockDriverState *bs)
close(s->fd);
s->fd = -1;
if (s->aligned_buf != NULL)
qemu_free(s->aligned_buf);
qemu_vfree(s->aligned_buf);
}
}
+5 -5
View File
@@ -882,7 +882,7 @@ static int init_directories(BDRVVVFATState* s,
mapping->dir_index = 0;
mapping->info.dir.parent_mapping_index = -1;
mapping->first_mapping_index = -1;
mapping->path = strdup(dirname);
mapping->path = qemu_strdup(dirname);
i = strlen(mapping->path);
if (i > 0 && mapping->path[i - 1] == '/')
mapping->path[i - 1] = '\0';
@@ -1632,10 +1632,10 @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
/* rename */
if (strcmp(basename, basename2))
schedule_rename(s, cluster_num, strdup(path));
schedule_rename(s, cluster_num, qemu_strdup(path));
} else if (is_file(direntry))
/* new file */
schedule_new_file(s, strdup(path), cluster_num);
schedule_new_file(s, qemu_strdup(path), cluster_num);
else {
assert(0);
return 0;
@@ -1752,10 +1752,10 @@ static int check_directory_consistency(BDRVVVFATState *s,
mapping->mode &= ~MODE_DELETED;
if (strcmp(basename, basename2))
schedule_rename(s, cluster_num, strdup(path));
schedule_rename(s, cluster_num, qemu_strdup(path));
} else
/* new directory */
schedule_mkdir(s, cluster_num, strdup(path));
schedule_mkdir(s, cluster_num, qemu_strdup(path));
lfn_init(&lfn);
do {
Vendored
+3
View File
@@ -2652,3 +2652,6 @@ d=libuser
mkdir -p $d
rm -f $d/Makefile
ln -s $source_path/Makefile.user $d/Makefile
if test "$static" = "no" -a "$user_pie" = "yes" ; then
echo "QEMU_CFLAGS+=-fpie" > $d/config.mak
fi
+2 -1
View File
@@ -1017,7 +1017,8 @@ static inline int64_t cpu_get_real_ticks (void)
#endif
}
#elif (defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__)
#elif defined(__mips__) && \
((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__))
/*
* binutils wants to use rdhwr only on mips32r2
* but as linux kernel emulate it, it's fine
+7 -5
View File
@@ -232,11 +232,13 @@ int cpu_exec(CPUState *env1)
env_to_regs();
#if defined(TARGET_I386)
/* put eflags in CPU temporary format */
CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
DF = 1 - (2 * ((env->eflags >> 10) & 1));
CC_OP = CC_OP_EFLAGS;
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
if (!kvm_enabled()) {
/* put eflags in CPU temporary format */
CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
DF = 1 - (2 * ((env->eflags >> 10) & 1));
CC_OP = CC_OP_EFLAGS;
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
}
#elif defined(TARGET_SPARC)
#elif defined(TARGET_M68K)
env->cc_op = CC_OP_FLAGS;
+1 -1
View File
@@ -3307,7 +3307,7 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
if (is_write) {
cpu_physical_memory_write(bounce.addr, bounce.buffer, access_len);
}
qemu_free(bounce.buffer);
qemu_vfree(bounce.buffer);
bounce.buffer = NULL;
cpu_notify_map_clients();
}
+4 -2
View File
@@ -2585,9 +2585,11 @@ static void map_linear_vram(CirrusVGAState *s)
static void unmap_linear_vram(CirrusVGAState *s)
{
if (s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end)
if (s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) {
s->vga.map_addr = s->vga.map_end = 0;
cpu_register_physical_memory(s->vga.lfb_addr, s->vga.vram_size,
s->cirrus_linear_io_addr);
}
cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
s->vga.vga_io_memory);
}
+6
View File
@@ -935,6 +935,12 @@ static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl)
fdctrl->dsr &= ~FD_DSR_PWRDOWN;
fdctrl->dor |= FD_DOR_nRESET;
/* Sparc mutation */
if (fdctrl->sun4m) {
retval |= FD_MSR_DIO;
fdctrl_reset_irq(fdctrl);
};
FLOPPY_DPRINTF("main status register: 0x%02x\n", retval);
return retval;
+11 -7
View File
@@ -278,7 +278,7 @@ int fw_cfg_add_file(FWCfgState *s, const char *dir, const char *filename,
uint8_t *data, uint32_t len)
{
const char *basename;
int index;
int i, index;
if (!s->files) {
int dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS;
@@ -300,13 +300,17 @@ int fw_cfg_add_file(FWCfgState *s, const char *dir, const char *filename,
} else {
basename = filename;
}
if (dir) {
snprintf(s->files->f[index].name, sizeof(s->files->f[index].name),
"%s/%s", dir, basename);
} else {
snprintf(s->files->f[index].name, sizeof(s->files->f[index].name),
"%s", basename);
snprintf(s->files->f[index].name, sizeof(s->files->f[index].name),
"%s/%s", dir, basename);
for (i = 0; i < index; i++) {
if (strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
FW_CFG_DPRINTF("%s: skip duplicate: %s\n", __FUNCTION__,
s->files->f[index].name);
return 1;
}
}
s->files->f[index].size = cpu_to_be32(len);
s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index);
FW_CFG_DPRINTF("%s: #%d: %s (%d bytes)\n", __FUNCTION__,
+69 -9
View File
@@ -115,7 +115,7 @@ static void ide_identify(IDEState *s)
put_le16(p + 20, 3); /* XXX: retired, remove ? */
put_le16(p + 21, 512); /* cache size in sectors */
put_le16(p + 22, 4); /* ecc bytes */
padstr((char *)(p + 23), QEMU_VERSION, 8); /* firmware version */
padstr((char *)(p + 23), s->version, 8); /* firmware version */
padstr((char *)(p + 27), "QEMU HARDDISK", 40); /* model */
#if MAX_MULT_SECTORS > 1
put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
@@ -186,7 +186,7 @@ static void ide_atapi_identify(IDEState *s)
put_le16(p + 20, 3); /* buffer type */
put_le16(p + 21, 512); /* cache size in sectors */
put_le16(p + 22, 4); /* ecc bytes */
padstr((char *)(p + 23), QEMU_VERSION, 8); /* firmware version */
padstr((char *)(p + 23), s->version, 8); /* firmware version */
padstr((char *)(p + 27), "QEMU DVD-ROM", 40); /* model */
put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
#ifdef USE_DMA_CDROM
@@ -238,7 +238,7 @@ static void ide_cfata_identify(IDEState *s)
put_le16(p + 8, s->nb_sectors); /* Sectors per card */
padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
put_le16(p + 22, 0x0004); /* ECC bytes */
padstr((char *) (p + 23), QEMU_VERSION, 8); /* Firmware Revision */
padstr((char *) (p + 23), s->version, 8); /* Firmware Revision */
padstr((char *) (p + 27), "QEMU MICRODRIVE", 40);/* Model number */
#if MAX_MULT_SECTORS > 1
put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
@@ -1591,7 +1591,7 @@ static void ide_atapi_cmd(IDEState *s)
buf[7] = 0; /* reserved */
padstr8(buf + 8, 8, "QEMU");
padstr8(buf + 16, 16, "QEMU DVD-ROM");
padstr8(buf + 32, 4, QEMU_VERSION);
padstr8(buf + 32, 4, s->version);
ide_atapi_cmd_reply(s, 36, max_len);
break;
case GPCMD_GET_CONFIGURATION:
@@ -2590,7 +2590,7 @@ void ide_bus_reset(IDEBus *bus)
ide_clear_hob(bus);
}
void ide_init_drive(IDEState *s, DriveInfo *dinfo)
void ide_init_drive(IDEState *s, DriveInfo *dinfo, const char *version)
{
int cylinders, heads, secs;
uint64_t nb_sectors;
@@ -2619,6 +2619,11 @@ void ide_init_drive(IDEState *s, DriveInfo *dinfo)
if (strlen(s->drive_serial_str) == 0)
snprintf(s->drive_serial_str, sizeof(s->drive_serial_str),
"QM%05d", s->drive_serial);
if (version) {
pstrcpy(s->version, sizeof(s->version), version);
} else {
pstrcpy(s->version, sizeof(s->version), QEMU_VERSION);
}
ide_reset(s);
}
@@ -2635,13 +2640,14 @@ void ide_init2(IDEBus *bus, DriveInfo *hd0, DriveInfo *hd1,
s->unit = i;
s->drive_serial = drive_serial++;
s->io_buffer = qemu_blockalign(s->bs, IDE_DMA_BUF_SECTORS*512 + 4);
s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4;
s->smart_selftest_data = qemu_blockalign(s->bs, 512);
s->sector_write_timer = qemu_new_timer(vm_clock,
ide_sector_write_timer_cb, s);
if (i == 0)
ide_init_drive(s, hd0);
ide_init_drive(s, hd0, NULL);
if (i == 1)
ide_init_drive(s, hd1);
ide_init_drive(s, hd1, NULL);
}
bus->irq = irq;
}
@@ -2669,6 +2675,25 @@ static bool is_identify_set(void *opaque, int version_id)
return s->identify_set != 0;
}
static EndTransferFunc* transfer_end_table[] = {
ide_sector_read,
ide_sector_write,
ide_transfer_stop,
ide_atapi_cmd_reply_end,
ide_atapi_cmd,
};
static int transfer_end_table_idx(EndTransferFunc *fn)
{
int i;
for (i = 0; i < ARRAY_SIZE(transfer_end_table); i++)
if (transfer_end_table[i] == fn)
return i;
return -1;
}
static int ide_drive_post_load(void *opaque, int version_id)
{
IDEState *s = opaque;
@@ -2679,14 +2704,42 @@ static int ide_drive_post_load(void *opaque, int version_id)
s->cdrom_changed = 1;
}
}
if (s->cur_io_buffer_len) {
s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx];
s->data_ptr = s->io_buffer + s->cur_io_buffer_offset;
s->data_end = s->data_ptr + s->cur_io_buffer_len;
}
return 0;
}
static void ide_drive_pre_save(void *opaque)
{
IDEState *s = opaque;
s->cur_io_buffer_len = 0;
if (!(s->status & DRQ_STAT))
return;
s->cur_io_buffer_offset = s->data_ptr - s->io_buffer;
s->cur_io_buffer_len = s->data_end - s->data_ptr;
s->end_transfer_fn_idx = transfer_end_table_idx(s->end_transfer_func);
if (s->end_transfer_fn_idx == -1) {
fprintf(stderr, "%s: invalid end_transfer_func for DRQ_STAT\n",
__func__);
s->end_transfer_fn_idx = 2;
}
}
const VMStateDescription vmstate_ide_drive = {
.name = "ide_drive",
.version_id = 3,
.version_id = 4,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.pre_save = ide_drive_pre_save,
.post_load = ide_drive_post_load,
.fields = (VMStateField []) {
VMSTATE_INT32(mult_sectors, IDEState),
@@ -2709,7 +2762,14 @@ const VMStateDescription vmstate_ide_drive = {
VMSTATE_UINT8(sense_key, IDEState),
VMSTATE_UINT8(asc, IDEState),
VMSTATE_UINT8_V(cdrom_changed, IDEState, 3),
/* XXX: if a transfer is pending, we do not save it yet */
VMSTATE_INT32_V(req_nb_sectors, IDEState, 4),
VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 4,
vmstate_info_uint8, uint8_t),
VMSTATE_INT32_V(cur_io_buffer_offset, IDEState, 4),
VMSTATE_INT32_V(cur_io_buffer_len, IDEState, 4),
VMSTATE_UINT8_V(end_transfer_fn_idx, IDEState, 4),
VMSTATE_INT32_V(elementary_transfer_size, IDEState, 4),
VMSTATE_INT32_V(packet_transfer_size, IDEState, 4),
VMSTATE_END_OF_LIST()
}
};
+8 -1
View File
@@ -397,6 +397,7 @@ struct IDEState {
/* set for lba48 access */
uint8_t lba48;
BlockDriverState *bs;
char version[9];
/* ATAPI specific */
uint8_t sense_key;
uint8_t asc;
@@ -416,6 +417,11 @@ struct IDEState {
uint8_t *data_ptr;
uint8_t *data_end;
uint8_t *io_buffer;
/* PIO save/restore */
int32_t io_buffer_total_len;
int cur_io_buffer_offset;
int cur_io_buffer_len;
uint8_t end_transfer_fn_idx;
QEMUTimer *sector_write_timer; /* only used for win2k install hack */
uint32_t irq_count; /* counts IRQs when using win2k install hack */
/* CF-ATA extended error */
@@ -449,6 +455,7 @@ struct IDEDevice {
DeviceState qdev;
uint32_t unit;
DriveInfo *dinfo;
char *version;
};
typedef int (*ide_qdev_initfn)(IDEDevice *dev);
@@ -548,7 +555,7 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr);
void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
uint32_t ide_data_readl(void *opaque, uint32_t addr);
void ide_init_drive(IDEState *s, DriveInfo *dinfo);
void ide_init_drive(IDEState *s, DriveInfo *dinfo, const char *version);
void ide_init2(IDEBus *bus, DriveInfo *hd0, DriveInfo *hd1,
qemu_irq irq);
void ide_init_ioport(IDEBus *bus, int iobase, int iobase2);
+2 -1
View File
@@ -99,7 +99,7 @@ typedef struct IDEDrive {
static int ide_drive_initfn(IDEDevice *dev)
{
IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
ide_init_drive(bus->ifs + dev->unit, dev->dinfo);
ide_init_drive(bus->ifs + dev->unit, dev->dinfo, dev->version);
return 0;
}
@@ -110,6 +110,7 @@ static IDEDeviceInfo ide_drive_info = {
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1),
DEFINE_PROP_DRIVE("drive", IDEDrive, dev.dinfo),
DEFINE_PROP_STRING("ver", IDEDrive, dev.version),
DEFINE_PROP_END_OF_LIST(),
}
};
+40 -30
View File
@@ -535,6 +535,7 @@ struct Rom {
QTAILQ_ENTRY(Rom) next;
};
static FWCfgState *fw_cfg;
static QTAILQ_HEAD(, Rom) roms = QTAILQ_HEAD_INITIALIZER(roms);
int rom_enable_driver_roms;
@@ -556,7 +557,7 @@ static void rom_insert(Rom *rom)
QTAILQ_INSERT_TAIL(&roms, rom, next);
}
int rom_add_file(const char *file, const char *fw_dir, const char *fw_file,
int rom_add_file(const char *file, const char *fw_dir,
target_phys_addr_t addr)
{
Rom *rom;
@@ -576,8 +577,10 @@ int rom_add_file(const char *file, const char *fw_dir, const char *fw_file,
goto err;
}
rom->fw_dir = fw_dir ? qemu_strdup(fw_dir) : NULL;
rom->fw_file = fw_file ? qemu_strdup(fw_file) : NULL;
if (fw_dir) {
rom->fw_dir = qemu_strdup(fw_dir);
rom->fw_file = qemu_strdup(file);
}
rom->addr = addr;
rom->romsize = lseek(fd, 0, SEEK_END);
rom->data = qemu_mallocz(rom->romsize);
@@ -590,6 +593,8 @@ int rom_add_file(const char *file, const char *fw_dir, const char *fw_file,
}
close(fd);
rom_insert(rom);
if (rom->fw_file && fw_cfg)
fw_cfg_add_file(fw_cfg, rom->fw_dir, rom->fw_file, rom->data, rom->romsize);
return 0;
err:
@@ -621,14 +626,14 @@ int rom_add_vga(const char *file)
{
if (!rom_enable_driver_roms)
return 0;
return rom_add_file(file, "vgaroms", file, 0);
return rom_add_file(file, "vgaroms", 0);
}
int rom_add_option(const char *file)
{
if (!rom_enable_driver_roms)
return 0;
return rom_add_file(file, "genroms", file, 0);
return rom_add_file(file, "genroms", 0);
}
static void rom_reset(void *unused)
@@ -636,10 +641,12 @@ static void rom_reset(void *unused)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->addr == 0)
if (rom->fw_file) {
continue;
if (rom->data == NULL)
}
if (rom->data == NULL) {
continue;
}
cpu_physical_memory_write_rom(rom->addr, rom->data, rom->romsize);
if (rom->isrom) {
/* rom needs to be written only once */
@@ -656,8 +663,9 @@ int rom_load_all(void)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->addr == 0)
if (rom->fw_file) {
continue;
}
if (addr > rom->addr) {
fprintf(stderr, "rom: requested regions overlap "
"(rom %s. free=0x" TARGET_FMT_plx
@@ -676,16 +684,9 @@ int rom_load_all(void)
return 0;
}
int rom_load_fw(void *fw_cfg)
void rom_set_fw(void *f)
{
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (!rom->fw_file)
continue;
fw_cfg_add_file(fw_cfg, rom->fw_dir, rom->fw_file, rom->data, rom->romsize);
}
return 0;
fw_cfg = f;
}
static Rom *find_rom(target_phys_addr_t addr)
@@ -693,17 +694,25 @@ static Rom *find_rom(target_phys_addr_t addr)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->addr == 0)
if (rom->fw_file) {
continue;
if (rom->addr > addr)
}
if (rom->addr > addr) {
continue;
if (rom->addr + rom->romsize < addr)
}
if (rom->addr + rom->romsize < addr) {
continue;
}
return rom;
}
return NULL;
}
/*
* Copies memory from registered ROMs to dest. Any memory that is contained in
* a ROM between addr and addr + size is copied. Note that this can involve
* multiple ROMs, which need not start at addr and need not end at addr + size.
*/
int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size)
{
target_phys_addr_t end = addr + size;
@@ -712,16 +721,18 @@ int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->addr == 0)
if (rom->fw_file) {
continue;
if (rom->addr > addr)
}
if (rom->addr + rom->romsize < addr) {
continue;
if (rom->addr + rom->romsize < addr)
continue;
if (rom->addr > end)
}
if (rom->addr > end) {
break;
if (!rom->data)
}
if (!rom->data) {
continue;
}
d = dest + (rom->addr - addr);
s = rom->data;
@@ -757,17 +768,16 @@ void do_info_roms(Monitor *mon)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->addr) {
if (!rom->fw_file) {
monitor_printf(mon, "addr=" TARGET_FMT_plx
" size=0x%06zx mem=%s name=\"%s\" \n",
rom->addr, rom->romsize,
rom->isrom ? "rom" : "ram",
rom->name);
} else {
monitor_printf(mon, "fw=%s%s%s"
monitor_printf(mon, "fw=%s/%s"
" size=0x%06zx name=\"%s\" \n",
rom->fw_dir ? rom->fw_dir : "",
rom->fw_dir ? "/" : "",
rom->fw_dir,
rom->fw_file,
rom->romsize,
rom->name);
+4 -3
View File
@@ -19,18 +19,19 @@ void pstrcpy_targphys(const char *name,
target_phys_addr_t dest, int buf_size,
const char *source);
int rom_add_file(const char *file, const char *fw_dir, const char *fw_file,
int rom_add_file(const char *file, const char *fw_dir,
target_phys_addr_t addr);
int rom_add_blob(const char *name, const void *blob, size_t len,
target_phys_addr_t addr);
int rom_load_all(void);
int rom_load_fw(void *fw_cfg);
void rom_set_fw(void *f);
int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size);
void *rom_ptr(target_phys_addr_t addr);
void do_info_roms(Monitor *mon);
#define rom_add_file_fixed(_f, _a) \
rom_add_file(_f, NULL, NULL, _a)
rom_add_file(_f, NULL, _a)
#define rom_add_blob_fixed(_f, _b, _l, _a) \
rom_add_blob(_f, _b, _l, _a)
+1 -1
View File
@@ -30,7 +30,7 @@
//#define DEBUG_CMOS
#define RTC_REINJECT_ON_ACK_COUNT 1000
#define RTC_REINJECT_ON_ACK_COUNT 20
#define RTC_SECONDS 0
#define RTC_SECONDS_ALARM 1
+4 -5
View File
@@ -67,7 +67,7 @@
#define MP_AUDIO_IRQ 30
/* Wolfson 8750 I2C address */
#define MP_WM_ADDR 0x34
#define MP_WM_ADDR 0x1A
/* Ethernet register offsets */
#define MP_ETH_SMIR 0x010
@@ -238,14 +238,13 @@ static void eth_send(mv88w8618_eth_state *s, int queue_index)
{
uint32_t desc_addr = s->tx_queue[queue_index];
mv88w8618_tx_desc desc;
uint32_t next_desc;
uint8_t buf[2048];
int len;
if (!desc_addr) {
return;
}
do {
eth_tx_desc_get(desc_addr, &desc);
next_desc = desc.next;
if (desc.cmdstat & MP_ETH_TX_OWN) {
len = desc.bytes;
if (len < 2048) {
@@ -256,7 +255,7 @@ static void eth_send(mv88w8618_eth_state *s, int queue_index)
s->icr |= 1 << (MP_ETH_IRQ_TXLO_BIT - queue_index);
eth_tx_desc_put(desc_addr, &desc);
}
desc_addr = desc.next;
desc_addr = next_desc;
} while (desc_addr != s->tx_queue[queue_index]);
}
+42 -3
View File
@@ -1090,6 +1090,7 @@ static void pc_init1(ram_addr_t ram_size,
bios_size, bios_offset | IO_MEM_ROM);
fw_cfg = bochs_bios_init();
rom_set_fw(fw_cfg);
if (linux_boot) {
load_linux(fw_cfg, kernel_filename, initrd_filename, kernel_cmdline, below_4g_mem_size);
@@ -1250,8 +1251,6 @@ static void pc_init1(ram_addr_t ram_size,
}
}
}
rom_load_fw(fw_cfg);
}
static void pc_init_pci(ram_addr_t ram_size,
@@ -1289,7 +1288,7 @@ void cmos_set_s3_resume(void)
}
static QEMUMachine pc_machine = {
.name = "pc-0.11",
.name = "pc-0.12",
.alias = "pc",
.desc = "Standard PC",
.init = pc_init_pci,
@@ -1297,6 +1296,33 @@ static QEMUMachine pc_machine = {
.is_default = 1,
};
static QEMUMachine pc_machine_v0_11 = {
.name = "pc-0.11",
.desc = "Standard PC, qemu 0.11",
.init = pc_init_pci,
.max_cpus = 255,
.compat_props = (GlobalProperty[]) {
{
.driver = "virtio-blk-pci",
.property = "vectors",
.value = stringify(0),
},{
.driver = "ide-drive",
.property = "ver",
.value = "0.11",
},{
.driver = "scsi-disk",
.property = "ver",
.value = "0.11",
},{
.driver = "PCI",
.property = "rombar",
.value = stringify(0),
},
{ /* end of list */ }
}
};
static QEMUMachine pc_machine_v0_10 = {
.name = "pc-0.10",
.desc = "Standard PC, qemu 0.10",
@@ -1319,6 +1345,18 @@ static QEMUMachine pc_machine_v0_10 = {
.driver = "virtio-blk-pci",
.property = "vectors",
.value = stringify(0),
},{
.driver = "ide-drive",
.property = "ver",
.value = "0.10",
},{
.driver = "scsi-disk",
.property = "ver",
.value = "0.10",
},{
.driver = "PCI",
.property = "rombar",
.value = stringify(0),
},
{ /* end of list */ }
},
@@ -1334,6 +1372,7 @@ static QEMUMachine isapc_machine = {
static void pc_machine_init(void)
{
qemu_register_machine(&pc_machine);
qemu_register_machine(&pc_machine_v0_11);
qemu_register_machine(&pc_machine_v0_10);
qemu_register_machine(&isapc_machine);
}
+15
View File
@@ -64,6 +64,7 @@ static struct BusInfo pci_bus_info = {
.props = (Property[]) {
DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
DEFINE_PROP_UINT32("rombar", PCIDevice, rom_bar, 1),
DEFINE_PROP_END_OF_LIST()
}
};
@@ -1464,6 +1465,20 @@ static int pci_add_option_rom(PCIDevice *pdev)
if (strlen(pdev->romfile) == 0)
return 0;
if (!pdev->rom_bar) {
/*
* Load rom via fw_cfg instead of creating a rom bar,
* for 0.11 compatibility.
*/
int class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
if (class == 0x0300) {
rom_add_vga(pdev->romfile);
} else {
rom_add_option(pdev->romfile);
}
return 0;
}
path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile);
if (path == NULL) {
path = qemu_strdup(pdev->romfile);
+1
View File
@@ -246,6 +246,7 @@ struct PCIDevice {
/* Location of option rom */
char *romfile;
ram_addr_t rom_offset;
uint32_t rom_bar;
};
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
+20 -8
View File
@@ -5,6 +5,12 @@
* Based on code by Fabrice Bellard
*
* Written by Paul Brook
* Modifications:
* 2009-Dec-12 Artyom Tarasenko : implemented stamdard inquiry for the case
* when the allocation length of CDB is smaller
* than 36.
* 2009-Oct-13 Artyom Tarasenko : implemented the block descriptor in the
* MODE SENSE response.
*
* This code is licenced under the LGPL.
*
@@ -59,6 +65,7 @@ struct SCSIDiskState
int cluster_size;
uint64_t max_lba;
QEMUBH *bh;
char *version;
};
static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
@@ -74,7 +81,7 @@ static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
static void scsi_remove_request(SCSIDiskReq *r)
{
qemu_free(r->iov.iov_base);
qemu_vfree(r->iov.iov_base);
scsi_req_free(&r->req);
}
@@ -309,6 +316,7 @@ static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
{
BlockDriverState *bdrv = req->dev->dinfo->bdrv;
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
int buflen = 0;
if (req->cmd.buf[1] & 0x2) {
@@ -406,11 +414,6 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
return -1;
}
if (req->cmd.xfer < 36) {
BADF("Error: Inquiry (STANDARD) buffer size %zd "
"is less than 36 (TODO: only 5 required)\n", req->cmd.xfer);
}
buflen = req->cmd.xfer;
if (buflen > SCSI_MAX_INQUIRY_LEN)
buflen = SCSI_MAX_INQUIRY_LEN;
@@ -431,12 +434,20 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
memcpy(&outbuf[16], "QEMU HARDDISK ", 16);
}
memcpy(&outbuf[8], "QEMU ", 8);
memcpy(&outbuf[32], QEMU_VERSION, 4);
memcpy(&outbuf[32], s->version ? s->version : QEMU_VERSION, 4);
/* Identify device as SCSI-3 rev 1.
Some later commands are also implemented. */
outbuf[2] = 3;
outbuf[3] = 2; /* Format 2 */
outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */
if (buflen > 36) {
outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */
} else {
/* If the allocation length of CDB is too small,
the additional length is not adjusted */
outbuf[4] = 36 - 5;
}
/* Sync data transfer and TCQ. */
outbuf[7] = 0x10 | (req->bus->tcq ? 0x02 : 0);
return buflen;
@@ -1020,6 +1031,7 @@ static SCSIDeviceInfo scsi_disk_info = {
.get_buf = scsi_get_buf,
.qdev.props = (Property[]) {
DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.dinfo),
DEFINE_PROP_STRING("ver", SCSIDiskState, version),
DEFINE_PROP_END_OF_LIST(),
},
};
+1 -1
View File
@@ -1492,7 +1492,7 @@ static USBDevice *usb_net_init(const char *cmdline)
dev = usb_create(NULL /* FIXME */, "usb-net");
qdev_set_nic_properties(&dev->qdev, &nd_table[idx]);
qdev_init(&dev->qdev);
qdev_init_nofail(&dev->qdev);
return dev;
}
+24 -8
View File
@@ -497,12 +497,28 @@ static int usb_serial_can_read(void *opaque)
static void usb_serial_read(void *opaque, const uint8_t *buf, int size)
{
USBSerialState *s = opaque;
int first_size = RECV_BUF - s->recv_ptr;
if (first_size > size)
first_size = size;
memcpy(s->recv_buf + s->recv_ptr + s->recv_used, buf, first_size);
if (size > first_size)
memcpy(s->recv_buf, buf + first_size, size - first_size);
int first_size, start;
/* room in the buffer? */
if (size > (RECV_BUF - s->recv_used))
size = RECV_BUF - s->recv_used;
start = s->recv_ptr + s->recv_used;
if (start < RECV_BUF) {
/* copy data to end of buffer */
first_size = RECV_BUF - start;
if (first_size > size)
first_size = size;
memcpy(s->recv_buf + start, buf, first_size);
/* wrap around to front if needed */
if (size > first_size)
memcpy(s->recv_buf, buf + first_size, size - first_size);
} else {
start -= RECV_BUF;
memcpy(s->recv_buf + start, buf, size);
}
s->recv_used += size;
}
@@ -583,7 +599,7 @@ static USBDevice *usb_serial_init(const char *filename)
qdev_prop_set_uint16(&dev->qdev, "vendorid", vendorid);
if (productid)
qdev_prop_set_uint16(&dev->qdev, "productid", productid);
qdev_init(&dev->qdev);
qdev_init_nofail(&dev->qdev);
return dev;
}
@@ -599,7 +615,7 @@ static USBDevice *usb_braille_init(const char *unused)
dev = usb_create(NULL /* FIXME */, "usb-braille");
qdev_prop_set_chr(&dev->qdev, "chardev", cdrv);
qdev_init(&dev->qdev);
qdev_init_nofail(&dev->qdev);
return dev;
}
+57 -36
View File
@@ -272,7 +272,7 @@ static void do_multiwrite(BlockDriverState *bs, BlockRequest *blkreq,
if (ret != 0) {
for (i = 0; i < num_writes; i++) {
if (blkreq[i].error) {
virtio_blk_req_complete(blkreq[i].opaque, VIRTIO_BLK_S_IOERR);
virtio_blk_rw_complete(blkreq[i].opaque, -EIO);
}
}
}
@@ -316,7 +316,46 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
acb = bdrv_aio_readv(req->dev->bs, req->out->sector, &req->qiov,
req->qiov.size / 512, virtio_blk_rw_complete, req);
if (!acb) {
virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
virtio_blk_rw_complete(req, -EIO);
}
}
typedef struct MultiReqBuffer {
BlockRequest blkreq[32];
int num_writes;
BlockDriverState *old_bs;
} MultiReqBuffer;
static void virtio_blk_handle_request(VirtIOBlockReq *req,
MultiReqBuffer *mrb)
{
if (req->elem.out_num < 1 || req->elem.in_num < 1) {
fprintf(stderr, "virtio-blk missing headers\n");
exit(1);
}
if (req->elem.out_sg[0].iov_len < sizeof(*req->out) ||
req->elem.in_sg[req->elem.in_num - 1].iov_len < sizeof(*req->in)) {
fprintf(stderr, "virtio-blk header not in correct element\n");
exit(1);
}
req->out = (void *)req->elem.out_sg[0].iov_base;
req->in = (void *)req->elem.in_sg[req->elem.in_num - 1].iov_base;
if (req->out->type & VIRTIO_BLK_T_FLUSH) {
virtio_blk_handle_flush(req);
} else if (req->out->type & VIRTIO_BLK_T_SCSI_CMD) {
virtio_blk_handle_scsi(req);
} else if (req->out->type & VIRTIO_BLK_T_OUT) {
qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
req->elem.out_num - 1);
virtio_blk_handle_write(mrb->blkreq, &mrb->num_writes,
req, &mrb->old_bs);
} else {
qemu_iovec_init_external(&req->qiov, &req->elem.in_sg[0],
req->elem.in_num - 1);
virtio_blk_handle_read(req);
}
}
@@ -324,42 +363,17 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOBlock *s = to_virtio_blk(vdev);
VirtIOBlockReq *req;
BlockRequest blkreq[32];
int num_writes = 0;
BlockDriverState *old_bs = NULL;
MultiReqBuffer mrb = {
.num_writes = 0,
.old_bs = NULL,
};
while ((req = virtio_blk_get_request(s))) {
if (req->elem.out_num < 1 || req->elem.in_num < 1) {
fprintf(stderr, "virtio-blk missing headers\n");
exit(1);
}
if (req->elem.out_sg[0].iov_len < sizeof(*req->out) ||
req->elem.in_sg[req->elem.in_num - 1].iov_len < sizeof(*req->in)) {
fprintf(stderr, "virtio-blk header not in correct element\n");
exit(1);
}
req->out = (void *)req->elem.out_sg[0].iov_base;
req->in = (void *)req->elem.in_sg[req->elem.in_num - 1].iov_base;
if (req->out->type & VIRTIO_BLK_T_FLUSH) {
virtio_blk_handle_flush(req);
} else if (req->out->type & VIRTIO_BLK_T_SCSI_CMD) {
virtio_blk_handle_scsi(req);
} else if (req->out->type & VIRTIO_BLK_T_OUT) {
qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
req->elem.out_num - 1);
virtio_blk_handle_write(blkreq, &num_writes, req, &old_bs);
} else {
qemu_iovec_init_external(&req->qiov, &req->elem.in_sg[0],
req->elem.in_num - 1);
virtio_blk_handle_read(req);
}
virtio_blk_handle_request(req, &mrb);
}
if (num_writes > 0) {
do_multiwrite(old_bs, blkreq, num_writes);
if (mrb.num_writes > 0) {
do_multiwrite(mrb.old_bs, mrb.blkreq, mrb.num_writes);
}
/*
@@ -373,6 +387,10 @@ static void virtio_blk_dma_restart_bh(void *opaque)
{
VirtIOBlock *s = opaque;
VirtIOBlockReq *req = s->rq;
MultiReqBuffer mrb = {
.num_writes = 0,
.old_bs = NULL,
};
qemu_bh_delete(s->bh);
s->bh = NULL;
@@ -380,10 +398,13 @@ static void virtio_blk_dma_restart_bh(void *opaque)
s->rq = NULL;
while (req) {
bdrv_aio_writev(req->dev->bs, req->out->sector, &req->qiov,
req->qiov.size / 512, virtio_blk_rw_complete, req);
virtio_blk_handle_request(req, &mrb);
req = req->next;
}
if (mrb.num_writes > 0) {
do_multiwrite(mrb.old_bs, mrb.blkreq, mrb.num_writes);
}
}
static void virtio_blk_dma_restart_cb(void *opaque, int running, int reason)
+9 -1
View File
@@ -384,7 +384,15 @@ static int virtio_net_has_buffers(VirtIONet *n, int bufsize)
(n->mergeable_rx_bufs &&
!virtqueue_avail_bytes(n->rx_vq, bufsize, 0))) {
virtio_queue_set_notification(n->rx_vq, 1);
return 0;
/* To avoid a race condition where the guest has made some buffers
* available after the above check but before notification was
* enabled, check for available buffers again.
*/
if (virtio_queue_empty(n->rx_vq) ||
(n->mergeable_rx_bufs &&
!virtqueue_avail_bytes(n->rx_vq, bufsize, 0)))
return 0;
}
virtio_queue_set_notification(n->rx_vq, 0);
+1 -1
View File
@@ -372,7 +372,7 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
if (PCI_COMMAND == address) {
if (!(val & PCI_COMMAND_MASTER)) {
proxy->vdev->status &= !VIRTIO_CONFIG_S_DRIVER_OK;
proxy->vdev->status &= ~VIRTIO_CONFIG_S_DRIVER_OK;
}
}
+7
View File
@@ -562,6 +562,13 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
cursor.height = y = vmsvga_fifo_read(s);
vmsvga_fifo_read(s);
cursor.bpp = vmsvga_fifo_read(s);
if (SVGA_BITMAP_SIZE(x, y) > sizeof cursor.mask ||
SVGA_PIXMAP_SIZE(x, y, cursor.bpp) > sizeof cursor.image) {
args = SVGA_BITMAP_SIZE(x, y) + SVGA_PIXMAP_SIZE(x, y, cursor.bpp);
goto badcmd;
}
for (args = 0; args < SVGA_BITMAP_SIZE(x, y); args ++)
cursor.mask[args] = vmsvga_fifo_read_raw(s);
for (args = 0; args < SVGA_PIXMAP_SIZE(x, y, cursor.bpp); args ++)
+16
View File
@@ -54,6 +54,9 @@ enum json_lexer_state {
IN_ESCAPE,
IN_ESCAPE_L,
IN_ESCAPE_LL,
IN_ESCAPE_I,
IN_ESCAPE_I6,
IN_ESCAPE_I64,
IN_ESCAPE_DONE,
IN_WHITESPACE,
IN_OPERATOR_DONE,
@@ -223,6 +226,18 @@ static const uint8_t json_lexer[][256] = {
['l'] = IN_ESCAPE_LL,
},
[IN_ESCAPE_I64] = {
['d'] = IN_ESCAPE_DONE,
},
[IN_ESCAPE_I6] = {
['4'] = IN_ESCAPE_I64,
},
[IN_ESCAPE_I] = {
['6'] = IN_ESCAPE_I6,
},
[IN_ESCAPE] = {
['d'] = IN_ESCAPE_DONE,
['i'] = IN_ESCAPE_DONE,
@@ -230,6 +245,7 @@ static const uint8_t json_lexer[][256] = {
['s'] = IN_ESCAPE_DONE,
['f'] = IN_ESCAPE_DONE,
['l'] = IN_ESCAPE_L,
['I'] = IN_ESCAPE_I,
},
/* top level rule */
+2 -1
View File
@@ -476,7 +476,8 @@ static QObject *parse_escape(JSONParserContext *ctxt, QList **tokens, va_list *a
obj = QOBJECT(qint_from_int(va_arg(*ap, int)));
} else if (token_is_escape(token, "%ld")) {
obj = QOBJECT(qint_from_int(va_arg(*ap, long)));
} else if (token_is_escape(token, "%lld")) {
} else if (token_is_escape(token, "%lld") ||
token_is_escape(token, "%I64d")) {
obj = QOBJECT(qint_from_int(va_arg(*ap, long long)));
} else if (token_is_escape(token, "%s")) {
obj = QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
+9 -7
View File
@@ -283,7 +283,6 @@ static void monitor_protocol_emitter(Monitor *mon, QObject *data)
if (!monitor_has_error(mon)) {
/* success response */
if (data) {
assert(qobject_type(data) == QTYPE_QDICT);
qobject_incref(data);
qdict_put_obj(qmp, "return", data);
} else {
@@ -335,13 +334,10 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
{
QDict *qmp;
const char *event_name;
Monitor *mon = cur_mon;
Monitor *mon;
assert(event < QEVENT_MAX);
if (!monitor_ctrl_mode(mon))
return;
switch (event) {
case QEVENT_DEBUG:
event_name = "DEBUG";
@@ -366,10 +362,16 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
qmp = qdict_new();
timestamp_put(qmp);
qdict_put(qmp, "event", qstring_from_str(event_name));
if (data)
if (data) {
qobject_incref(data);
qdict_put_obj(qmp, "data", data);
}
monitor_json_emitter(mon, QOBJECT(qmp));
QLIST_FOREACH(mon, &mon_list, entry) {
if (monitor_ctrl_mode(mon)) {
monitor_json_emitter(mon, QOBJECT(qmp));
}
}
QDECREF(qmp);
}
+37 -27
View File
@@ -96,7 +96,7 @@ int parse_host_src_port(struct sockaddr_in *haddr,
struct sockaddr_in *saddr,
const char *input_str)
{
char *str = strdup(input_str);
char *str = qemu_strdup(input_str);
char *host_str = str;
char *src_str;
const char *src_str2;
@@ -812,9 +812,6 @@ static int net_init_nic(QemuOpts *opts,
}
nd->used = 1;
if (vlan) {
nd->vlan->nb_guest_devs++;
}
nb_nics++;
return idx;
@@ -1128,20 +1125,6 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
return -1;
}
void net_client_uninit(NICInfo *nd)
{
if (nd->vlan) {
nd->vlan->nb_guest_devs--;
}
nb_nics--;
qemu_free(nd->model);
qemu_free(nd->name);
qemu_free(nd->devaddr);
nd->used = 0;
}
static int net_host_check_device(const char *device)
{
int i;
@@ -1227,16 +1210,23 @@ void net_set_boot_mask(int net_boot_mask)
void do_info_network(Monitor *mon)
{
VLANState *vlan;
VLANClientState *vc;
QTAILQ_FOREACH(vlan, &vlans, next) {
VLANClientState *vc;
monitor_printf(mon, "VLAN %d devices:\n", vlan->id);
QTAILQ_FOREACH(vc, &vlan->clients, next) {
monitor_printf(mon, " %s: %s\n", vc->name, vc->info_str);
}
}
monitor_printf(mon, "Devices not on any VLAN:\n");
QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
monitor_printf(mon, " %s: %s", vc->name, vc->info_str);
if (vc->peer) {
monitor_printf(mon, " peer=%s", vc->peer->name);
}
monitor_printf(mon, "\n");
}
}
void do_set_link(Monitor *mon, const QDict *qdict)
@@ -1253,6 +1243,7 @@ void do_set_link(Monitor *mon, const QDict *qdict)
}
}
}
vc = qemu_find_netdev(name);
done:
if (!vc) {
@@ -1289,20 +1280,41 @@ void net_cleanup(void)
}
}
static void net_check_clients(void)
void net_check_clients(void)
{
VLANState *vlan;
VLANClientState *vc;
int has_nic, has_host_dev;
QTAILQ_FOREACH(vlan, &vlans, next) {
if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
continue;
if (vlan->nb_guest_devs == 0)
QTAILQ_FOREACH(vc, &vlan->clients, next) {
switch (vc->info->type) {
case NET_CLIENT_TYPE_NIC:
has_nic = 1;
break;
case NET_CLIENT_TYPE_SLIRP:
case NET_CLIENT_TYPE_TAP:
case NET_CLIENT_TYPE_SOCKET:
case NET_CLIENT_TYPE_VDE:
has_host_dev = 1;
break;
default: ;
}
}
if (has_host_dev && !has_nic)
fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
if (vlan->nb_host_devs == 0)
if (has_nic && !has_host_dev)
fprintf(stderr,
"Warning: vlan %d is not connected to host network\n",
vlan->id);
}
QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
if (!vc->peer) {
fprintf(stderr, "Warning: %s %s has no peer\n",
vc->info->type == NET_CLIENT_TYPE_NIC ? "nic" : "netdev",
vc->name);
}
}
}
static int net_init_client(QemuOpts *opts, void *dummy)
@@ -1337,8 +1349,6 @@ int net_init_clients(void)
return -1;
}
net_check_clients();
return 0;
}
+1 -2
View File
@@ -76,7 +76,6 @@ struct VLANState {
int id;
QTAILQ_HEAD(, VLANClientState) clients;
QTAILQ_ENTRY(VLANState) next;
unsigned int nb_guest_devs, nb_host_devs;
NetQueue *send_queue;
};
@@ -160,9 +159,9 @@ extern const char *legacy_tftp_prefix;
extern const char *legacy_bootp_filename;
int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev);
void net_client_uninit(NICInfo *nd);
int net_client_parse(QemuOptsList *opts_list, const char *str);
int net_init_clients(void);
void net_check_clients(void);
void net_cleanup(void);
void net_set_boot_mask(int boot_mask);
void net_host_device_add(Monitor *mon, const QDict *qdict);
-4
View File
@@ -728,10 +728,6 @@ int net_init_slirp(QemuOpts *opts,
qemu_free(config);
}
if (ret != -1 && vlan) {
vlan->nb_host_devs++;
}
qemu_free(vnet);
return ret;
-4
View File
@@ -569,9 +569,5 @@ int net_init_socket(QemuOpts *opts,
return -1;
}
if (vlan) {
vlan->nb_host_devs++;
}
return 0;
}
-4
View File
@@ -714,10 +714,6 @@ int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan
return -1;
}
if (vlan) {
vlan->nb_host_devs++;
}
return 0;
}
-4
View File
@@ -441,9 +441,5 @@ int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan
}
}
if (vlan) {
vlan->nb_host_devs++;
}
return 0;
}
-4
View File
@@ -127,9 +127,5 @@ int net_init_vde(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan
return -1;
}
if (vlan) {
vlan->nb_host_devs++;
}
return 0;
}
+1 -1
View File
@@ -306,7 +306,7 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
#ifdef CONFIG_ACCEPT4
ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
if (ret != -1 || errno != EINVAL) {
if (ret != -1 || errno != ENOSYS) {
return ret;
}
#endif
+2 -1
View File
@@ -1,4 +1,5 @@
- The PC BIOS comes from the Bochs project (http://bochs.sourceforge.net/).
- SeaBIOS (bios.bin) is the successor of pc bios.
See http://www.seabios.org/ for more information.
- The VGA BIOS and the Cirrus VGA BIOS come from the LGPL VGA bios
project (http://www.nongnu.org/vgabios/).
BIN
View File
Binary file not shown.
+3 -2
View File
@@ -86,9 +86,10 @@ copy_kernel:
/* Now create the GDT descriptor */
movw $((3 * 8) - 1), -16(%bp)
mov %cs, %eax
movzwl %ax, %eax
shl $4, %eax
addl $gdt, %ebx
movl %ebx, -14(%bp)
addl $gdt, %eax
movl %eax, -14(%bp)
/* And load the GDT */
data32 lgdt -16(%bp)
+3
View File
@@ -1180,6 +1180,9 @@ static CharDriverState *qemu_chr_open_tty(QemuOpts *opts)
int fd;
TFR(fd = open(filename, O_RDWR | O_NONBLOCK));
if (fd < 0) {
return NULL;
}
tty_serial_init(fd, 115200, 'N', 8, 1);
chr = qemu_chr_open_fd(fd, fd);
if (!chr) {
+2 -1
View File
@@ -2,6 +2,8 @@
#ifndef QEMU_COMMON_H
#define QEMU_COMMON_H
#include "config-host.h"
#define QEMU_NORETURN __attribute__ ((__noreturn__))
#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT
#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
@@ -29,7 +31,6 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <assert.h>
#include "config-host.h"
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
+1 -1
View File
@@ -467,7 +467,7 @@ int main(int argc, char **argv)
}
}
} while (persistent || nb_fds > 1);
qemu_free(data);
qemu_vfree(data);
close(sharing_fds[0]);
bdrv_close(bs);
+22 -5
View File
@@ -404,6 +404,12 @@ ETEXI
DEF("device", HAS_ARG, QEMU_OPTION_device,
"-device driver[,options] add device\n")
STEXI
@item -device @var{driver}[,@var{option}[,...]]
Add device @var{driver}. Depending on the device type,
@var{option} (typically @var{key}=@var{value}) may be useful.
ETEXI
DEF("name", HAS_ARG, QEMU_OPTION_name,
"-name string1[,process=string2] set the name of the guest\n"
" string1 sets the window title and string2 the process name (on Linux)\n")
@@ -1893,6 +1899,8 @@ ETEXI
DEF("nodefaults", 0, QEMU_OPTION_nodefaults, \
"-nodefaults don't create default devices.\n")
STEXI
@item -nodefaults
Don't create default devices.
ETEXI
#ifndef _WIN32
@@ -1915,10 +1923,6 @@ Immediately before starting guest execution, drop root privileges, switching
to the specified user.
ETEXI
STEXI
@end table
ETEXI
#if defined(TARGET_SPARC) || defined(TARGET_PPC)
DEF("prom-env", HAS_ARG, QEMU_OPTION_prom_env,
"-prom-env variable=value\n"
@@ -1934,6 +1938,19 @@ DEF("old-param", 0, QEMU_OPTION_old_param,
#endif
DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig,
"-readconfig <file>\n")
STEXI
@item -readconfig @var{file}
Read device configuration from @var{file}.
ETEXI
DEF("writeconfig", HAS_ARG, QEMU_OPTION_writeconfig,
"-writeconfig <file>\n"
" read/write config file")
" read/write config file\n")
STEXI
@item -writeconfig @var{file}
Write device configuration to @var{file}.
ETEXI
HXCOMM This is the last statement. Insert new options before this line!
STEXI
@end table
ETEXI
+4 -4
View File
@@ -424,7 +424,7 @@ static int inet_parse(QemuOpts *opts, const char *str)
__FUNCTION__, str);
return -1;
}
qemu_opt_set(opts, "ipv6", "yes");
qemu_opt_set(opts, "ipv6", "on");
} else if (qemu_isdigit(str[0])) {
/* IPv4 addr */
if (2 != sscanf(str,"%64[0-9.]:%32[^,]%n",addr,port,&pos)) {
@@ -432,7 +432,7 @@ static int inet_parse(QemuOpts *opts, const char *str)
__FUNCTION__, str);
return -1;
}
qemu_opt_set(opts, "ipv4", "yes");
qemu_opt_set(opts, "ipv4", "on");
} else {
/* hostname */
if (2 != sscanf(str,"%64[^:]:%32[^,]%n",addr,port,&pos)) {
@@ -450,9 +450,9 @@ static int inet_parse(QemuOpts *opts, const char *str)
if (h)
qemu_opt_set(opts, "to", h+4);
if (strstr(optstr, ",ipv4"))
qemu_opt_set(opts, "ipv4", "yes");
qemu_opt_set(opts, "ipv4", "on");
if (strstr(optstr, ",ipv6"))
qemu_opt_set(opts, "ipv6", "yes");
qemu_opt_set(opts, "ipv6", "on");
return 0;
}
+1 -1
View File
@@ -1696,7 +1696,7 @@ void do_savevm(Monitor *mon, const QDict *qdict)
sn->vm_clock_nsec = qemu_get_clock(vm_clock);
/* Delete old snapshots of the same name */
if (del_existing_snapshots(mon, name) < 0) {
if (name && del_existing_snapshots(mon, name) < 0) {
goto the_end;
}
+1
View File
@@ -525,6 +525,7 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state
static void toggle_full_screen(DisplayState *ds)
{
gui_fullscreen = !gui_fullscreen;
do_sdl_resize(real_screen->w, real_screen->h, real_screen->format->BitsPerPixel);
if (gui_fullscreen) {
scaling_active = 0;
gui_saved_grab = gui_grab;
+1 -1
View File
@@ -179,7 +179,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
close(s);
i = 0;
bptr = strdup(ex); /* No need to free() this */
bptr = qemu_strdup(ex); /* No need to free() this */
if (do_pty == 1) {
/* Setup "slirp.telnetd -x" */
argv[i++] = "slirp.telnetd";
+24
View File
@@ -264,6 +264,12 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
size_t prefix_len;
char *req_fname;
/* check if a session already exists and if so terminate it */
s = tftp_session_find(slirp, tp);
if (s >= 0) {
tftp_session_terminate(&slirp->tftp_sessions[s]);
}
s = tftp_session_allocate(slirp, tp);
if (s < 0) {
@@ -362,6 +368,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
}
tftp_send_oack(spt, "tsize", tsize, tp);
return;
}
}
@@ -385,6 +392,19 @@ static void tftp_handle_ack(Slirp *slirp, struct tftp_t *tp, int pktlen)
}
}
static void tftp_handle_error(Slirp *slirp, struct tftp_t *tp, int pktlen)
{
int s;
s = tftp_session_find(slirp, tp);
if (s < 0) {
return;
}
tftp_session_terminate(&slirp->tftp_sessions[s]);
}
void tftp_input(struct mbuf *m)
{
struct tftp_t *tp = (struct tftp_t *)m->m_data;
@@ -397,5 +417,9 @@ void tftp_input(struct mbuf *m)
case TFTP_ACK:
tftp_handle_ack(m->slirp, tp, m->m_len);
break;
case TFTP_ERROR:
tftp_handle_error(m->slirp, tp, m->m_len);
break;
}
}
+2 -2
View File
@@ -46,10 +46,10 @@ uint64_t helper_load_fpcr (void)
{
uint64_t ret = 0;
#ifdef CONFIG_SOFTFLOAT
ret |= env->fp_status.float_exception_flags << 52;
ret |= (uint64_t)env->fp_status.float_exception_flags << 52;
if (env->fp_status.float_exception_flags)
ret |= 1ULL << 63;
env->ipr[IPR_EXC_SUM] &= ~0x3E:
env->ipr[IPR_EXC_SUM] &= ~0x3E;
env->ipr[IPR_EXC_SUM] |= env->fp_status.float_exception_flags << 1;
#endif
switch (env->fp_status.float_rounding_mode) {
+2
View File
@@ -617,6 +617,8 @@ void cpu_reset(CPUX86State *env)
env->dr[7] = DR7_FIXED_1;
cpu_breakpoint_remove_all(env, BP_CPU);
cpu_watchpoint_remove_all(env, BP_CPU);
env->mcg_status = 0;
}
void cpu_x86_close(CPUX86State *env)
+1
View File
@@ -227,6 +227,7 @@ int kvm_arch_init_vcpu(CPUState *env)
void kvm_arch_reset_vcpu(CPUState *env)
{
env->exception_injected = -1;
env->interrupt_injected = -1;
env->nmi_injected = 0;
env->nmi_pending = 0;
+2
View File
@@ -6259,6 +6259,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
tval += next_eip;
if (s->dflag == 0)
tval &= 0xffff;
else if(!CODE64(s))
tval &= 0xffffffff;
gen_movtl_T0_im(next_eip);
gen_push_T0(s);
gen_jmp(s, tval);
+2 -2
View File
@@ -590,8 +590,8 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
#define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault
void do_interrupt (CPUState *env);
void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra);
target_phys_addr_t do_translate_address (CPUState *env, target_ulong address,
int rw);
target_phys_addr_t cpu_mips_translate_address (CPUState *env, target_ulong address,
int rw);
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
{
+4 -4
View File
@@ -311,7 +311,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
}
#if !defined(CONFIG_USER_ONLY)
target_phys_addr_t do_translate_address(CPUState *env, target_ulong address, int rw)
target_phys_addr_t cpu_mips_translate_address(CPUState *env, target_ulong address, int rw)
{
target_phys_addr_t physical;
int prot;
@@ -326,10 +326,10 @@ target_phys_addr_t do_translate_address(CPUState *env, target_ulong address, int
address, rw, access_type);
if (ret != TLBRET_MATCH) {
raise_mmu_exception(env, address, rw, ret);
cpu_loop_exit();
return -1LL;
} else {
return physical;
}
return physical;
}
#endif
+16 -2
View File
@@ -276,10 +276,24 @@ void helper_dmultu (target_ulong arg1, target_ulong arg2)
#endif
#ifndef CONFIG_USER_ONLY
static inline target_phys_addr_t do_translate_address(target_ulong address, int rw)
{
target_phys_addr_t lladdr;
lladdr = cpu_mips_translate_address(env, address, rw);
if (lladdr == -1LL) {
cpu_loop_exit();
} else {
return lladdr;
}
}
#define HELPER_LD_ATOMIC(name, insn) \
target_ulong helper_##name(target_ulong arg, int mem_idx) \
{ \
env->lladdr = do_translate_address(env, arg, 0); \
env->lladdr = do_translate_address(arg, 0); \
env->llval = do_##insn(arg, mem_idx); \
return env->llval; \
}
@@ -298,7 +312,7 @@ target_ulong helper_##name(target_ulong arg1, target_ulong arg2, int mem_idx) \
env->CP0_BadVAddr = arg2; \
helper_raise_exception(EXCP_AdES); \
} \
if (do_translate_address(env, arg2, 1) == env->lladdr) { \
if (do_translate_address(arg2, 1) == env->lladdr) { \
tmp = do_##ld_insn(arg2, mem_idx); \
if (tmp == env->llval) { \
do_##st_insn(arg2, arg1, mem_idx); \
+5 -1
View File
@@ -821,7 +821,7 @@ static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv
static inline void check_cp0_enabled(DisasContext *ctx)
{
if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
generate_exception_err(ctx, EXCP_CpU, 1);
generate_exception_err(ctx, EXCP_CpU, 0);
}
static inline void check_cp1_enabled(DisasContext *ctx)
@@ -1451,6 +1451,8 @@ static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
tcg_gen_rotri_i32(t1, t1, uimm);
tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
tcg_temp_free_i32(t1);
} else {
tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
}
opn = "rotr";
} else {
@@ -1489,6 +1491,8 @@ static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
if (env->insn_flags & ISA_MIPS32R2) {
if (uimm != 0) {
tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
} else {
tcg_gen_mov_tl(cpu_gpr[rt], t0);
}
opn = "drotr";
} else {
+2 -2
View File
@@ -731,9 +731,9 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
/* label1: fast path */
reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
tcg_out_opc_imm(s, OPC_LW, TCG_REG_V0, TCG_REG_A0,
tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
offsetof(CPUState, tlb_table[mem_index][0].addend) + addr_meml);
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
addr_reg1 = TCG_REG_V0;
#endif
+1 -1
View File
@@ -1036,7 +1036,7 @@ USBDevice *usb_host_device_open(const char *devname)
qdev_prop_set_uint32(&dev->qdev, "hostaddr", filter.addr);
qdev_prop_set_uint32(&dev->qdev, "vendorid", filter.vendor_id);
qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id);
qdev_init(&dev->qdev);
qdev_init_nofail(&dev->qdev);
return dev;
fail:
+23 -9
View File
@@ -2689,17 +2689,28 @@ static int usb_device_del(const char *devname)
static int usb_parse(const char *cmdline)
{
return usb_device_add(cmdline, 0);
int r;
r = usb_device_add(cmdline, 0);
if (r < 0) {
fprintf(stderr, "qemu: could not add USB device '%s'\n", cmdline);
}
return r;
}
void do_usb_add(Monitor *mon, const QDict *qdict)
{
usb_device_add(qdict_get_str(qdict, "devname"), 1);
const char *devname = qdict_get_str(qdict, "devname");
if (usb_device_add(devname, 1) < 0) {
qemu_error("could not add USB device '%s'\n", devname);
}
}
void do_usb_del(Monitor *mon, const QDict *qdict)
{
usb_device_del(qdict_get_str(qdict, "devname"));
const char *devname = qdict_get_str(qdict, "devname");
if (usb_device_del(devname) < 0) {
qemu_error("could not delete USB device '%s'\n", devname);
}
}
/***********************************************************/
@@ -3473,10 +3484,10 @@ void qemu_init_vcpu(void *_env)
{
CPUState *env = _env;
if (kvm_enabled())
kvm_init_vcpu(env);
env->nr_cores = smp_cores;
env->nr_threads = smp_threads;
if (kvm_enabled())
kvm_init_vcpu(env);
return;
}
@@ -3802,12 +3813,12 @@ void qemu_init_vcpu(void *_env)
{
CPUState *env = _env;
env->nr_cores = smp_cores;
env->nr_threads = smp_threads;
if (kvm_enabled())
kvm_start_vcpu(env);
else
tcg_init_vcpu(env);
env->nr_cores = smp_cores;
env->nr_threads = smp_threads;
}
void qemu_notify_event(void)
@@ -4031,14 +4042,15 @@ static void tcg_cpu_exec(void)
for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) {
CPUState *env = cur_cpu = next_cpu;
if (!vm_running)
break;
if (timer_alarm_pending) {
timer_alarm_pending = 0;
break;
}
if (cpu_can_run(env))
ret = qemu_cpu_exec(env);
else if (env->stop)
break;
if (ret == EXCP_DEBUG) {
gdb_set_stop_cpu(env);
debug_requested = 1;
@@ -5957,6 +5969,8 @@ int main(int argc, char **argv, char **envp)
if (qemu_opts_foreach(&qemu_device_opts, device_init_func, NULL, 1) != 0)
exit(1);
net_check_clients();
if (!display_state)
dumb_display_init();
/* just use the first displaystate for the moment */
+8 -2
View File
@@ -2293,7 +2293,7 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
static void vnc_refresh(void *opaque)
{
VncDisplay *vd = opaque;
VncState *vs = NULL;
VncState *vs = NULL, *vn = NULL;
int has_dirty = 0, rects = 0;
vga_hw_update();
@@ -2302,9 +2302,15 @@ static void vnc_refresh(void *opaque)
vs = vd->clients;
while (vs != NULL) {
vn = vs->next;
rects += vnc_update_client(vs, has_dirty);
vs = vs->next;
/* vs might be free()ed here */
vs = vn;
}
/* vd->timer could be NULL now if the last client disconnected,
* in this case don't update the timer */
if (vd->timer == NULL)
return;
if (has_dirty && rects) {
vd->timer_interval /= 2;
+2
View File
@@ -165,6 +165,8 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
}
/* A SubrectsColoured subtile invalidates the foreground color */
*has_fg = 0;
if (n_data > (w * h * sizeof(pixel_t))) {
n_colors = 4;
flags = 0x01;