Compare commits

...

156 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
Anthony Liguori
6c412ddf1c Update for 0.12.0 release
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-19 08:26:29 -06:00
Anthony Liguori
862ad4be53 Update to SeaBIOS 0.5.0
The only change is updating the makefile but that way we're carrying an official
release.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit eac1bb74be4d95616b8a6217e020b1b0d6918608)
2009-12-19 08:26:28 -06:00
Anthony Liguori
aac2ad563a Revert "monitor: Convert do_migrate_set_speed() to QObject"
This reverts commit 3a4921047d.

From Luiz:

  do_migrate_set_speed() accepts a suffix for the 'value' argument and this is
  not good for QMP.  We will have to add a new argument type to handle that and
  this will have to wait for 0.13.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 46ee2295678af629a2869e4e331e4e002bcc31fd)
2009-12-19 08:26:28 -06:00
Anthony Liguori
eb41f58a4e e1000: Don't muck with PCI commmand register
Otherwise, the driver does not work in Linux after the INT_DISABLE changes in
PCI.

Michael Tsirkin had a patch to do this, I'm not sure what happened to it.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 17a7a5c59c4d72dd1d5666f348b010be6b10163c)
2009-12-19 08:26:28 -06:00
Luiz Capitulino
5543b41167 monitor: do_balloon(): Use 'M' argument type
This makes do_balloon() accept megabyte values from the user
Monitor while accepting byte values for QMP.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 056001ab30b1e596b992e70f9cb2adacef9c0ad0)
2009-12-19 08:26:28 -06:00
Luiz Capitulino
31d85f6a6b monitor: Introduce 'M' argument type
This is a target long value in megabytes which should be
converted to bytes.

It will be used by handlers which accept a megabyte value
when in "user mode".

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 7cfe34fe4e3b518485c15aa9a78b4cf9cbd11a4d)
2009-12-19 08:26:28 -06:00
Luiz Capitulino
9c49a2533c QMP: Update spec file
- Remove "draft" status
- Change default success response to be json-object
- Change error and event data member to be a json-object
- Update examples
- Add new section "Compatibility Considerations"
- Other fixes and clarifications

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 58341bcd112cf11c6266cabe36921572fa4b019d)
2009-12-19 08:26:28 -06:00
Luiz Capitulino
c6faf5fd73 QMP: Update README file
- Fix output description
- Fix command-line usage notes
- Minor improvements

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d683cfb1a94aa61ace4ce7ce824f1e087b37b851)
2009-12-19 08:26:27 -06:00
Luiz Capitulino
069def25cb QMP: Assure that returned data is a QDict
This is for debug purposes only.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 19863875a2e18fc868a7b830f16fa76d32518bd1)
2009-12-19 08:26:27 -06:00
Luiz Capitulino
3733a1e804 QMP: Return an empty dict by default
Currently, when a regular command doesn't have any data to output,
QMP will emit:

{ "return": "OK" }

Returning an empty dict is better though, because dicts can support
some protocol changes in a compatible way.

So, with this commit we will return:

{ "return": {} }

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit e38fb11b5099db8de8d60d536d4a01610ee4c08b)
2009-12-19 08:26:27 -06:00
Luiz Capitulino
5b06a3f785 QMP: Only handle converted commands
Looks like I dropped this check when addressing the 'query-'
commands request.

QMP should only handle converted commands, obviously.

Reported-by: Markus Armbruster <armbru@redhat.com>

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 89f5461fc9a3c437e632f6895dc605e8f03b925e)
2009-12-19 08:26:27 -06:00
Anthony Liguori
baaf73aaac Update SeaBIOS to include PCI based option rom loading
Also remove pcbios from the tree.  It will no longer work.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2dc3f77c86)
2009-12-19 08:26:27 -06:00
Gerd Hoffmann
345c22aa80 roms: remove option rom packing logic
Now that we load the option roms via fw_cfg, we can stop copying
them to the 0xc000 -> 0xe000.  The patch does just that.

Also the rom loader gets simplified as all remaining users of the
rom loader load the bits at a fixed address so the packing and
aligning logic can go away.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 632cf034b4)
2009-12-19 08:26:26 -06:00
Gerd Hoffmann
26bb2a0865 roms: use new fw_cfg file xfer support.
roms: use fw_cfg for vgabios and option rom loading, additionally to
deploying them the traditional way (copy to 0xc0000 -> 0xe0000 range).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 379526a40e)
2009-12-19 08:26:25 -06:00
Gerd Hoffmann
e6ea832410 fw_cfg: add API for file transfer.
This patch adds a file transfer interface to fw_cfg.  Intended to be
used for passing non-pci option roms and vgabios to seabios.  Namespace
is modeled after the existing cbfs filesystem support in seabios.

Reading the new FW_CFG_FILE_DIR entry returns a file list.
Fields there are in network byte order (aka bigendian).

aliguori: fix fw_cfg.h for multiboot.bin, add proper fw_cfg.h declarations,
          quiet fprintf() in fw_cfg.c

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit abe147e0ce)
2009-12-19 08:26:25 -06:00
Gerd Hoffmann
22d0cc8d38 fw_cfg: make calls typesafe
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit c2b5bda43a)
2009-12-19 08:26:25 -06:00
Gerd Hoffmann
898829d5c7 pci romfiles: add property, add default to PCIDeviceInfo
This patch adds a romfile property to the pci bus.  It allows to specify
a romfile to load into the rom bar of the pci device.  The default value
comes from a new field in PCIDeviceInfo.  The property allows to change
the file and also to disable the rom loading using an empty string.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 8c52c8f320)
2009-12-19 08:26:24 -06:00
Anthony Liguori
72bb3c7571 Support PCI based option rom loading
Currently, we preload option roms into the option rom space in memory.  This
prevents DDIM from functioning correctly which severely limits the number
of roms we can support.

This patch introduces a pci_add_option_rom() which registers the
PCI_ROM_ADDRESS bar which points to our option rom.  It also converts over
the cirrus vga adapter, the rtl8139, virtio, and the e1000 to use this
new mechanism.

The result is that PXE boot functions even with three unique types of cards.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit c2039bd0ff)
2009-12-19 08:26:24 -06:00
Daniel P. Berrange
48c437f0ab Fix backcompat for hotplug of SCSI controllers
SCSI controllers have no trouble existing without any attached
disks. This could be achieved with the (legacy) monitor syntax

  pci_add pci_addr=auto storage if=scsi

This is now denied with

  scsi requires a backing file/device.
  failed to add if=scsi

There is no need for this denial and it breaks compatability
with existing QEMU usage, so remove the check for presence
of a drive.

  Signed-off-by: Daniel P. Berrange <berrange@redhat.com>

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit ec7efac4a9)
2009-12-19 08:26:24 -06:00
Juan Quintela
07d00c2174 fdc: fix migration from 0.11
0.11 uses as instance ide io_base, get it back

Signed-off-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 47f5ba7248)
2009-12-19 08:26:24 -06:00
Juan Quintela
3243a06f51 Revert "fdc: fix vmstate variable passed"
Floppy used the io_base address to register savevm region.

This reverts commit 2966b390d0.

Signed-off-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit aef30c3c6a)
2009-12-19 08:26:24 -06:00
Jan Kiszka
1c3f96be38 monitor: Accept input only byte-wise
This allows to suspend command interpretation and execution
synchronously, e.g. during migration.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit c62313bbdc)
2009-12-19 08:26:24 -06:00
Anthony Liguori
df9e7219db Revert "kvm: x86: Save/restore exception_index"
This reverts commit ebbc8a3d8e.

As suggested by Jan Kiszka,

  "It was obsoleted by d1793b836f8f123b961c613de1bb1c0c185c84cc and now
   saves/restores a useless field."

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit acb6685fea)
2009-12-19 08:26:24 -06:00
Dave Airlie
e83421f511 vmware: increase cursor buffer size.
The cursor pixmap size we calculate later ends up being 4096 dwords
long by the looks of it. This boots an F12 LiveCD now.

Signed-off-by: Dave Airlie <airlied@linux.ie>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 8095cb3ed2)
2009-12-19 08:26:24 -06:00
Anthony Liguori
2b311b3cce VMware VGA: Only enable dirty log tracking when fifo is disabled
This patch enables dirty log tracking whenever it's needed and disables it
when it is not.

We unconditionally enable dirty log tracking on reset, restart dirty log
tracking when PCI IO regions are remapped, and disable/enable it based on
commands from the guest.

Rebased-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit b5cc6e32ba)
2009-12-19 08:26:23 -06:00
Anthony Liguori
4b5db3749c Fix VMware VGA depth computation
VMware VGA requires that the depth presented to the guest is the same as the
DisplaySurface that it renders to.  This is because it performs a very simple
memcpy() to blit from one surface to another.

We currently hardcode a 24-bit depth.  The surface allocator for SDL may, and
usually will, allocate a surface with a different depth causing screen
corruption.

This changes the code to allocate the DisplaySurface before initializing the
device which allows the depth of the DisplaySurface to be used instead of
hardcoding something.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit a6109ff1b5)
2009-12-19 08:26:23 -06:00
Anthony Liguori
a1497a782c Make sure to enable dirty log tracking for VMware VGA
This is needed for VMware VGA to work properly under KVM.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit ee3e41a9a0)
2009-12-19 08:26:23 -06:00
Anthony Liguori
3c547d7bb7 Make sure to enable dirty tracking of VBE vram mapping
Apparently, VBE maps the VGA vram to a fixed physical location.  KVM requires
that all mappings of the VGA vram have dirty tracking enabled on them.  Any
access to the VGA vram through the VBE mapping currently fails to result in
dirty page tracking updates causing a black screen.

This is the true root cause of VMware VGA not working correctly under KVM and
likely also an issue with some of the std-vga black screen issues too.

Cirrus does not enable VBE so it would not be a problem when using Cirrus.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Rebased-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit f0138a63a4)
2009-12-19 08:26:23 -06:00
Dave Airlie
3b43502e3a vmware: setup PCI BAR 2 for FIFO as per vmware spec
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f351d050dc)
2009-12-19 08:26:23 -06:00
Gerd Hoffmann
078517421f qdev: improve property error reporting.
Add a error message in case we fail to parse a qdev property.

Also make qemu not abort() in case setting a global property can't be
set.  This used to be a clear programming error.  The introduction of
the -global switch changed that though, so better exit instead (after
printing the new error message).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 9ef5c4bf81)
2009-12-19 08:26:22 -06:00
Gerd Hoffmann
afc7055619 fix vga names in default_list
Fix mismerge between 64465297 and 556cd098.

Cc: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 69fd02eea6)
2009-12-19 08:26:22 -06:00
Gerd Hoffmann
53425683d4 usb-host: check mon before using it.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit eba6fe8732)
2009-12-19 08:26:22 -06:00
Gerd Hoffmann
ef5a63186a usb-net: use qdev for -usbdevice
Rebased to master, adapted to device renaming by armbru,
no other changes.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 42be86ce95)
2009-12-19 08:26:22 -06:00
Gerd Hoffmann
4a0e0accd7 Check rom_load_all() return value.
Check rom_load_all() return value.
Also don't make option rom loading failure fatal.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 15ff770544)
2009-12-19 08:26:22 -06:00
Gerd Hoffmann
73e47683de defaults: update device_list[]
Add isa-fdc (disables default_floppy).
Add ide-drive (disables default_cdrom).

Also walk the -global QemuOpts, so we'll catch
-global isa-fdc.drive{A,B}=<name> too.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d8bcbabf26)
2009-12-19 08:26:21 -06:00
Gerd Hoffmann
115e94a31e defaults: split default_drive
Split default_drive into default_{floppy,cdrom,sdcard}.
Also add QEMUMachine flags to disable them per machine.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit ac33f8fad1)
2009-12-19 08:26:21 -06:00
Luiz Capitulino
5fd5f6999d monitor: Catch printing to non-existent monitor
The monitor_vprintf() function now touches the 'mon' pointer
before calling monitor_puts(), this causes block migration
to segfault as its functions call monitor_printf() with a
NULL 'mon'.

To fix the problem this commit moves the 'mon' NULL check
from monitor_puts() to monitor_vprintf().

This can potentially hide bugs, but for some reason this has
been the behavior for a long time.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2daa119126)
2009-12-19 08:26:21 -06:00
Luiz Capitulino
602e97b725 monitor: Avoid readline functions in QMP
The monitor_read_command() function is readline specific
and should only be used when readline is available.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 183e6e5257)
2009-12-19 08:26:21 -06:00
Luiz Capitulino
97b766dfcd monitor: do_balloon(): Check for errors
do_balloon() should check for ballooning availability as
do_info_balloon() does.

Noted by Daniel P. Berrange <berrange@redhat.com>.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit cfdf2c4057)
2009-12-19 08:26:21 -06:00
Luiz Capitulino
fb8cf78db6 monitor: Use 'device' in eject
Monitor's eject command uses 'filename' for the device name
argument, but 'device' is a better name.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 78d714e08f)
2009-12-19 08:26:21 -06:00
Luiz Capitulino
c5238ac21b QDict: Fix size update
Key replacement should not update the dictionary's size.

This commit also adds a test for the bug.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 29ec3156ee)
2009-12-19 08:26:21 -06:00
Markus Armbruster
99917a99cd qdev: Improve uni-north device names
Switch to the names suggested by Blue Swirl.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 18dd19a7d9)
2009-12-19 08:26:21 -06:00
Daniel P. Berrange
55ed56908f Avoid permanently disabled QEMU monitor when UNIX migration fails
If a UNIX migration command is attempt to a UNIX socket which does
not exist, then the monitor is suspended, but never resumed. This
prevents any further use of the monitor

* migration-unix.c: Only call migrate_fd_monitor_suspend() once
  connected to the UNIX socket.

   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2dd650e58a)
2009-12-19 08:26:20 -06:00
Kevin Wolf
139e310025 Fix loading of ELF multiboot kernels
The multiboot implementation assumed that there is only one program header
(which contains the entry point) and that the entry point is at the start of
the code. This doesn't hold true generally and caused too little data to be
loaded.

Fix the loading code to pass the whole loaded data to the Multiboot Option ROM.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 092493be3c)
2009-12-19 08:26:20 -06:00
Kevin Wolf
bed93b1dcb Revert "Rename DriveInfo.onerror to on_write_error" (fix mismerge)
Part of the first patch of the -drive rerror series has been merged once more
on top of the rest of the series. This effectively disables the rerror option
and always goes with the default value. Reverting the commit re-enables the
option.

This reverts commit fc072ec4df.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 75f1247539)
2009-12-19 08:26:20 -06:00
Kevin Wolf
73b4ac5cd8 qemu-io: Fix memory leak
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 40a0d7c395)
2009-12-19 08:26:20 -06:00
Paolo Bonzini
00e8277b83 Fix thinko in linuxboot.S
The %gs segment that was used was not matching the comments.
I just moved the GDT descriptor on the stack instead.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 36ecd7c016)
2009-12-19 08:26:20 -06:00
Jan Kiszka
a8ea3a357b target-i386: Fix evaluation of DR7 register
hw_breakpoint_type and hw_breakpoint_len used the wrong index multiplier
to extract type and len.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d46272c774)
2009-12-19 08:26:20 -06:00
Jan Kiszka
f8051485c1 kvm: x86: Use separate exception_injected CPUState field
Marcelo correctly remarked that there are usage conflicts between QEMU
core code and KVM /wrt exception_index. So spend a separate field and
also save/restore it properly.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 31827373f0)
2009-12-19 08:26:20 -06:00
Anthony Liguori
807c80b259 vnc: hextile: do not generate ForegroundSpecified and SubrectsColoured tiles
This violates the RFB specification (section 6.6.4).  It happens to work with
most clients but it's still wrong.

Reported-by: Yaniv Kaul <ykaul@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 02c2b87fff)
2009-12-19 08:26:20 -06:00
Anthony Liguori
686a3c3dc2 Revert "pci: interrupt disable bit support"
This reverts commit 0ea5709a32.

Per discussion with Michael Tsirkin, this is too risky for 0.12

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d587e07871)
2009-12-19 08:26:19 -06:00
Alexander Graf
a381d8277c target-ppc: fix ppc32 kvm build
My segment sync patch broke compilation on PPC32, because it was trying to
sync the SLB even though ppc32 CPUs don't have an SLB.

So let's only sync it when we're on a PP64 one!

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 82c09f2f0d)
2009-12-19 09:30:40 +01:00
Alexander Graf
8647b09bfd S390: Bail out without KVM
Currently only the S390 KVM target works. To keep users from accidently not
using KVM, let's not even initialize the machine when KVM is not used.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit e249651ca9)
2009-12-18 16:39:40 +01:00
Alexander Graf
9153014fa0 S390: Don't tell guest we're updating config space
Currently we always set the "config space changed" bit to 1 when triggering
any virtio interrupt. While that worked in 2.6.27, newer kernels interpret
that value as "only the config space changed and nothing else happened".

Since we usually trigger interrupts to tell the guest that something did
happen, we just not tell it the config space changed for now until we
implement the correct callback for that.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 86f3dba651)
2009-12-18 16:36:39 +01:00
Alexander Graf
f6d4446ea8 add default virtcon initialization
When going through the default devices, we don't initialize the virtio
console, unless we're doing -nographic.

I suppose that's just a leftover from the recent code restructuring, so
let's put it in.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 38536da1e3)
2009-12-18 16:36:39 +01:00
Alexander Graf
f1e247ee6b S390: Loop through virtio console devices
We used to always create one single virtio console device. This breaks when
either zero of multiple virtio console devices are requested, so let's use
the same code as on x86.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit a1e4b07f04)
2009-12-18 16:36:38 +01:00
Alexander Graf
a49668769d target-s390: Fail on unknown instructions
We were being a bit too nice and didn't give the guest an invalid instruction
interrupt.

While that works, it's not exactly the fastest thing to do, since now the
guest doesn't know that we're not really implementing that instruction, so it
continues doing it.

We run into this with the set_page_unstable hint instruction. So let's bail out
in these cases.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit d7963c43b9)
2009-12-18 16:36:37 +01:00
Andre Przywara
97d949d9da osdep: Fix runtime failure on older Linux kernels
If QEMU finds newer kernel header files on compilation time, it will use
advertised features like pipe2 or SOCK_CLOEXEC by just doing a compile test.
If later the executables are executed on an older kernel (<2.6.27,
like Xen Dom0 2.6.18), then QEMU will fail on opening sockets and creating
pipes and returns the rather unspecific "qemu_init_main_loop failed".
This patch fixes this by checking the return values of these calls
for EINVAL and ENOSYS and falling back to the older versions automatically.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2009-12-18 16:30:45 +01:00
Juergen Lock
040093b1a5 Fix a make -j race
Make libuser.a depend on $(GENERATED_HEADERS) too so make -j won't start
building it before the headers exist.  (There may be more bugs like this
but at least this makes (g)make -j4 started from scratch on a quadcore
now always complete here again.)

Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit c1bb0dcef2)
2009-12-17 18:27:27 +01:00
Richard Henderson
5d4e53dc81 target-alpha: Fix generic ctz64.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 06445248d2)
2009-12-17 18:24:59 +01:00
Stefan Weil
3ebee80226 s390: Fix buggy assignment
nd->model keeps dynamically allocated model names.
So casting of a constant string is wrong here.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 5a2b3fc5aa)
2009-12-16 18:25:30 +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
Nathan Froyd
869ca150e7 target-mips: fix user-mode emulation startup
Running programs with the MIPS user-mode emulator fails during dynamic
loading, as floating-point instructions are not enabled in in
env->hflags.  Move the code for doing so from fpu_init to cpu_reset so
the MIPS_HFLAG_{FPU,F64} setting doesn't get clobbered by cpu_reset
setting env->hflags to MIPS_HFLAG_UM.

The same end can be achieved by swapping the ordering of fpu_init and
cpu_reset in cpu_mips_init, but it seemed better to consolidate the
CONFIG_USER_ONLY code into a single location.

Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 91a7593526)
2009-12-13 21:05:16 +01:00
Andre Przywara
910628f396 target-i386: Update CPUID feature set for TCG
The CPUID features QEMU presented to the guest were not up-to-date
with QEMU's emulated feature set.
Add the missing bits of recent (and not so recent) additions to
QEMU's emulation engine.
For stability reasons only the user mode usable bits are exposed for
now, features like Monitor or CR8LEG are left out.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit f1e00a9cf3)
2009-12-13 20:56:26 +01:00
Michael S. Tsirkin
251241dc90 s390: typo fix
s390 code has an obvious typo, which results in:
hw/s390-virtio.c: At top level:
hw/s390-virtio.c:249: error: request for member ‘no_vga’ in something not a structure or union

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2009-12-13 19:47:12 +01:00
Michael S. Tsirkin
03a23e5c6e s390: fix build on 32 bit host
Building on 32 bit host we get:
hw/s390-virtio.c: In function ‘s390_init’:
hw/s390-virtio.c:184: error: integer constant is too large for ‘unsigned long’ type
64 bit values must be ULL.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2009-12-13 19:47:09 +01:00
107 changed files with 1475 additions and 724 deletions

124
Changelog
View File

@@ -1,3 +1,127 @@
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
- e1000: fix device link status in Linux (Anthony Liguori)
- monitor: fix QMP for balloon command (Luiz Capitulino)
- QMP: Return an empty dict by default (Luiz Capitulino)
- QMP: Only handle converted commands (Luiz Capitulino)
- pci: support PCI based option rom loading (Gerd Hoffman/Anthony Liguori)
- Fix backcompat for hotplug of SCSI controllers (Daniel P. Berrange)
- fdc: fix migration from 0.11 (Juan Quintela)
- vmware-vga: fix segv on cursor resize. (Dave Airlie)
- vmware-vga: various fixes (Dave Airlie/Anthony Liguori)
- qdev: improve property error reporting. (Gerd Hoffmann)
- fix vga names in default_list (Gerd Hoffmann)
- usb-host: check mon before using it. (Gerd Hoffmann)
- usb-net: use qdev for -usbdevice (Gerd Hoffmann)
- monitor: Catch printing to non-existent monitor (Luiz Capitulino)
- Avoid permanently disabled QEMU monitor when UNIX migration fails (Daniel P. Berrange)
- Fix loading of ELF multiboot kernels (Kevin Wolf)
- qemu-io: Fix memory leak (Kevin Wolf)
- Fix thinko in linuxboot.S (Paolo Bonzini)
- target-i386: Fix evaluation of DR7 register (Jan Kiszka)
- vnc: hextile: do not generate ForegroundSpecified and SubrectsColoured tiles (Anthony Liguori)
- S390: Bail out without KVM (Alexander Graf)
- S390: Don't tell guest we're updating config space (Alexander Graf)
- target-s390: Fail on unknown instructions (Alexander Graf)
- osdep: Fix runtime failure on older Linux kernels (Andre Przywara)
- Fix a make -j race (Juergen Lock)
- target-alpha: Fix generic ctz64. (Richard Henderson)
- s390: Fix buggy assignment (Stefan Weil)
- target-mips: fix user-mode emulation startup (Nathan Froyd)
- target-i386: Update CPUID feature set for TCG (Andre Przywara)
- s390: fix build on 32 bit host (Michael S. Tsirkin)
version 0.12.0-rc2:
- v2: properly save kvm system time msr registers (Glauber Costa)

View File

@@ -70,7 +70,7 @@ $(filter %-softmmu,$(SUBDIR_RULES)): libqemu_common.a
$(filter %-user,$(SUBDIR_RULES)): libuser.a
libuser.a:
libuser.a: $(GENERATED_HEADERS)
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libuser V="$(V)" TARGET_DIR="libuser/" all,)
ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))

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..

View File

@@ -4,45 +4,57 @@
Introduction
-------------
The QEMU Monitor Protocol (QMP) is a JSON[1] based protocol for QEMU.
The QEMU Monitor Protocol (QMP) allows applications to communicate with
QEMU's Monitor.
By using it applications can control QEMU in reliable and "parseable" way,
QMP also provides asynchronous events support.
QMP is JSON[1] based and has the following features:
- Lightweight, text-based, easy to parse data format
- Asynchronous events support
- Stability
For more information, please, refer to the following files:
o qmp-spec.txt QEMU Monitor Protocol current draft specification
o qmp-spec.txt QEMU Monitor Protocol current specification
o qmp-events.txt List of available asynchronous events
There are also two simple Python scripts available:
o qmp-shell A shell
o vm-info Show some informations about the Virtal Machine
o vm-info Show some information about the Virtual Machine
[1] http://www.json.org
Usage
-----
To enable QMP, QEMU has to be started in "control mode". This is done
by passing the flag "control" to the "-monitor" command-line option.
To enable QMP, QEMU has to be started in "control mode". There are
two ways of doing this, the simplest one is using the the '-qmp'
command-line option.
For example:
$ qemu [...] -monitor control,tcp:localhost:4444,server
$ qemu [...] -qmp tcp:localhost:4444,server
Will start QEMU in control mode, waiting for a client TCP connection
on localhost port 4444.
To manually test it you can connect with telnet and issue commands:
It is also possible to use the '-mon' command-line option to have
more complex combinations. Please, refer to the QEMU's manpage for
more information.
Simple Testing
--------------
To manually test QMP one can connect with telnet and issue commands:
$ telnet localhost 4444
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
{"QMP": {"capabilities": []}}
{ "execute": "query-version" }
{"return": "0.11.50"}
{"return": {"qemu": "0.11.50", "package": ""}}
Contact
-------

View File

@@ -1,4 +1,4 @@
QEMU Monitor Protocol Draft Specification - Version 0.1
QEMU Monitor Protocol Specification - Version 0.1
1. Introduction
===============
@@ -27,9 +27,9 @@ the JSON standard:
http://www.ietf.org/rfc/rfc4627.txt
For convenience, json-objects mentioned in this document will have its members
in a certain order. However, in real protocol usage json-objects members can
be in ANY order, thus no particular order should be assumed.
For convenience, json-object members and json-array elements mentioned in
this document will be in a certain order. However, in real protocol usage
they can be in ANY order, thus no particular order should be assumed.
2.1 General Definitions
-----------------------
@@ -85,12 +85,13 @@ without errors.
The format is:
{ "return": json-value, "id": json-value }
{ "return": json-object, "id": json-value }
Where,
- The "return" member contains the command returned data, which is defined
in a per-command basis or "OK" if the command does not return data
in a per-command basis or an empty json-object if the command does not
return data
- The "id" member contains the transaction identification associated
with the command execution (if issued by the Client)
@@ -102,7 +103,7 @@ completed because of an error condition.
The format is:
{ "error": { "class": json-string, "data": json-value, "desc": json-string },
{ "error": { "class": json-string, "data": json-object, "desc": json-string },
"id": json-value }
Where,
@@ -110,7 +111,7 @@ The format is:
- The "class" member contains the error class name (eg. "ServiceUnavailable")
- The "data" member contains specific error data and is defined in a
per-command basis, it will be an empty json-object if the error has no data
- The "desc" member is a human-readable error message. Clients should
- The "desc" member is a human-readable error message. Clients should
not attempt to parse this message.
- The "id" member contains the transaction identification associated with
the command execution (if issued by the Client)
@@ -127,7 +128,7 @@ to the Client at any time. They are called 'asynchronous events'.
The format is:
{ "event": json-string, "data": json-value,
{ "event": json-string, "data": json-object,
"timestamp": { "seconds": json-number, "microseconds": json-number } }
Where,
@@ -135,7 +136,7 @@ The format is:
- The "event" member contains the event's name
- The "data" member contains event specific data, which is defined in a
per-event basis, it is optional
- The "timestamp" member contains the exact time of when the event ocurred
- The "timestamp" member contains the exact time of when the event occurred
in the Server. It is a fixed json-object with time in seconds and
microseconds
@@ -157,19 +158,20 @@ S: {"QMP": {"capabilities": []}}
---------------------------
C: { "execute": "stop" }
S: {"return": "OK"}
S: {"return": {}}
3.3 KVM information
-------------------
C: {"execute": "query-kvm", "id": "example"}
S: {"return": "enabled", "id": "example"}
C: { "execute": "query-kvm", "id": "example" }
S: {"return": {"enabled": true, "present": true}, "id": "example"}
3.4 Parsing error
------------------
C: { "execute": }
S: {"error": {"class": "JSONParsing", "data": {}}}
S: {"error": {"class": "JSONParsing", "desc": "Invalid JSON syntax", "data":
{}}}
3.5 Powerdown event
-------------------
@@ -177,19 +179,25 @@ S: {"error": {"class": "JSONParsing", "data": {}}}
S: {"timestamp": {"seconds": 1258551470, "microseconds": 802384}, "event":
"POWERDOWN"}
4. Notes to Client implementors
-------------------------------
4. Compatibility Considerations
--------------------------------
4.1 It is recommended to always start the Server in pause mode, thus the
Client is able to perform any setup procedure without the risk of
race conditions and related problems
In order to achieve maximum compatibility between versions, Clients must not
assume any particular:
4.2 It is recommended to always check the capabilities json-array, issued
with the greeting message, at connection time
- Size of json-objects or length of json-arrays
- Order of json-object members or json-array elements
- Amount of errors generated by a command, that is, new errors can be added
to any existing command in newer versions of the Server
4.3 Json-objects or json-arrays mentioned in this document are not fixed
and no particular size or number of members/elements should be assumed.
New members/elements can be added at any time.
Additionally, Clients should always:
4.4 No particular order of json-objects members should be assumed, they
can change at any time
- Check the capabilities json-array at connection time
- Check the availability of commands with 'query-commands' before issuing them
5. Recommendations to Client implementors
-----------------------------------------
5.1 The Server should be always started in pause mode, thus the Client is
able to perform any setup procedure without the risk of race conditions
and related problems

View File

@@ -1 +1 @@
0.11.92
0.12.3

36
block.c
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);
}
}

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. */

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,

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,

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 {

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) {

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,

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);

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);
}
}

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 {

View File

@@ -205,6 +205,8 @@ START_TEST(qdict_put_exists_test)
value = qdict_get_int(tests_dict, key);
fail_unless(value == 2);
fail_unless(qdict_size(tests_dict) == 1);
}
END_TEST

3
configure vendored
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

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

View File

@@ -179,7 +179,7 @@ typedef struct CPUWatchpoint {
\
/* Core interrupt code */ \
jmp_buf jmp_env; \
int32_t exception_index; \
int exception_index; \
\
CPUState *next_cpu; /* next CPU sharing TB cache */ \
int cpu_index; /* CPU index (informative) */ \

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;

2
exec.c
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();
}

View File

@@ -164,7 +164,7 @@ static inline int ctz64(uint64_t val)
{
#if QEMU_GNUC_PREREQ(3, 4)
if (val)
return __builtin_ctz(val);
return __builtin_ctzll(val);
else
return 64;
#else

View File

@@ -22,7 +22,10 @@ typedef struct QEMUMachine {
int no_serial:1,
no_parallel:1,
use_virtcon:1,
no_vga:1;
no_vga:1,
no_floppy:1,
no_cdrom:1,
no_sdcard:1;
int is_default;
GlobalProperty *compat_props;
struct QEMUMachine *next;

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);
}
@@ -3209,9 +3211,6 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
pci_register_bar((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE,
PCI_BASE_ADDRESS_SPACE_MEMORY, cirrus_pci_mmio_map);
}
/* ROM BIOS */
rom_add_vga(VGABIOS_CIRRUS_FILENAME);
return 0;
}
@@ -3226,6 +3225,7 @@ static PCIDeviceInfo cirrus_vga_info = {
.qdev.size = sizeof(PCICirrusVGAState),
.qdev.vmsd = &vmstate_pci_cirrus_vga,
.init = pci_cirrus_vga_initfn,
.romfile = VGABIOS_CIRRUS_FILENAME,
.config_write = pci_cirrus_write_config,
};

View File

@@ -1089,7 +1089,6 @@ static int pci_e1000_init(PCIDevice *pci_dev)
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
pci_config_set_device_id(pci_conf, E1000_DEVID);
*(uint16_t *)(pci_conf+0x04) = cpu_to_le16(0x0407);
*(uint16_t *)(pci_conf+0x06) = cpu_to_le16(0x0010);
pci_conf[0x08] = 0x03;
pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
@@ -1121,14 +1120,6 @@ static int pci_e1000_init(PCIDevice *pci_dev)
d->dev.qdev.info->name, d->dev.qdev.id, d);
qemu_format_nic_info_str(&d->nic->nc, macaddr);
if (!pci_dev->qdev.hotplugged) {
static int loaded = 0;
if (!loaded) {
rom_add_option("pxe-e1000.bin");
loaded = 1;
}
}
return 0;
}
@@ -1146,6 +1137,7 @@ static PCIDeviceInfo e1000_info = {
.qdev.vmsd = &vmstate_e1000,
.init = pci_e1000_init,
.exit = pci_e1000_uninit,
.romfile = "pxe-e1000.bin",
.qdev.props = (Property[]) {
DEFINE_NIC_PROPERTIES(E1000State, conf),
DEFINE_PROP_END_OF_LIST(),

View File

@@ -661,7 +661,7 @@ static int fdc_post_load(void *opaque, int version_id)
}
static const VMStateDescription vmstate_fdc = {
.name = "fdctrl",
.name = "fdc",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
@@ -699,31 +699,6 @@ static const VMStateDescription vmstate_fdc = {
}
};
static const VMStateDescription vmstate_fdc_isa = {
.name = "fdc",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
.fields = (VMStateField []) {
/* Controller State */
VMSTATE_STRUCT(state, fdctrl_isabus_t, 0, vmstate_fdc, fdctrl_t),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_fdc_sysbus = {
.name = "fdc",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
.fields = (VMStateField []) {
/* Controller State */
VMSTATE_STRUCT(state, fdctrl_sysbus_t, 0, vmstate_fdc, fdctrl_t),
VMSTATE_END_OF_LIST()
}
};
static void fdctrl_external_reset_sysbus(DeviceState *d)
{
fdctrl_sysbus_t *sys = container_of(d, fdctrl_sysbus_t, busdev.qdev);
@@ -960,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;
@@ -1926,7 +1907,7 @@ fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
return fdctrl;
}
static int fdctrl_init_common(fdctrl_t *fdctrl)
static int fdctrl_init_common(fdctrl_t *fdctrl, target_phys_addr_t io_base)
{
int i, j;
static int command_tables_inited = 0;
@@ -1957,6 +1938,7 @@ static int fdctrl_init_common(fdctrl_t *fdctrl)
DMA_register_channel(fdctrl->dma_chann, &fdctrl_transfer_handler, fdctrl);
fdctrl_connect_drives(fdctrl);
vmstate_register(io_base, &vmstate_fdc, fdctrl);
return 0;
}
@@ -1980,7 +1962,7 @@ static int isabus_fdc_init1(ISADevice *dev)
isa_init_irq(&isa->busdev, &fdctrl->irq, isairq);
fdctrl->dma_chann = dma_chann;
ret = fdctrl_init_common(fdctrl);
ret = fdctrl_init_common(fdctrl, iobase);
return ret;
}
@@ -1998,7 +1980,7 @@ static int sysbus_fdc_init1(SysBusDevice *dev)
qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
fdctrl->dma_chann = -1;
ret = fdctrl_init_common(fdctrl);
ret = fdctrl_init_common(fdctrl, io);
return ret;
}
@@ -2015,7 +1997,7 @@ static int sun4m_fdc_init1(SysBusDevice *dev)
qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
fdctrl->sun4m = 1;
return fdctrl_init_common(fdctrl);
return fdctrl_init_common(fdctrl, io);
}
static ISADeviceInfo isa_fdc_info = {
@@ -2023,7 +2005,6 @@ static ISADeviceInfo isa_fdc_info = {
.qdev.name = "isa-fdc",
.qdev.size = sizeof(fdctrl_isabus_t),
.qdev.no_user = 1,
.qdev.vmsd = &vmstate_fdc_isa,
.qdev.reset = fdctrl_external_reset_isa,
.qdev.props = (Property[]) {
DEFINE_PROP_DRIVE("driveA", fdctrl_isabus_t, state.drives[0].dinfo),
@@ -2036,7 +2017,6 @@ static SysBusDeviceInfo sysbus_fdc_info = {
.init = sysbus_fdc_init1,
.qdev.name = "sysbus-fdc",
.qdev.size = sizeof(fdctrl_sysbus_t),
.qdev.vmsd = &vmstate_fdc_sysbus,
.qdev.reset = fdctrl_external_reset_sysbus,
.qdev.props = (Property[]) {
DEFINE_PROP_DRIVE("driveA", fdctrl_sysbus_t, state.drives[0].dinfo),
@@ -2049,7 +2029,6 @@ static SysBusDeviceInfo sun4m_fdc_info = {
.init = sun4m_fdc_init1,
.qdev.name = "SUNW,fdtwo",
.qdev.size = sizeof(fdctrl_sysbus_t),
.qdev.vmsd = &vmstate_fdc_sysbus,
.qdev.reset = fdctrl_external_reset_sysbus,
.qdev.props = (Property[]) {
DEFINE_PROP_DRIVE("drive", fdctrl_sysbus_t, state.drives[0].dinfo),

View File

@@ -45,11 +45,12 @@ typedef struct _FWCfgEntry {
FWCfgCallback callback;
} FWCfgEntry;
typedef struct _FWCfgState {
struct _FWCfgState {
FWCfgEntry entries[2][FW_CFG_MAX_ENTRY];
FWCfgFiles *files;
uint16_t cur_entry;
uint32_t cur_offset;
} FWCfgState;
};
static void fw_cfg_write(FWCfgState *s, uint8_t value)
{
@@ -210,9 +211,8 @@ static const VMStateDescription vmstate_fw_cfg = {
}
};
int fw_cfg_add_bytes(void *opaque, uint16_t key, uint8_t *data, uint32_t len)
int fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len)
{
FWCfgState *s = opaque;
int arch = !!(key & FW_CFG_ARCH_LOCAL);
key &= FW_CFG_ENTRY_MASK;
@@ -226,37 +226,36 @@ int fw_cfg_add_bytes(void *opaque, uint16_t key, uint8_t *data, uint32_t len)
return 1;
}
int fw_cfg_add_i16(void *opaque, uint16_t key, uint16_t value)
int fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value)
{
uint16_t *copy;
copy = qemu_malloc(sizeof(value));
*copy = cpu_to_le16(value);
return fw_cfg_add_bytes(opaque, key, (uint8_t *)copy, sizeof(value));
return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
}
int fw_cfg_add_i32(void *opaque, uint16_t key, uint32_t value)
int fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value)
{
uint32_t *copy;
copy = qemu_malloc(sizeof(value));
*copy = cpu_to_le32(value);
return fw_cfg_add_bytes(opaque, key, (uint8_t *)copy, sizeof(value));
return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
}
int fw_cfg_add_i64(void *opaque, uint16_t key, uint64_t value)
int fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
{
uint64_t *copy;
copy = qemu_malloc(sizeof(value));
*copy = cpu_to_le64(value);
return fw_cfg_add_bytes(opaque, key, (uint8_t *)copy, sizeof(value));
return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
}
int fw_cfg_add_callback(void *opaque, uint16_t key, FWCfgCallback callback,
int fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
void *callback_opaque, uint8_t *data, size_t len)
{
FWCfgState *s = opaque;
int arch = !!(key & FW_CFG_ARCH_LOCAL);
if (!(key & FW_CFG_WRITE_CHANNEL))
@@ -275,8 +274,54 @@ int fw_cfg_add_callback(void *opaque, uint16_t key, FWCfgCallback callback,
return 1;
}
void *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
target_phys_addr_t ctl_addr, target_phys_addr_t data_addr)
int fw_cfg_add_file(FWCfgState *s, const char *dir, const char *filename,
uint8_t *data, uint32_t len)
{
const char *basename;
int i, index;
if (!s->files) {
int dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS;
s->files = qemu_mallocz(dsize);
fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, (uint8_t*)s->files, dsize);
}
index = be32_to_cpu(s->files->count);
if (index == FW_CFG_FILE_SLOTS) {
fprintf(stderr, "fw_cfg: out of file slots\n");
return 0;
}
fw_cfg_add_bytes(s, FW_CFG_FILE_FIRST + index, data, len);
basename = strrchr(filename, '/');
if (basename) {
basename++;
} else {
basename = filename;
}
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__,
index, s->files->f[index].name, len);
s->files->count = cpu_to_be32(index+1);
return 1;
}
FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
target_phys_addr_t ctl_addr, target_phys_addr_t data_addr)
{
FWCfgState *s;
int io_ctl_memory, io_data_memory;

View File

@@ -26,7 +26,11 @@
#define FW_CFG_SETUP_ADDR 0x16
#define FW_CFG_SETUP_SIZE 0x17
#define FW_CFG_SETUP_DATA 0x18
#define FW_CFG_MAX_ENTRY 0x19
#define FW_CFG_FILE_DIR 0x19
#define FW_CFG_FILE_FIRST 0x20
#define FW_CFG_FILE_SLOTS 0x10
#define FW_CFG_MAX_ENTRY (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS)
#define FW_CFG_WRITE_CHANNEL 0x4000
#define FW_CFG_ARCH_LOCAL 0x8000
@@ -35,16 +39,31 @@
#define FW_CFG_INVALID 0xffff
#ifndef NO_QEMU_PROTOS
typedef struct FWCfgFile {
uint32_t size; /* file size */
uint16_t select; /* write this to 0x510 to read it */
uint16_t reserved;
char name[56];
} FWCfgFile;
typedef struct FWCfgFiles {
uint32_t count;
FWCfgFile f[];
} FWCfgFiles;
typedef void (*FWCfgCallback)(void *opaque, uint8_t *data);
int fw_cfg_add_bytes(void *opaque, uint16_t key, uint8_t *data, uint32_t len);
int fw_cfg_add_i16(void *opaque, uint16_t key, uint16_t value);
int fw_cfg_add_i32(void *opaque, uint16_t key, uint32_t value);
int fw_cfg_add_i64(void *opaque, uint16_t key, uint64_t value);
int fw_cfg_add_callback(void *opaque, uint16_t key, FWCfgCallback callback,
typedef struct _FWCfgState FWCfgState;
int fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len);
int fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);
int fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value);
int fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);
int fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
void *callback_opaque, uint8_t *data, size_t len);
void *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
target_phys_addr_t crl_addr, target_phys_addr_t data_addr);
int fw_cfg_add_file(FWCfgState *s, const char *dir, const char *filename,
uint8_t *data, uint32_t len);
FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
target_phys_addr_t crl_addr, target_phys_addr_t data_addr);
#endif /* NO_QEMU_PROTOS */

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()
}
};

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);

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(),
}
};

View File

@@ -48,6 +48,7 @@
#include "sysemu.h"
#include "uboot_image.h"
#include "loader.h"
#include "fw_cfg.h"
#include <zlib.h>
@@ -526,15 +527,15 @@ struct Rom {
char *path;
size_t romsize;
uint8_t *data;
int align;
int isrom;
char *fw_dir;
char *fw_file;
target_phys_addr_t min;
target_phys_addr_t max;
target_phys_addr_t addr;
QTAILQ_ENTRY(Rom) next;
};
static FWCfgState *fw_cfg;
static QTAILQ_HEAD(, Rom) roms = QTAILQ_HEAD_INITIALIZER(roms);
int rom_enable_driver_roms;
@@ -548,7 +549,7 @@ static void rom_insert(Rom *rom)
/* list is ordered by load address */
QTAILQ_FOREACH(item, &roms, next) {
if (rom->min >= item->min)
if (rom->addr >= item->addr)
continue;
QTAILQ_INSERT_BEFORE(item, rom, next);
return;
@@ -556,8 +557,8 @@ static void rom_insert(Rom *rom)
QTAILQ_INSERT_TAIL(&roms, rom, next);
}
int rom_add_file(const char *file,
target_phys_addr_t min, target_phys_addr_t max, int align)
int rom_add_file(const char *file, const char *fw_dir,
target_phys_addr_t addr)
{
Rom *rom;
int rc, fd = -1;
@@ -576,9 +577,11 @@ int rom_add_file(const char *file,
goto err;
}
rom->align = align;
rom->min = min;
rom->max = max;
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);
lseek(fd, 0, SEEK_SET);
@@ -590,6 +593,8 @@ int rom_add_file(const char *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:
@@ -603,15 +608,13 @@ err:
}
int rom_add_blob(const char *name, const void *blob, size_t len,
target_phys_addr_t min, target_phys_addr_t max, int align)
target_phys_addr_t addr)
{
Rom *rom;
rom = qemu_mallocz(sizeof(*rom));
rom->name = qemu_strdup(name);
rom->align = align;
rom->min = min;
rom->max = max;
rom->addr = addr;
rom->romsize = len;
rom->data = qemu_mallocz(rom->romsize);
memcpy(rom->data, blob, len);
@@ -623,14 +626,14 @@ int rom_add_vga(const char *file)
{
if (!rom_enable_driver_roms)
return 0;
return rom_add_file(file, PC_ROM_MIN_VGA, PC_ROM_MAX, PC_ROM_ALIGN);
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, PC_ROM_MIN_OPTION, PC_ROM_MAX, PC_ROM_ALIGN);
return rom_add_file(file, "genroms", 0);
}
static void rom_reset(void *unused)
@@ -638,8 +641,12 @@ static void rom_reset(void *unused)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->data == NULL)
if (rom->fw_file) {
continue;
}
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,32 +663,17 @@ int rom_load_all(void)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (addr < rom->min)
addr = rom->min;
if (rom->max) {
/* load address range */
if (rom->align) {
addr += (rom->align-1);
addr &= ~(rom->align-1);
}
if (addr + rom->romsize > rom->max) {
fprintf(stderr, "rom: out of memory (rom %s, "
"addr 0x" TARGET_FMT_plx
", size 0x%zx, max 0x" TARGET_FMT_plx ")\n",
rom->name, addr, rom->romsize, rom->max);
return -1;
}
} else {
/* fixed address requested */
if (addr != rom->min) {
fprintf(stderr, "rom: requested regions overlap "
"(rom %s. free=0x" TARGET_FMT_plx
", addr=0x" TARGET_FMT_plx ")\n",
rom->name, addr, rom->min);
return -1;
}
if (rom->fw_file) {
continue;
}
rom->addr = addr;
if (addr > rom->addr) {
fprintf(stderr, "rom: requested regions overlap "
"(rom %s. free=0x" TARGET_FMT_plx
", addr=0x" TARGET_FMT_plx ")\n",
rom->name, addr, rom->addr);
return -1;
}
addr = rom->addr;
addr += rom->romsize;
memtype = cpu_get_physical_page_desc(rom->addr) & (3 << IO_MEM_SHIFT);
if (memtype == IO_MEM_ROM)
@@ -692,22 +684,35 @@ int rom_load_all(void)
return 0;
}
void rom_set_fw(void *f)
{
fw_cfg = f;
}
static Rom *find_rom(target_phys_addr_t addr)
{
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->max)
if (rom->fw_file) {
continue;
if (rom->min > addr)
}
if (rom->addr > addr) {
continue;
if (rom->min + 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;
@@ -716,25 +721,27 @@ int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->max)
if (rom->fw_file) {
continue;
if (rom->min > addr)
}
if (rom->addr + rom->romsize < addr) {
continue;
if (rom->min + rom->romsize < addr)
continue;
if (rom->min > end)
}
if (rom->addr > end) {
break;
if (!rom->data)
}
if (!rom->data) {
continue;
}
d = dest + (rom->min - addr);
d = dest + (rom->addr - addr);
s = rom->data;
l = rom->romsize;
if (rom->min < addr) {
if (rom->addr < addr) {
d = dest;
s += (addr - rom->min);
l -= (addr - rom->min);
s += (addr - rom->addr);
l -= (addr - rom->addr);
}
if ((d + l) > (dest + size)) {
l = dest - d;
@@ -753,7 +760,7 @@ void *rom_ptr(target_phys_addr_t addr)
rom = find_rom(addr);
if (!rom || !rom->data)
return NULL;
return rom->data + (addr - rom->min);
return rom->data + (addr - rom->addr);
}
void do_info_roms(Monitor *mon)
@@ -761,10 +768,19 @@ void do_info_roms(Monitor *mon)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
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);
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"
" size=0x%06zx name=\"%s\" \n",
rom->fw_dir,
rom->fw_file,
rom->romsize,
rom->name);
}
}
}

View File

@@ -19,19 +19,21 @@ void pstrcpy_targphys(const char *name,
target_phys_addr_t dest, int buf_size,
const char *source);
int rom_add_file(const char *file,
target_phys_addr_t min, target_phys_addr_t max, int align);
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 min, target_phys_addr_t max, int align);
target_phys_addr_t addr);
int rom_load_all(void);
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, _a, 0, 0)
rom_add_file(_f, NULL, _a)
#define rom_add_blob_fixed(_f, _b, _l, _a) \
rom_add_blob(_f, _b, _l, _a, 0, 0)
rom_add_blob(_f, _b, _l, _a)
#define PC_ROM_MIN_VGA 0xc0000
#define PC_ROM_MIN_OPTION 0xc8000

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

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]);
}

53
hw/pc.c
View File

@@ -560,19 +560,21 @@ static int load_multiboot(void *fw_cfg,
}
if (!(flags & 0x00010000)) { /* MULTIBOOT_HEADER_HAS_ADDR */
uint64_t elf_entry;
uint64_t elf_low, elf_high;
int kernel_size;
fclose(f);
kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_low, &elf_high,
0, ELF_MACHINE, 0);
if (kernel_size < 0) {
fprintf(stderr, "Error while loading elf kernel\n");
exit(1);
}
mh_load_addr = mh_entry_addr = elf_entry;
mb_kernel_size = kernel_size;
mh_load_addr = elf_low;
mb_kernel_size = elf_high - elf_low;
mh_entry_addr = elf_entry;
mb_kernel_data = qemu_malloc(mb_kernel_size);
if (rom_copy(mb_kernel_data, elf_entry, kernel_size) != kernel_size) {
if (rom_copy(mb_kernel_data, mh_load_addr, mb_kernel_size) != mb_kernel_size) {
fprintf(stderr, "Error while fetching elf kernel from rom\n");
exit(1);
}
@@ -1088,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);
@@ -1285,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,
@@ -1293,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",
@@ -1315,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 */ }
},
@@ -1330,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);
}

View File

@@ -199,14 +199,10 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
switch (type) {
case IF_SCSI:
if (!dinfo) {
monitor_printf(mon, "scsi requires a backing file/device.\n");
return NULL;
}
dev = pci_create(bus, devfn, "lsi53c895a");
if (qdev_init(&dev->qdev) < 0)
dev = NULL;
if (dev) {
if (dev && dinfo) {
if (scsi_hot_add(&dev->qdev, dinfo, 0) != 0) {
qdev_unplug(&dev->qdev);
dev = NULL;

View File

@@ -26,6 +26,7 @@
#include "monitor.h"
#include "net.h"
#include "sysemu.h"
#include "loader.h"
//#define DEBUG_PCI
#ifdef DEBUG_PCI
@@ -62,12 +63,15 @@ static struct BusInfo pci_bus_info = {
.print_dev = pcibus_dev_print,
.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()
}
};
static void pci_update_mappings(PCIDevice *d);
static void pci_set_irq(void *opaque, int irq_num, int level);
static int pci_add_option_rom(PCIDevice *pdev);
target_phys_addr_t pci_mem_base;
static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
@@ -518,8 +522,7 @@ static void pci_init_wmask(PCIDevice *dev)
dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff;
dev->wmask[PCI_INTERRUPT_LINE] = 0xff;
pci_set_word(dev->wmask + PCI_COMMAND,
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
PCI_COMMAND_INTX_DISABLE);
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
memset(dev->wmask + PCI_CONFIG_HEADER_SIZE, 0xff,
config_size - PCI_CONFIG_HEADER_SIZE);
@@ -944,25 +947,6 @@ static void pci_update_mappings(PCIDevice *d)
}
}
static inline int pci_irq_disabled(PCIDevice *d)
{
return pci_get_word(d->config + PCI_COMMAND) & PCI_COMMAND_INTX_DISABLE;
}
/* Called after interrupt disabled field update in config space,
* assert/deassert interrupts if necessary.
* Gets original interrupt disable bit value (before update). */
static void pci_update_irq_disabled(PCIDevice *d, int was_irq_disabled)
{
int i, disabled = pci_irq_disabled(d);
if (disabled == was_irq_disabled)
return;
for (i = 0; i < PCI_NUM_PINS; ++i) {
int state = pci_irq_state(d, i);
pci_change_irq_level(d, i, disabled ? -state : state);
}
}
uint32_t pci_default_read_config(PCIDevice *d,
uint32_t address, int len)
{
@@ -975,7 +959,7 @@ uint32_t pci_default_read_config(PCIDevice *d,
void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
{
int i, was_irq_disabled = pci_irq_disabled(d);
int i;
uint32_t config_size = pci_config_size(d);
for (i = 0; i < l && addr + i < config_size; val >>= 8, ++i) {
@@ -987,9 +971,6 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
ranges_overlap(addr, l, PCI_ROM_ADDRESS1, 4) ||
range_covers_byte(addr, l, PCI_COMMAND))
pci_update_mappings(d);
if (range_covers_byte(addr, l, PCI_COMMAND))
pci_update_irq_disabled(d, was_irq_disabled);
}
/***********************************************************/
@@ -1007,8 +988,6 @@ static void pci_set_irq(void *opaque, int irq_num, int level)
pci_set_irq_state(pci_dev, irq_num, level);
pci_update_irq_status(pci_dev);
if (pci_irq_disabled(pci_dev))
return;
pci_change_irq_level(pci_dev, irq_num, change);
}
@@ -1386,6 +1365,12 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
rc = info->init(pci_dev);
if (rc != 0)
return rc;
/* rom loading */
if (pci_dev->romfile == NULL && info->romfile != NULL)
pci_dev->romfile = qemu_strdup(info->romfile);
pci_add_option_rom(pci_dev);
if (qdev->hotplugged)
bus->hotplug(pci_dev, 1);
return 0;
@@ -1463,6 +1448,64 @@ static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id,
return next;
}
static void pci_map_option_rom(PCIDevice *pdev, int region_num, pcibus_t addr, pcibus_t size, int type)
{
cpu_register_physical_memory(addr, size, pdev->rom_offset);
}
/* Add an option rom for the device */
static int pci_add_option_rom(PCIDevice *pdev)
{
int size;
char *path;
void *ptr;
if (!pdev->romfile)
return 0;
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);
}
size = get_image_size(path);
if (size < 0) {
qemu_error("%s: failed to find romfile \"%s\"\n", __FUNCTION__,
pdev->romfile);
return -1;
}
if (size & (size - 1)) {
size = 1 << qemu_fls(size);
}
pdev->rom_offset = qemu_ram_alloc(size);
ptr = qemu_get_ram_ptr(pdev->rom_offset);
load_image(path, ptr);
qemu_free(path);
pci_register_bar(pdev, PCI_ROM_SLOT, size,
0, pci_map_option_rom);
return 0;
}
/* Reserve space and add capability to the linked list in pci config space */
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
{

View File

@@ -101,7 +101,6 @@ typedef struct PCIIORegion {
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
#define PCI_COMMAND_MASTER 0x4 /* Enable bus master */
#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
#define PCI_STATUS 0x06 /* 16 bits */
#define PCI_STATUS_INTERRUPT 0x08
#define PCI_REVISION_ID 0x08 /* 8 bits */
@@ -243,6 +242,11 @@ struct PCIDevice {
uint32_t msix_bar_size;
/* Version id needed for VMState */
int32_t version_id;
/* Location of option rom */
char *romfile;
ram_addr_t rom_offset;
uint32_t rom_bar;
};
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
@@ -381,6 +385,9 @@ typedef struct {
/* pcie stuff */
int is_express; /* is this device pci express? */
/* rom bar */
const char *romfile;
} PCIDeviceInfo;
void pci_qdev_register(PCIDeviceInfo *info);

View File

@@ -500,7 +500,12 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
dev->info->name, name);
return -1;
}
return prop->info->parse(dev, prop, value);
if (prop->info->parse(dev, prop, value) != 0) {
fprintf(stderr, "property \"%s.%s\": failed to parse \"%s\"\n",
dev->info->name, name, value);
return -1;
}
return 0;
}
void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
@@ -619,7 +624,7 @@ void qdev_prop_set_globals(DeviceState *dev)
continue;
}
if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
abort();
exit(1);
}
}
}

View File

@@ -3353,14 +3353,6 @@ static int pci_rtl8139_init(PCIDevice *dev)
qemu_mod_timer(s->timer,
rtl8139_get_next_tctr_time(s,qemu_get_clock(vm_clock)));
#endif /* RTL8139_ONBOARD_TIMER */
if (!dev->qdev.hotplugged) {
static int loaded = 0;
if (!loaded) {
rom_add_option("pxe-rtl8139.bin");
loaded = 1;
}
}
return 0;
}
@@ -3371,6 +3363,7 @@ static PCIDeviceInfo rtl8139_info = {
.qdev.vmsd = &vmstate_rtl8139,
.init = pci_rtl8139_init,
.exit = pci_rtl8139_uninit,
.romfile = "pxe-rtl8139.bin",
.qdev.props = (Property[]) {
DEFINE_NIC_PROPERTIES(RTL8139State, conf),
DEFINE_PROP_END_OF_LIST(),

View File

@@ -307,7 +307,7 @@ static void virtio_s390_notify(void *opaque, uint16_t vector)
uint64_t token = s390_virtio_device_vq_token(dev, vector);
/* XXX kvm dependency! */
kvm_s390_virtio_irq(s390_cpu_addr2state(0), 1, token);
kvm_s390_virtio_irq(s390_cpu_addr2state(0), 0, token);
}
/**************** S390 Virtio Bus Device Descriptions *******************/

View File

@@ -142,6 +142,13 @@ static void s390_init(ram_addr_t ram_size,
ram_addr_t initrd_size = 0;
int i;
/* XXX we only work on KVM for now */
if (!kvm_enabled()) {
fprintf(stderr, "The S390 target only works with KVM enabled\n");
exit(1);
}
/* get a BUS */
s390_bus = s390_virtio_bus_init(&ram_size);
@@ -181,7 +188,7 @@ static void s390_init(ram_addr_t ram_size,
cpu_synchronize_state(env);
env->psw.addr = KERN_IMAGE_START;
env->psw.mask = 0x0000000180000000UL;
env->psw.mask = 0x0000000180000000ULL;
}
if (initrd_filename) {
@@ -201,7 +208,11 @@ static void s390_init(ram_addr_t ram_size,
}
/* Create VirtIO console */
qdev_init_nofail(qdev_create((BusState *)s390_bus, "virtio-console-s390"));
for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
if (virtcon_hds[i]) {
qdev_init_nofail(qdev_create((BusState *)s390_bus, "virtio-console-s390"));
}
}
/* Create VirtIO network adapters */
for(i = 0; i < nb_nics; i++) {
@@ -209,7 +220,7 @@ static void s390_init(ram_addr_t ram_size,
DeviceState *dev;
if (!nd->model) {
nd->model = (char*)"virtio";
nd->model = qemu_strdup("virtio");
}
if (strcmp(nd->model, "virtio")) {
@@ -245,7 +256,7 @@ static QEMUMachine s390_machine = {
.init = s390_init,
.no_serial = 1,
.no_parallel = 1,
.use_virtcon = 1.
.use_virtcon = 1,
.no_vga = 1,
.max_cpus = 255,
.is_default = 1,

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(),
},
};

View File

@@ -148,7 +148,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
/* Use values found on a real PowerMac */
/* Uninorth main bus */
dev = qdev_create(NULL, "uni-north-main");
dev = qdev_create(NULL, "uni-north");
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
d = FROM_SYSBUS(UNINState, s);
@@ -157,7 +157,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
pic, 11 << 3, 4);
#if 0
pci_create_simple(d->host_state.bus, 11 << 3, "uni-north-main");
pci_create_simple(d->host_state.bus, 11 << 3, "uni-north");
#endif
sysbus_mmio_map(s, 0, 0xf2800000);
@@ -170,8 +170,8 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
#endif
/* Uninorth AGP bus */
pci_create_simple(d->host_state.bus, 11 << 3, "uni-north-AGP");
dev = qdev_create(NULL, "uni-north-AGP");
pci_create_simple(d->host_state.bus, 11 << 3, "uni-north-agp");
dev = qdev_create(NULL, "uni-north-agp");
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
sysbus_mmio_map(s, 0, 0xf0800000);
@@ -180,8 +180,8 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
/* Uninorth internal bus */
#if 0
/* XXX: not needed for now */
pci_create_simple(d->host_state.bus, 14 << 3, "uni-north-internal");
dev = qdev_create(NULL, "uni-north-internal");
pci_create_simple(d->host_state.bus, 14 << 3, "uni-north-pci");
dev = qdev_create(NULL, "uni-north-pci");
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
sysbus_mmio_map(s, 0, 0xf4800000);
@@ -260,7 +260,7 @@ static int unin_internal_pci_host_init(PCIDevice *d)
}
static PCIDeviceInfo unin_main_pci_host_info = {
.qdev.name = "uni-north-main",
.qdev.name = "uni-north",
.qdev.size = sizeof(PCIDevice),
.init = unin_main_pci_host_init,
};
@@ -272,29 +272,29 @@ static PCIDeviceInfo dec_21154_pci_host_info = {
};
static PCIDeviceInfo unin_agp_pci_host_info = {
.qdev.name = "uni-north-AGP",
.qdev.name = "uni-north-agp",
.qdev.size = sizeof(PCIDevice),
.init = unin_agp_pci_host_init,
};
static PCIDeviceInfo unin_internal_pci_host_info = {
.qdev.name = "uni-north-internal",
.qdev.name = "uni-north-pci",
.qdev.size = sizeof(PCIDevice),
.init = unin_internal_pci_host_init,
};
static void unin_register_devices(void)
{
sysbus_register_dev("uni-north-main", sizeof(UNINState),
sysbus_register_dev("uni-north", sizeof(UNINState),
pci_unin_main_init_device);
pci_qdev_register(&unin_main_pci_host_info);
sysbus_register_dev("dec-21154", sizeof(UNINState),
pci_dec_21154_init_device);
pci_qdev_register(&dec_21154_pci_host_info);
sysbus_register_dev("uni-north-AGP", sizeof(UNINState),
sysbus_register_dev("uni-north-agp", sizeof(UNINState),
pci_unin_agp_init_device);
pci_qdev_register(&unin_agp_pci_host_info);
sysbus_register_dev("uni-north-internal", sizeof(UNINState),
sysbus_register_dev("uni-north-pci", sizeof(UNINState),
pci_unin_internal_init_device);
pci_qdev_register(&unin_internal_pci_host_info);
}

View File

@@ -1420,8 +1420,7 @@ static void usbnet_cleanup(VLANClientState *nc)
{
USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
rndis_clear_responsequeue(s);
qemu_free(s);
s->nic = NULL;
}
static void usb_net_handle_destroy(USBDevice *dev)
@@ -1429,9 +1428,18 @@ static void usb_net_handle_destroy(USBDevice *dev)
USBNetState *s = (USBNetState *) dev;
/* TODO: remove the nd_table[] entry */
rndis_clear_responsequeue(s);
qemu_del_vlan_client(&s->nic->nc);
}
static NetClientInfo net_usbnet_info = {
.type = NET_CLIENT_TYPE_NIC,
.size = sizeof(NICState),
.can_receive = usbnet_can_receive,
.receive = usbnet_receive,
.cleanup = usbnet_cleanup,
};
static int usb_net_initfn(USBDevice *dev)
{
USBNetState *s = DO_UPCAST(USBNetState, dev, dev);
@@ -1447,43 +1455,45 @@ static int usb_net_initfn(USBDevice *dev)
s->media_state = 0; /* NDIS_MEDIA_STATE_CONNECTED */;
s->filter = 0;
s->vendorid = 0x1234;
qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
s->dev.qdev.info->name, s->dev.qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
snprintf(s->usbstring_mac, sizeof(s->usbstring_mac),
"%02x%02x%02x%02x%02x%02x",
0x40,
s->conf.macaddr.a[1],
s->conf.macaddr.a[2],
s->conf.macaddr.a[3],
s->conf.macaddr.a[4],
s->conf.macaddr.a[5]);
return 0;
}
static NetClientInfo net_usbnet_info = {
.type = NET_CLIENT_TYPE_NIC,
.size = sizeof(NICState),
.can_receive = usbnet_can_receive,
.receive = usbnet_receive,
.cleanup = usbnet_cleanup,
};
USBDevice *usb_net_init(NICInfo *nd)
static USBDevice *usb_net_init(const char *cmdline)
{
USBDevice *dev;
USBNetState *s;
QemuOpts *opts;
int idx;
dev = usb_create_simple(NULL /* FIXME */, "usb-net");
s = DO_UPCAST(USBNetState, dev, dev);
opts = qemu_opts_parse(&qemu_net_opts, cmdline, NULL);
if (!opts) {
return NULL;
}
qemu_opt_set(opts, "type", "nic");
qemu_opt_set(opts, "model", "usb");
memcpy(s->conf.macaddr.a, nd->macaddr, sizeof(nd->macaddr));
s->conf.vlan = nd->vlan;
s->conf.peer = nd->netdev;
idx = net_client_init(NULL, opts, 0);
if (idx == -1) {
return NULL;
}
s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
nd->model, nd->name, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
snprintf(s->usbstring_mac, sizeof(s->usbstring_mac),
"%02x%02x%02x%02x%02x%02x",
0x40, s->conf.macaddr.a[1], s->conf.macaddr.a[2],
s->conf.macaddr.a[3], s->conf.macaddr.a[4], s->conf.macaddr.a[5]);
fprintf(stderr, "usbnet: initialized mac %02x:%02x:%02x:%02x:%02x:%02x\n",
s->conf.macaddr.a[0], s->conf.macaddr.a[1], s->conf.macaddr.a[2],
s->conf.macaddr.a[3], s->conf.macaddr.a[4], s->conf.macaddr.a[5]);
return (USBDevice *) s;
dev = usb_create(NULL /* FIXME */, "usb-net");
qdev_set_nic_properties(&dev->qdev, &nd_table[idx]);
qdev_init_nofail(&dev->qdev);
return dev;
}
static struct USBDeviceInfo net_info = {
@@ -1496,6 +1506,12 @@ static struct USBDeviceInfo net_info = {
.handle_control = usb_net_handle_control,
.handle_data = usb_net_handle_data,
.handle_destroy = usb_net_handle_destroy,
.usbdevice_name = "net",
.usbdevice_init = usb_net_init,
.qdev.props = (Property[]) {
DEFINE_NIC_PROPERTIES(USBNetState, conf),
DEFINE_PROP_END_OF_LIST(),
}
};
static void usb_net_register_devices(void)

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;
}

View File

@@ -258,9 +258,6 @@ void usb_host_info(Monitor *mon);
/* usb-hid.c */
void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *));
/* usb-net.c */
USBDevice *usb_net_init(NICInfo *nd);
/* usb-bt.c */
USBDevice *usb_bt_init(HCIInfo *hci);

View File

@@ -42,11 +42,7 @@ int isa_vga_init(void)
s->ds = graphic_console_init(s->update, s->invalidate,
s->screen_dump, s->text_update, s);
#ifdef CONFIG_BOCHS_VBE
/* XXX: use optimized standard vga accesses */
cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
VGA_RAM_SIZE, s->vram_offset);
#endif
vga_init_vbe(s);
/* ROM BIOS */
rom_add_vga(VGABIOS_FILENAME);
return 0;

View File

@@ -106,12 +106,7 @@ static int pci_vga_initfn(PCIDevice *dev)
PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);
}
#ifdef CONFIG_BOCHS_VBE
/* XXX: use optimized standard vga accesses */
cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
VGA_RAM_SIZE, s->vram_offset);
#endif
vga_init_vbe(s);
/* ROM BIOS */
rom_add_vga(VGABIOS_FILENAME);
return 0;

View File

@@ -1581,6 +1581,14 @@ static void vga_sync_dirty_bitmap(VGACommonState *s)
cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa0000, 0xa8000);
cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000);
}
#ifdef CONFIG_BOCHS_VBE
if (s->vbe_mapped) {
cpu_physical_sync_dirty_bitmap(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
VBE_DISPI_LFB_PHYSICAL_ADDRESS + s->vram_size);
}
#endif
}
void vga_dirty_log_start(VGACommonState *s)
@@ -1592,6 +1600,35 @@ void vga_dirty_log_start(VGACommonState *s)
kvm_log_start(isa_mem_base + 0xa0000, 0x8000);
kvm_log_start(isa_mem_base + 0xa8000, 0x8000);
}
#ifdef CONFIG_BOCHS_VBE
if (kvm_enabled() && s->vbe_mapped) {
kvm_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
}
#endif
}
void vga_dirty_log_stop(VGACommonState *s)
{
if (kvm_enabled() && s->map_addr)
kvm_log_stop(s->map_addr, s->map_end - s->map_addr);
if (kvm_enabled() && s->lfb_vram_mapped) {
kvm_log_stop(isa_mem_base + 0xa0000, 0x80000);
kvm_log_stop(isa_mem_base + 0xa8000, 0x80000);
}
#ifdef CONFIG_BOCHS_VBE
if (kvm_enabled() && s->vbe_mapped) {
kvm_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
}
#endif
}
void vga_dirty_log_restart(VGACommonState *s)
{
vga_dirty_log_stop(s);
vga_dirty_log_start(s);
}
/*
@@ -2294,6 +2331,15 @@ void vga_init(VGACommonState *s)
qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
}
void vga_init_vbe(VGACommonState *s)
{
#ifdef CONFIG_BOCHS_VBE
/* XXX: use optimized standard vga accesses */
cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
VGA_RAM_SIZE, s->vram_offset);
s->vbe_mapped = 1;
#endif
}
/********************************************************/
/* vga screen dump */

View File

@@ -71,8 +71,8 @@
uint16_t vbe_regs[VBE_DISPI_INDEX_NB]; \
uint32_t vbe_start_addr; \
uint32_t vbe_line_offset; \
uint32_t vbe_bank_mask;
uint32_t vbe_bank_mask; \
int vbe_mapped;
#else
#define VGA_STATE_COMMON_BOCHS_VBE
@@ -194,6 +194,8 @@ void vga_init(VGACommonState *s);
void vga_common_reset(VGACommonState *s);
void vga_dirty_log_start(VGACommonState *s);
void vga_dirty_log_stop(VGACommonState *s);
void vga_dirty_log_restart(VGACommonState *s);
extern const VMStateDescription vmstate_vga_common;
uint32_t vga_ioport_read(void *opaque, uint32_t addr);
@@ -217,6 +219,7 @@ void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1,
unsigned int color_xor);
int vga_ioport_invalid(VGACommonState *s, uint32_t addr);
void vga_init_vbe(VGACommonState *s);
extern const uint8_t sr_mask[8];
extern const uint8_t gr_mask[16];

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)

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);

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;
}
}
@@ -518,14 +518,6 @@ static int virtio_net_init_pci(PCIDevice *pci_dev)
/* make the actual value visible */
proxy->nvectors = vdev->nvectors;
if (!pci_dev->qdev.hotplugged) {
static int loaded = 0;
if (!loaded) {
rom_add_option("pxe-virtio.bin");
loaded = 1;
}
}
return 0;
}
@@ -569,6 +561,7 @@ static PCIDeviceInfo virtio_info[] = {
.qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_net_init_pci,
.exit = virtio_net_exit_pci,
.romfile = "pxe-virtio.bin",
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),

View File

@@ -67,6 +67,11 @@ struct vmsvga_state_s {
int syncing;
int fb_size;
ram_addr_t fifo_offset;
uint8_t *fifo_ptr;
unsigned int fifo_size;
target_phys_addr_t fifo_base;
union {
uint32_t *fifo;
struct __attribute__((__packed__)) {
@@ -462,7 +467,7 @@ struct vmsvga_cursor_definition_s {
int hot_x;
int hot_y;
uint32_t mask[1024];
uint32_t image[1024];
uint32_t image[4096];
};
#define SVGA_BITMAP_SIZE(w, h) ((((w) + 31) >> 5) * (h))
@@ -557,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 ++)
@@ -680,7 +692,7 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
return 0x0;
case SVGA_REG_VRAM_SIZE:
return s->vga.vram_size - SVGA_FIFO_SIZE;
return s->vga.vram_size;
case SVGA_REG_FB_SIZE:
return s->fb_size;
@@ -701,10 +713,10 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
return caps;
case SVGA_REG_MEM_START:
return s->vram_base + s->vga.vram_size - SVGA_FIFO_SIZE;
return s->fifo_base;
case SVGA_REG_MEM_SIZE:
return SVGA_FIFO_SIZE;
return s->fifo_size;
case SVGA_REG_CONFIG_DONE:
return s->config;
@@ -766,8 +778,12 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
s->height = -1;
s->invalidated = 1;
s->vga.invalidate(&s->vga);
if (s->enable)
s->fb_size = ((s->depth + 7) >> 3) * s->new_width * s->new_height;
if (s->enable) {
s->fb_size = ((s->depth + 7) >> 3) * s->new_width * s->new_height;
vga_dirty_log_stop(&s->vga);
} else {
vga_dirty_log_start(&s->vga);
}
break;
case SVGA_REG_WIDTH:
@@ -790,7 +806,7 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
case SVGA_REG_CONFIG_DONE:
if (value) {
s->fifo = (uint32_t *) &s->vga.vram_ptr[s->vga.vram_size - SVGA_FIFO_SIZE];
s->fifo = (uint32_t *) s->fifo_ptr;
/* Check range and alignment. */
if ((CMD(min) | CMD(max) |
CMD(next_cmd) | CMD(stop)) & 3)
@@ -910,8 +926,8 @@ static void vmsvga_reset(struct vmsvga_state_s *s)
s->width = -1;
s->height = -1;
s->svgaid = SVGA_ID;
s->depth = 24;
s->bypp = (s->depth + 7) >> 3;
s->depth = ds_get_bits_per_pixel(s->vga.ds);
s->bypp = ds_get_bytes_per_pixel(s->vga.ds);
s->cursor.on = 0;
s->redraw_fifo_first = 0;
s->redraw_fifo_last = 0;
@@ -943,6 +959,8 @@ static void vmsvga_reset(struct vmsvga_state_s *s)
break;
}
s->syncing = 0;
vga_dirty_log_start(&s->vga);
}
static void vmsvga_invalidate_display(void *opaque)
@@ -1059,7 +1077,7 @@ static int vmsvga_post_load(void *opaque, int version_id)
s->invalidated = 1;
if (s->config)
s->fifo = (uint32_t *) &s->vga.vram_ptr[s->vga.vram_size - SVGA_FIFO_SIZE];
s->fifo = (uint32_t *) s->fifo_ptr;
return 0;
}
@@ -1109,23 +1127,25 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
s->scratch_size = SVGA_SCRATCH_SIZE;
s->scratch = qemu_malloc(s->scratch_size * 4);
vmsvga_reset(s);
vga_common_init(&s->vga, vga_ram_size);
vga_init(&s->vga);
vmstate_register(0, &vmstate_vga_common, &s->vga);
s->vga.ds = graphic_console_init(vmsvga_update_display,
vmsvga_invalidate_display,
vmsvga_screen_dump,
vmsvga_text_update, s);
#ifdef CONFIG_BOCHS_VBE
/* XXX: use optimized standard vga accesses */
cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
vga_ram_size, s->vga.vram_offset);
#endif
rom_add_vga(VGABIOS_FILENAME);
s->fifo_size = SVGA_FIFO_SIZE;
s->fifo_offset = qemu_ram_alloc(s->fifo_size);
s->fifo_ptr = qemu_get_ram_ptr(s->fifo_offset);
vga_common_init(&s->vga, vga_ram_size);
vga_init(&s->vga);
vmstate_register(0, &vmstate_vga_common, &s->vga);
vga_init_vbe(&s->vga);
rom_add_vga(VGABIOS_FILENAME);
vmsvga_reset(s);
}
static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num,
@@ -1164,6 +1184,23 @@ static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num,
#endif
cpu_register_physical_memory(s->vram_base, s->vga.vram_size,
iomemtype);
s->vga.map_addr = addr;
s->vga.map_end = addr + s->vga.vram_size;
vga_dirty_log_restart(&s->vga);
}
static void pci_vmsvga_map_fifo(PCIDevice *pci_dev, int region_num,
pcibus_t addr, pcibus_t size, int type)
{
struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
struct vmsvga_state_s *s = &d->chip;
ram_addr_t iomemtype;
s->fifo_base = addr;
iomemtype = s->fifo_offset | IO_MEM_RAM;
cpu_register_physical_memory(s->fifo_base, s->fifo_size,
iomemtype);
}
static int pci_vmsvga_initfn(PCIDevice *dev)
@@ -1189,6 +1226,9 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
pci_register_bar(&s->card, 1, VGA_RAM_SIZE,
PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_mem);
pci_register_bar(&s->card, 2, SVGA_FIFO_SIZE,
PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_fifo);
vmsvga_init(&s->chip, VGA_RAM_SIZE);
return 0;

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 */

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 *)));

View File

@@ -112,10 +112,6 @@ MigrationState *unix_start_outgoing_migration(Monitor *mon,
socket_set_nonblock(s->fd);
if (!detach) {
migrate_fd_monitor_suspend(s, mon);
}
do {
ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr));
if (ret == -1)
@@ -128,7 +124,13 @@ MigrationState *unix_start_outgoing_migration(Monitor *mon,
if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) {
dprintf("connect failed\n");
goto err_after_open;
} else if (ret >= 0)
}
if (!detach) {
migrate_fd_monitor_suspend(s, mon);
}
if (ret >= 0)
migrate_fd_connect(s);
return &s->mig_state;

View File

@@ -106,7 +106,7 @@ void do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data)
s->cancel(s);
}
void do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data)
void do_migrate_set_speed(Monitor *mon, const QDict *qdict)
{
double d;
char *ptr;

View File

@@ -56,7 +56,7 @@ void do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data);
void do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data);
void do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data);
void do_migrate_set_speed(Monitor *mon, const QDict *qdict);
uint64_t migrate_max_downtime(void);

View File

@@ -140,6 +140,9 @@ static inline int monitor_ctrl_mode(const Monitor *mon)
static void monitor_read_command(Monitor *mon, int show_prompt)
{
if (!mon->rs)
return;
readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL);
if (show_prompt)
readline_show_prompt(mon->rs);
@@ -174,9 +177,6 @@ static void monitor_puts(Monitor *mon, const char *str)
{
char c;
if (!mon)
return;
for(;;) {
c = *str++;
if (c == '\0')
@@ -192,6 +192,9 @@ static void monitor_puts(Monitor *mon, const char *str)
void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
{
if (!mon)
return;
if (mon->mc && !mon->mc->print_enabled) {
qemu_error_new(QERR_UNDEFINED_ERROR);
} else {
@@ -283,7 +286,8 @@ static void monitor_protocol_emitter(Monitor *mon, QObject *data)
qobject_incref(data);
qdict_put_obj(qmp, "return", data);
} else {
qdict_put(qmp, "return", qstring_from_str("OK"));
/* return an empty QDict by default */
qdict_put(qmp, "return", qdict_new());
}
} else {
/* error response */
@@ -330,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";
@@ -361,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);
}
@@ -864,7 +871,7 @@ static void do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
BlockDriverState *bs;
int force = qdict_get_int(qdict, "force");
const char *filename = qdict_get_str(qdict, "filename");
const char *filename = qdict_get_str(qdict, "device");
bs = bdrv_find(filename);
if (!bs) {
@@ -2053,14 +2060,33 @@ static void do_info_status(Monitor *mon, QObject **ret_data)
vm_running, singlestep);
}
static ram_addr_t balloon_get_value(void)
{
ram_addr_t actual;
if (kvm_enabled() && !kvm_has_sync_mmu()) {
qemu_error_new(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
return 0;
}
actual = qemu_balloon_status();
if (actual == 0) {
qemu_error_new(QERR_DEVICE_NOT_ACTIVE, "balloon");
return 0;
}
return actual;
}
/**
* do_balloon(): Request VM to change its memory allocation
*/
static void do_balloon(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
int value = qdict_get_int(qdict, "value");
ram_addr_t target = value;
qemu_balloon(target << 20);
if (balloon_get_value()) {
/* ballooning is active */
qemu_balloon(qdict_get_int(qdict, "value"));
}
}
static void monitor_print_balloon(Monitor *mon, const QObject *data)
@@ -2088,14 +2114,11 @@ static void do_info_balloon(Monitor *mon, QObject **ret_data)
{
ram_addr_t actual;
actual = qemu_balloon_status();
if (kvm_enabled() && !kvm_has_sync_mmu())
qemu_error_new(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
else if (actual == 0)
qemu_error_new(QERR_DEVICE_NOT_ACTIVE, "balloon");
else
actual = balloon_get_value();
if (actual != 0) {
*ret_data = qobject_from_jsonf("{ 'balloon': %" PRId64 "}",
(int64_t) actual);
}
}
static qemu_acl *find_acl(Monitor *mon, const char *name)
@@ -3479,6 +3502,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
break;
case 'i':
case 'l':
case 'M':
{
int64_t val;
@@ -3509,6 +3533,8 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
monitor_printf(mon, "\'%s\' has failed: ", cmdname);
monitor_printf(mon, "integer is for 32-bit values\n");
goto fail;
} else if (c == 'M') {
val <<= 20;
}
qdict_put(qdict, key, qint_from_int(val));
}
@@ -3844,7 +3870,7 @@ static int monitor_can_read(void *opaque)
{
Monitor *mon = opaque;
return (mon->suspend_cnt == 0) ? 128 : 0;
return (mon->suspend_cnt == 0) ? 1 : 0;
}
typedef struct CmdArgs {
@@ -3913,6 +3939,7 @@ static int check_arg(const CmdArgs *cmd_args, QDict *args)
}
case 'i':
case 'l':
case 'M':
if (qobject_type(value) != QTYPE_QINT) {
qemu_error_new(QERR_INVALID_PARAMETER_TYPE, name, "int");
return -1;
@@ -4050,7 +4077,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
qobject_from_jsonf("{ 'item': %s }", info_item));
} else {
cmd = monitor_find_command(cmd_name);
if (!cmd) {
if (!cmd || !monitor_handler_ported(cmd)) {
qemu_error_new(QERR_COMMAND_NOT_FOUND, cmd_name);
goto err_input;
}

64
net.c
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;
}

3
net.h
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);

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;

View File

@@ -569,9 +569,5 @@ int net_init_socket(QemuOpts *opts,
return -1;
}
if (vlan) {
vlan->nb_host_devs++;
}
return 0;
}

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;
}

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;
}

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;
}

18
osdep.c
View File

@@ -262,13 +262,15 @@ int qemu_pipe(int pipefd[2])
#ifdef CONFIG_PIPE2
ret = pipe2(pipefd, O_CLOEXEC);
#else
if (ret != -1 || errno != ENOSYS) {
return ret;
}
#endif
ret = pipe(pipefd);
if (ret == 0) {
qemu_set_cloexec(pipefd[0]);
qemu_set_cloexec(pipefd[1]);
}
#endif
return ret;
}
@@ -283,12 +285,14 @@ int qemu_socket(int domain, int type, int protocol)
#ifdef SOCK_CLOEXEC
ret = socket(domain, type | SOCK_CLOEXEC, protocol);
#else
if (ret != -1 || errno != EINVAL) {
return ret;
}
#endif
ret = socket(domain, type, protocol);
if (ret >= 0) {
qemu_set_cloexec(ret);
}
#endif
return ret;
}
@@ -302,12 +306,14 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
#ifdef CONFIG_ACCEPT4
ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
#else
if (ret != -1 || errno != ENOSYS) {
return ret;
}
#endif
ret = accept(s, addr, addrlen);
if (ret >= 0) {
qemu_set_cloexec(ret);
}
#endif
return ret;
}

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/).

Binary file not shown.

View File

@@ -79,24 +79,21 @@ copy_kernel:
mode, so let's get into 32 bit mode, write the kernel and jump
back again. */
/* Set DS to SS+SP - 0x10, so we can write our GDT descriptor there */
mov %ss, %eax
shl $4, %eax
add %esp, %eax
sub $0x10, %eax
shr $4, %eax
/* Reserve space on the stack for our GDT descriptor. */
mov %esp, %ebp
sub $16, %esp
/* Now create the GDT descriptor */
movw $((3 * 8) - 1), -16(%bp)
mov %cs, %eax
movzwl %ax, %eax
shl $4, %eax
movw $((3 * 8) - 1), %bx
movw %bx, %gs:0
movl $gdt, %ebx
add %eax, %ebx
movl %ebx, %gs:2
addl $gdt, %eax
movl %eax, -14(%bp)
/* And load the GDT */
data32 lgdt %gs:0
data32 lgdt -16(%bp)
mov %ebp, %esp
/* Get us to protected mode now */
mov $1, %eax

Binary file not shown.

View File

@@ -122,9 +122,8 @@ void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
/* allocate a new entry */
entry = alloc_entry(key, value);
QLIST_INSERT_HEAD(&qdict->table[hash], entry, next);
qdict->size++;
}
qdict->size++;
}
/**

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) {

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

View File

@@ -7,6 +7,7 @@ extern QemuOptsList qemu_device_opts;
extern QemuOptsList qemu_netdev_opts;
extern QemuOptsList qemu_net_opts;
extern QemuOptsList qemu_rtc_opts;
extern QemuOptsList qemu_global_opts;
extern QemuOptsList qemu_mon_opts;
int qemu_set_option(const char *str);

View File

@@ -129,7 +129,8 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
{
size_t *sizes = calloc(nr_iov, sizeof(size_t));
size_t count = 0;
void *buf, *p;
void *buf = NULL;
void *p;
int i;
for (i = 0; i < nr_iov; i++) {
@@ -139,19 +140,19 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
len = cvtnum(arg);
if (len < 0) {
printf("non-numeric length argument -- %s\n", arg);
return NULL;
goto fail;
}
/* should be SIZE_T_MAX, but that doesn't exist */
if (len > UINT_MAX) {
printf("too large length argument -- %s\n", arg);
return NULL;
goto fail;
}
if (len & 0x1ff) {
printf("length argument %lld is not sector aligned\n",
len);
return NULL;
goto fail;
}
sizes[i] = len;
@@ -167,6 +168,7 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
p += sizes[i];
}
fail:
free(sizes);
return buf;
}

View File

@@ -130,7 +130,7 @@ ETEXI
{
.name = "eject",
.args_type = "force:-f,filename:B",
.args_type = "force:-f,device:B",
.params = "[-f] device",
.help = "eject a removable medium (use -f to force it)",
.user_print = monitor_user_noop,
@@ -763,8 +763,7 @@ ETEXI
.args_type = "value:s",
.params = "value",
.help = "set maximum speed (in bytes) for migrations",
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_migrate_set_speed,
.mhandler.cmd = do_migrate_set_speed,
},
STEXI
@@ -887,7 +886,7 @@ ETEXI
{
.name = "balloon",
.args_type = "value:i",
.args_type = "value:M",
.params = "target",
.help = "request VM to change it's memory allocation (in MB)",
.user_print = monitor_user_noop,

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);

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

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;
}

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
sdl.c
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;

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";

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;
}
}

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) {

View File

@@ -694,6 +694,7 @@ typedef struct CPUX86State {
/* For KVM */
uint32_t mp_state;
int32_t exception_injected;
int32_t interrupt_injected;
uint8_t soft_interrupt;
uint8_t nmi_injected;
@@ -834,12 +835,12 @@ static inline int hw_breakpoint_enabled(unsigned long dr7, int index)
static inline int hw_breakpoint_type(unsigned long dr7, int index)
{
return (dr7 >> (DR7_TYPE_SHIFT + (index * 2))) & 3;
return (dr7 >> (DR7_TYPE_SHIFT + (index * 4))) & 3;
}
static inline int hw_breakpoint_len(unsigned long dr7, int index)
{
int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 2))) & 3);
int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 4))) & 3);
return (len == 2) ? 8 : len + 1;
}

View File

@@ -131,10 +131,11 @@ static x86_def_t x86_defs[] = {
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
/* this feature is needed for Solaris and isn't fully implemented */
CPUID_PSE36,
.ext_features = CPUID_EXT_SSE3,
.ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
.ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
.ext3_features = CPUID_EXT3_SVM,
.ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
.xlevel = 0x8000000A,
.model_id = "QEMU Virtual CPU version " QEMU_VERSION,
},
@@ -151,18 +152,19 @@ static x86_def_t x86_defs[] = {
.features = PPRO_FEATURES |
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
CPUID_PSE36,
/* Missing: CPUID_EXT_CX16, CPUID_EXT_POPCNT */
.ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
.ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
CPUID_EXT_POPCNT,
/* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
.ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
CPUID_EXT2_FFXSR,
/* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
/* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
CPUID_EXT3_CR8LEG,
CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
.ext3_features = CPUID_EXT3_SVM,
.ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
.xlevel = 0x8000001A,
.model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
},
@@ -183,7 +185,7 @@ static x86_def_t x86_defs[] = {
CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
.ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
.ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
/* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
.ext3_features = CPUID_EXT3_LAHF_LM,
.xlevel = 0x80000008,
.model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
},
@@ -221,7 +223,7 @@ static x86_def_t x86_defs[] = {
.model = 3,
.stepping = 3,
.features = PPRO_FEATURES,
.ext_features = CPUID_EXT_SSE3,
.ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
.xlevel = 0,
.model_id = "QEMU Virtual CPU version " QEMU_VERSION,
},
@@ -615,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)
@@ -1783,11 +1787,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
}
if (kvm_enabled()) {
/* Nested SVM not yet supported in KVM */
/* Nested SVM not yet supported in upstream QEMU */
*ecx &= ~CPUID_EXT3_SVM;
} else {
/* AMD 3DNow! is not supported in QEMU */
*edx &= ~(CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT);
}
break;
case 0x80000002:

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;
@@ -720,8 +721,8 @@ static int kvm_put_vcpu_events(CPUState *env)
return 0;
}
events.exception.injected = (env->exception_index >= 0);
events.exception.nr = env->exception_index;
events.exception.injected = (env->exception_injected >= 0);
events.exception.nr = env->exception_injected;
events.exception.has_error_code = env->has_error_code;
events.exception.error_code = env->error_code;
@@ -755,7 +756,7 @@ static int kvm_get_vcpu_events(CPUState *env)
if (ret < 0) {
return ret;
}
env->exception_index =
env->exception_injected =
events.exception.injected ? events.exception.nr : -1;
env->has_error_code = events.exception.has_error_code;
env->error_code = events.exception.error_code;

View File

@@ -448,12 +448,12 @@ static const VMStateDescription vmstate_cpu = {
VMSTATE_INT32_V(interrupt_injected, CPUState, 9),
VMSTATE_UINT32_V(mp_state, CPUState, 9),
VMSTATE_UINT64_V(tsc, CPUState, 9),
VMSTATE_INT32_V(exception_injected, CPUState, 11),
VMSTATE_UINT8_V(soft_interrupt, CPUState, 11),
VMSTATE_UINT8_V(nmi_injected, CPUState, 11),
VMSTATE_UINT8_V(nmi_pending, CPUState, 11),
VMSTATE_UINT8_V(has_error_code, CPUState, 11),
VMSTATE_UINT32_V(sipi_vector, CPUState, 11),
VMSTATE_INT32_V(exception_index, CPUState, 11),
/* MCE */
VMSTATE_UINT64_V(mcg_cap, CPUState, 10),
VMSTATE_UINT64_V(mcg_status, CPUState, 10),

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);

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)
{

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

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); \

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 {
@@ -8652,6 +8656,14 @@ void cpu_reset (CPUMIPSState *env)
env->hflags = MIPS_HFLAG_UM;
/* Enable access to the SYNCI_Step register. */
env->CP0_HWREna |= (1 << 1);
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
env->hflags |= MIPS_HFLAG_FPU;
}
#ifdef TARGET_MIPS64
if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
env->hflags |= MIPS_HFLAG_F64;
}
#endif
#else
if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot,

View File

@@ -524,14 +524,6 @@ static void fpu_init (CPUMIPSState *env, const mips_def_t *def)
env->fpus[i].fcr0 = def->CP1_fcr0;
memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu));
#if defined(CONFIG_USER_ONLY)
if (env->CP0_Config1 & (1 << CP0C1_FP))
env->hflags |= MIPS_HFLAG_FPU;
#ifdef TARGET_MIPS64
if (env->active_fpu.fcr0 & (1 << FCR0_F64))
env->hflags |= MIPS_HFLAG_F64;
#endif
#endif
}
static void mvp_init (CPUMIPSState *env, const mips_def_t *def)

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