Compare commits

..

76 Commits

Author SHA1 Message Date
Justin M. Forbes
56a60dd6d6 Version 0.14.1 2011-05-04 13:50:56 -05:00
Christoph Hellwig
76c9b330e3 virtio-blk: fail unaligned requests
Like all block drivers virtio-blk should not allow small than block size
granularity access.  But given that the protocol specifies a
byte unit length field we currently accept such requests, which cause
qemu to abort() in lower layers.  Add checks to the main read and
write handlers to catch them early.

Reported-by: Conor Murphy <conor_murphy_virt@hotmail.com>
Tested-by: Conor Murphy <conor_murphy_virt@hotmail.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2011-05-03 08:32:03 -05:00
Stefan Hajnoczi
9b33410d3b qed: Fix consistency check on 32-bit hosts
The qed_bytes_to_clusters() function is normally used with size_t
lengths.  Consistency check used it with file size length and therefore
failed on 32-bit hosts when the image file is 4 GB or more.

Make qed_bytes_to_clusters() explicitly 64-bit and update consistency
check to keep 64-bit cluster counts.

Reported-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2011-05-03 08:31:32 -05:00
Michael Tokarev
419f1c3503 exit if -drive specified is invalid instead of ignoring the "wrong" -drive
This fixes the problem when qemu continues even if -drive specification
is somehow invalid, resulting in a mess.  Applicable for both current
master and for stable-0.14 (and the same issue exist 0.13 and 0.12 too).

The prob can actually be seriuos: when you start guest with two drives
and make an error in the specification of one of them, and the guest
has something like a raid array on the two drives, guest may start failing
that array or kick "missing" drives which may result in a mess - this is
what actually happened to me, I did't want a resync at all, and a resync
resulted in re-writing (and allocating) a 4TB virtual drive I used for
testing, which in turn resulted in my filesystem filling up and whole
thing failing badly.  Yes it was just testing VM, I experimented with
larger raid arrays, but the end result was quite, well, unexpected.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2011-05-03 08:30:49 -05:00
Michael S. Tsirkin
fc5c4a7a63 vhost: fix dirty page handling
vhost was passing a physical address to cpu_physical_memory_set_dirty,
which is wrong: we need to translate to ram address first.

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

Note: this lead to crashes during migration, so the patch
is needed on the stable branch too.
2011-05-03 08:28:58 -05:00
Ryan Harper
22da30fc28 Do not delete BlockDriverState when deleting the drive
When removing a drive from the host-side via drive_del we currently have
the following path:

drive_del
qemu_aio_flush()
bdrv_close()    // zaps bs->drv, which makes any subsequent I/O get
                // dropped.  Works as designed
drive_uninit()
bdrv_delete()   // frees the bs.  Since the device is still connected to
                // bs, any subsequent I/O is a use-after-free.

The value of bs->drv becomes unpredictable on free.  As long as it
remains null, I/O still gets dropped, however it could become non-null
at any point after the free resulting SEGVs or other QEMU state
corruption.

To resolve this issue as simply as possible, we can chose to not
actually delete the BlockDriverState pointer.  Since bdrv_close()
handles setting the drv pointer to NULL, we just need to remove the
BlockDriverState from the QLIST that is used to enumerate the block
devices.  This is currently handled within bdrv_delete, so move this
into its own function, bdrv_make_anon().

The result is that we can now invoke drive_del, this closes the file
descriptors and sets BlockDriverState->drv to NULL which prevents futher
IO to the device, and since we do not free BlockDriverState, we don't
have to worry about the copy retained in the block devices.

We also don't attempt to remove the qdev property since we are no longer
deleting the BlockDriverState on drives with associated drives.  This
also allows for removing Drives with no devices associated either.

Reported-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2011-05-03 07:59:05 -05:00
Michael Tokarev
f8a4bf59fe vnc: tight: Fix crash after 2GB of output
fix 2Gb integer overflow in in VNC tight and zlib encodings

As found by Roland Dreier <roland@purestorage.com> (excellent
catch!), when amount of VNC compressed data produced by zlib
and sent to client exceeds 2Gb, integer overflow occurs because
currently, we calculate amount of data produced at each step by
comparing saved total_out with new total_out, and total_out is
something which grows without bounds.  Compare it with previous
avail_out instead of total_out, and leave total_out alone.

The same code is used in vnc-enc-tight.c and vnc-enc-zlib.c,
so fix both cases.

There, there's no actual need to save previous_out value, since
capacity-offset (which is how that value is calculated) stays
the same so it can be recalculated again after call to deflate(),
but whole thing becomes less readable this way.

Reported-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Corentin Chary <corentin.chary@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2011-04-10 00:23:52 +02:00
Atsushi Nemoto
b3d657bce4 lan9118: Ignore write to MAC_VLAN1 register
On Mon, 4 Apr 2011 20:15:30 +0200, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Is it really safe ignoring write to this register? If yes, it's probably
> a good idea to explain why in a comment. In any case, if supporting this
> register is easy to do, it would be the best option.

I think it is safe.  Please see an updated comment below.

And though implementing this register might be possible, I suppose it
is not worth to supporting FrameTooLong detection, for now at least.

Thank you for comments.

>8---------------------------------------------------------------------
From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Date: Tue, 5 Apr 2011 23:12:07 +0900
Subject: [PATCH] lan9118: Ignore write to MAC_VLAN1 register

Since linux 2.6.38, smsc911x driver writes to VLAN1 registger.
Since this register only affects FrameTooLong detection, ignoring
write to this register should be safe.

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit a0313c00fc)
2011-04-09 23:41:40 +02:00
Ryan Harper
a0af597d00 Don't allow multiwrites against a block device without underlying medium
If the block device has been closed, we no longer have a medium to submit
IO against, check for this before submitting io.  This prevents a segfault
further in the code where we dereference elements of the block driver.

Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2011-04-04 14:24:29 -05:00
Bernhard Kohl
d4b4ba03e8 lsi53c895a: add support for ABORT messages
If these messages are not handled correctly the guest driver may hang.

Always mandatory:
- ABORT
- BUS DEVICE RESET

Mandatory if tagged queuing is implemented (which disks usually do):
- ABORT TAG
- CLEAR QUEUE

Signed-off-by: Bernhard Kohl <bernhard.kohl@nsn.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 508240c0da)
2011-04-01 22:15:37 +02:00
Michael S. Tsirkin
6f162b368f virtio-pci: fix bus master work around on load
Commit c81131db15
detects old guests by comparing virtio and
PCI status. It attempts to do this on load,
as well, but load_config callback in a binding
is invoked too early and so the virtio status
isn't set yet.

We could add yet another callback to the
binding, to invoke after load, but it
seems easier to reuse the existing vmstate
callback.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Cc: Alexander Graf <agraf@suse.de>
(cherry picked from commit 89c473fd82)
2011-03-29 08:55:12 +02:00
René Rebe
b25a1bbcda fix applesmc REV key
Fix applesmc REV key string literal hex encoding.

Signed-off-by: René Rebe <rene@exactcode.de>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 7f90fa77b8)
2011-03-29 08:54:03 +02:00
Aurelien Jarno
3d19c4e338 rbd: don't link with -lcrypto
rbd support tries to both link with -lrados and -lcrypto. While the
first one is of course necessary, the second is not necessary (only
librados ifself needs to link with libcrypto).

This fixes a licensing issue: qemu as a whole is GPL v2, and thus can't
be linked with OpenSSL without an exception in the license, which seems
difficult to get given the number of persons involved.

Cc: Christian Brunner <chb@muc.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit cc4e8741cc)
2011-03-29 08:53:13 +02:00
Jason Wang
2288eb3af2 net: Add the missing option declaration of "vhostforce"
Signed-off-by: Jason Wang <jasowang@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 96c94b298f)
2011-03-06 20:16:49 +01:00
Stefan Hajnoczi
ecebecffe3 lsi53c895a: Update dnad when skipping MSGOUT bytes
Update not only dbc but also dnad when skipping bytes during the MSGOUT
phase.  Previously only dbc was updated which is probably wrong and
could lead to bogus message codes being read.

Tested on Linux and Windows Server 2003.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 444dd39b5f)
2011-03-06 18:43:54 +01:00
Aurelien Jarno
6f9cace17a Revert "prep: Disable second IDE channel, as long as ISA IDE emulation doesn't support same irq for both channels"
This reverts commit 491e2a338f.
(cherry picked from commit 81aa06471a)
2011-03-04 00:00:24 +01:00
Jan Kiszka
57c864b1f3 isa-bus: Remove bogus IRQ sharing check
Nothing prevented IRQ sharing on the ISA bus in principle. Not all
boards supported this, neither each and every card nor driver and OS.
Still, there existed valid IRQ sharing scenarios, (at least) two of them
can also be found in QEMU: >2 PC UARTs and the PREP IDE buses.

So remove this artificial restriction from our ISA model.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit ee951a37d8)
2011-03-03 23:59:44 +01:00
Stefan Hajnoczi
4b35dfea68 virtio-net: Fix lduw_p() pointer argument of wrong size
A pointer to a size_t variable was passed as the void * pointer to
lduw_p() in virtio_net_receive().  Instead of acting on the 16-bit value
this caused failure on big-endian hosts.

Avoid this issue in the future by using stw_p() instead.  In general we
should use ld*_p() for loading from target memory and st*_p() for
storing to target memory anyway, not the other way around.

Also tighten up a correct use of lduw_p() when stw_p() should be used
instead in virtio_net_get_config().

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit b46d97f2d2)
2011-03-03 23:46:18 +01:00
Peter Maydell
cdd8152e56 hw/sd.c: Add missing state change for SD_STATUS, SEND_NUM_WR_BLOCKS
The SD_STATUS and SEND_NUM_WR_BLOCKS commands are supposed to cause
the card to send data back to the host. However sd.c was missing the
state change to sd_sendingdata_state for these commands, with the effect
that the Linux driver would either hang indefinitely waiting for
nonexistent data (pl181) or read zeroes and provoke a qemu warning
message (omap).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2011-02-25 10:17:48 -06:00
Stefan Weil
74b121a007 vnc: Fix fatal crash with vnc reverse mode
Reverse mode is unusable:

	qemu -vnc localhost:5500,reverse

crashes in vnc_refresh_server_surface because some pointers are NULL.

Fix this by calling vnc_dpy_resize (which initializes these pointers)
before calling vnc_refresh.

Cc: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2011-02-25 10:17:07 -06:00
Stefan Hajnoczi
8d610b6ba2 qemu-char: Check for missing backend name
Check if the backend option is missing before searching the backend
table.  This fixes a NULL pointer dereference when QEMU is invoked with
the following invalid command-line:

  $ qemu -chardev id=foo,path=/tmp/socket

Previously QEMU would segfault, now it produces this error message:

  chardev: "foo" missing backend

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2011-02-20 18:26:41 +01:00
Anthony Liguori
0850f81099 Update version for 0.14.0
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2011-02-16 08:42:46 -06:00
Anthony Liguori
6a7999b222 Update version for 0.14.0-rc2
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2011-02-14 16:01:01 -06:00
Anthony Liguori
e3c8fc83aa Fix build from previous commit
I unfortunately got on an unnamed branch and pushed the wrong bits

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2011-02-14 14:42:29 -06:00
Bruce Rogers
bd2483faf1 PATCH] slirp: fix buffer overrun
Since the addition of the slirp member to struct mbuf, the value of
SLIRP_MSIZE and the initialization of m_size have not been correct,
resulting in overrunning the end of the malloc'd buffer in some cases.

Signed-off-by: Bruce Rogers <brogers@novell.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2011-02-14 14:19:12 -06:00
Gleb Natapov
7083b66b45 correctly check ppr priority during interrupt injection]
TPR blocks all interrupts in a priority class, so simple "less or
equal" check is not enough.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2011-02-14 14:15:36 -06:00
Justin M. Forbes
9de12c453d Merge branch 'linux-user-for-0.14' of git://gitorious.org/qemu-maemo/qemu 2011-02-14 12:11:43 -06:00
Kevin Wolf
c7e9df3bc6 qcow2: Fix order in L2 table COW
When copying L2 tables (this happens only with internal snapshots), the order
wasn't completely safe, so that after a crash you could end up with a L2 table
that has too low refcount, possibly leading to corruption in the long run.

This patch puts the operations in the right order: First allocate the new
L2 table and replace the reference, and only then decrease the refcount of the
old table.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 16fde5f2c2)
2011-02-11 14:34:06 +01:00
Kevin Wolf
038a866f81 qemu-img: Improve error messages for failed bdrv_open
Output the error message string of the bdrv_open return code. Also set a
non-empty device name for the images because the unknown feature error message
includes it.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit b9eaf9ecb1)
2011-02-11 14:34:01 +01:00
Kevin Wolf
64a216f58e qed: Report error for unsupported features
Instead of just returning -ENOTSUP, generate a more detailed error.

Unfortunately we don't have a helpful text for features that we don't know yet,
so just print the feature mask. It might be useful at least if someone asks for
help.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Acked-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 10b758e85c)
2011-02-11 14:34:01 +01:00
Kevin Wolf
12597b0608 qcow2: Report error for version > 2
The qcow2 driver is now declared responsible for any QCOW image that has
version 2 or greater (before this, version 3 would be detected as raw).

For everything newer than version 2, an error is reported.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit e8cdcec123)
2011-02-11 14:34:00 +01:00
Kevin Wolf
e37dcdfb8d qerror: Add QERR_UNKNOWN_BLOCK_FORMAT_FEATURE
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f54e364112)
2011-02-11 14:33:59 +01:00
Kevin Wolf
5c9596112c qcow2: Fix error handling for reading compressed clusters
When reading a compressed cluster failed, qcow2 falsely returned success.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit 8af3648843)
2011-02-11 14:33:58 +01:00
Kevin Wolf
16e07bc282 qcow2: Fix error handling for immediate backing file read failure
Requests could return success even though they failed when bdrv_aio_readv
returned NULL for a backing file read.

Reported-by: Chunqiang Tang <ctang@us.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 3ab4c7e92d)
2011-02-11 14:33:57 +01:00
Chunqiang Tang
607a375709 QCOW2: bug fix - read base image beyond its size
This patch fixes the following bug in QCOW2. For a QCOW2 image that is larger
than its base image, when handling a read request straddling over the end of the
base image, the QCOW2 driver attempts to read beyond the end of the base image
and the request would fail.

This bug was found by Fast Virtual Disk (FVD)'s fully automated testing tool.
The following test triggered the bug.

dd if=/dev/zero of=/var/ramdisk/truth.raw count=0 bs=1 seek=1098561536
dd if=/dev/zero of=/var/ramdisk/zero-500M.raw count=0 bs=1 seek=593099264
./qemu-img create -f qcow2 -ocluster_size=65536,backing_fmt=blksim -b /var/ramdisk/zero-500M.raw /var/ramdisk/test.qcow2 1098561536
./qemu-io --auto --seed=30477694 --truth=/var/ramdisk/truth.raw --format=qcow2 --test=blksim:/var/ramdisk/test.qcow2 --verify_write=true --compare_before=false --compare_after=true --round=100000 --parallel=100 --io_size=10485760 --fail_prob=0 --cancel_prob=0 --instant_qemubh=true

Signed-off-by: Chunqiang Tang <ctang@us.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit e0d9c6f937)
2011-02-11 14:33:56 +01:00
Jes Sorensen
ac12a5af0b Change snapshot_blkdev hmp to use correct argument type for device
Pointed out by Markus

Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 982aa95532)
2011-02-11 14:33:54 +01:00
Stefan Weil
b03088c32f linux-user: Fix possible realloc memory leak
Extract from "man realloc":
"If realloc() fails the original block is left untouched;
it is not freed or moved."

Fix a possible memory leak (reported by cppcheck).

Cc: Riku Voipio <riku.voipio@iki.fi>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Riku Voipio <riku.voipio@nokia.com>
(cherry picked from commit 8d79de6e42)
2011-02-09 21:24:05 +01:00
Stefan Weil
eee37d310c linux-user: Fix possible realloc memory leak
Extract from "man realloc":
"If realloc() fails the original block is left untouched;
it is not freed or moved."

Fix a possible memory leak (reported by cppcheck).

Cc: Riku Voipio <riku.voipio@iki.fi>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Riku Voipio <riku.voipio@nokia.com>
2011-02-09 09:05:48 +02:00
Martin Mohring
28637533d6 linux-user: fix for loopmount ioctl
In case a chrooted build uses XEN or KVM, a looped mount needs to be done to setup the chroot.
The ioctl for loop mount works correctly for arm, mips, ppc32 and sh4, so its now activated.

Signed-off-by: Riku Voipio <riku.voipio@nokia.com>
2011-02-09 09:05:48 +02:00
Justin M. Forbes
23e4cff984 Merge branch 'master' of git+ssh://git.qemu.org/pub/git/qemu-stable-0.14 2011-02-08 12:41:18 -06:00
Markus Armbruster
0893194783 blockdev: Plug memory leak in drive_init() error paths
Should have spotted this when doing commit 319ae529.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
2011-02-08 08:41:54 -06:00
Markus Armbruster
e5f1c19665 blockdev: Plug memory leak in drive_uninit()
Started leaking in commit 1dae12e6.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
2011-02-08 08:41:54 -06:00
Jan Kiszka
343c1de916 x86: Fix MCA broadcast parameters for TCG case
When broadcasting MCEs, we need to set MCIP and RIPV in mcg_status like
it is done for KVM. Use the symbolic constants at this chance.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 2905749287)
2011-02-08 12:37:30 +01:00
Stefan Weil
b75568889f qemu-timer: Fix compilation of new timer code for w32, w64
qemu_next_alarm_deadline() is needed by MinGW, too.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Anthony Liguori <aliguori@us.ibm.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit f26e5a54f0)
2011-02-08 09:06:41 +01:00
Anthony Liguori
a3dfab563e Update version for 0.14.0-rc1
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2011-02-07 13:36:28 -06:00
Marcelo Tosatti
c1f1ffff21 block: enable in_use flag
Set block device in use during block migration, disallow drive_del and
bdrv_truncate for in use devices.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 8591675f44)
2011-02-07 12:55:32 +01:00
Marcelo Tosatti
44d631a001 Add flag to indicate external users to block device
Certain operations such as drive_del or resize cannot be performed
while external users (eg. block migration) reference the block device.

Add a flag to indicate that.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit db593f2565)
2011-02-07 12:55:29 +01:00
Marcelo Tosatti
28b0e1cd0e block-migration: add reference to target DriveInfo
So that ejection of attached device by guest does not free data
in use by block migration instance.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
CC: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit f48905d44f)
2011-02-07 12:55:27 +01:00
Marcelo Tosatti
ddebe9d473 blockdev: add refcount to DriveInfo
The host part of a block device can be deleted with in progress
block migration.

To fix this, add a reference count to DriveInfo, freeing resources
on last reference.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
CC: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 84fb392526)
2011-02-07 12:55:26 +01:00
Marcelo Tosatti
f17f8b687c block-migration: actually disable dirty tracking on cleanup
Call to set_dirty_tracking() is misplaced.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 8f794c557c)
2011-02-07 12:55:25 +01:00
Alexander Graf
d27dd7e1a2 ahci: make number of ports runtime determined
Different AHCI controllers have a different number of ports, so the core
shouldn't care about the amount of ports available.

This patch makes the number of ports available to the AHCI core runtime
configurable, allowing us to have multiple different AHCI implementations
with different amounts of ports.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 2c4b9d0ea4)
2011-02-07 12:55:25 +01:00
Alexander Graf
c3a965c943 ahci: Implement HBA reset
The ahci code was missing its soft reset functionality. This wasn't really an
issue for Linux guests, but Windows gets confused when the controller doesn't
reset when it tells it so.

Using this patch I can now successfully boot Windows 7 from AHCI using AHCI
enabled SeaBIOS.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 760c3e44d3)
2011-02-07 12:55:24 +01:00
Alexander Graf
abc9997416 ahci: send init d2h fis on fis enable
The drive sends a d2h init fis on initialization. Usually, the guest doesn't
receive fises yet at that point though, so the delivery is deferred.

Let's reflect that by sending the init fis on fis receive enablement.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 87e62065bb)
2011-02-07 12:55:23 +01:00
Alexander Graf
ed97a4f2cf ahci: split ICH and AHCI even more
Sebastian's patch already did a pretty good job at splitting up ICH-9
AHCI code and the AHCI core. We need some more though. Copyright was missing,
the lspci dump belongs to ICH-9, we don't need the AHCI core to have its
own qdev device duplicate.

So let's split them a bit more in this patch, making things easier to
read an understand.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 7fb6577b13)
2011-02-07 12:55:22 +01:00
Alexander Graf
8f7dfd6bda ahci: add license header in ahci.h
Due to popular request, this patch adds a license header to ahci.h

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit f83a40dcd7)
2011-02-07 12:55:21 +01:00
Sebastian Herbszt
e81c113d28 ahci: split ICH9 from core
There are multiple ahci devices out there. The currently implemented ich-9
is only one of the many. So let's split that one out into a separate file
to stress the difference.

Signed-off-by: Sebastian Herbszt <herbszt@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 03c7a6a8e7)
2011-02-07 12:55:19 +01:00
Stefan Weil
d4e6590ab8 block/vdi: Fix wrong size in conditionally used memset, memcmp
Error report from cppcheck:
block/vdi.c:122: error: Using sizeof for array given as function argument returns the size of pointer.
block/vdi.c:128: error: Using sizeof for array given as function argument returns the size of pointer.

Fix both by setting the correct size.

The buggy code is only used when QEMU is build without uuid support.
The bug is not critical, so there is no urgent need to apply it to
old versions of QEMU.

Cc: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 4f3669ea5b)
2011-02-07 12:55:18 +01:00
MORITA Kazutaka
f188c02db7 Documentation: add Sheepdog disk images
Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 42af9c30ea)
2011-02-07 12:55:17 +01:00
Kevin Wolf
7edb1c3a51 qcow2: Really use cache=unsafe for image creation
For cache=unsafe we also need to set BDRV_O_CACHE_WB, otherwise we have some
strange unsafe writethrough mode.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit e1a7107f2d)
2011-02-07 12:55:16 +01:00
Gleb Natapov
fd08f20c23 do not pass NULL to strdup.
Also use qemu_strdup() instead of strdup() in bootindex code.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 4fef930af8)
2011-02-04 21:23:05 +01:00
Christophe Lyon
8798240196 Set the right overflow bit for neon 32 and 64 bit saturating add/sub.
Signed-off-by: Christophe Lyon <christophe.lyon@st.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 72902672dc)
2011-02-04 20:59:57 +01:00
Christophe Lyon
ffbda4e682 target-arm: Fix Neon vsra instructions.
This patch fixes the errors reported by my tests in VSRA.

Signed-off-by: Christophe Lyon <christophe.lyon@st.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 5371cb8140)
2011-02-04 20:50:21 +01:00
Aurelien Jarno
81cd8f6047 target-sh4: fix negc
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 7026259f79)
2011-02-04 20:50:16 +01:00
Jan Kiszka
1299aa0d03 ioapic: Style & magics cleanup
Fix a few style issues and convert magic numbers into prober symbolic
constants, also fixing the wrong but unused IOAPIC_DM_SIPI value.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 1f5e71a8e6)
2011-02-04 06:53:52 -06:00
Jan Kiszka
8faaf42a4c ioapic: Add support for qemu-kvm's vmstate v2
qemu-kvm carries the IOAPIC base address in its v2 vmstate. We only
support the default base address so far, and saving even that in the
device state was rejected.

Add a padding field to be able to read qemu-kvm's old state, but
increase our version to 3, indicating that we are not saving a valid
address. This also gives downstream the chance to change to stop
evaluating the base_address and move to v3 as well.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 5dce499948)
2011-02-04 06:53:52 -06:00
Jan Kiszka
f05929b182 ioapic: Save/restore irr
This is a guest modifiable state that must be saved/restored properly.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 35a74c5c59)
2011-02-04 06:53:52 -06:00
Jan Kiszka
bc3aaac57b ioapic: Implement EOI handling for level-triggered IRQs
Add the missing EOI broadcast from local APIC to the IOAPICs on
completion of level-triggered IRQs. This ensures that a still asserted
IRQ source properly re-triggers an APIC IRQ.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 0280b571c1)
2011-02-04 06:53:52 -06:00
Corentin Chary
602c075070 vnc: qemu can die if the client is disconnected while updating screen
agraf reported that qemu_mutex_destroy(vs->output_mutex) while failing
in vnc_disconnect_finish().

It's because vnc_worker_thread_loop() tries to unlock the mutex while
not locked. The unlocking call doesn't fail (pthread bug ?), but
the destroy call does.

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 73eb4c04e9)
2011-02-04 06:53:52 -06:00
Amit Shah
cb5281b199 virtio-serial: Make sure virtqueue is ready before discarding data
This can happen if a port gets unplugged before guest has chance to
initialise vqs.

Reported-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 7185f9315b)
2011-02-04 06:53:52 -06:00
Stefan Weil
9a121a2fbf ui/sdl: Fix handling of caps lock and num lock keys
Starting with SDL version 1.2.14, caps lock and num lock keys
will send a SDL_KEYUP when SDL_DISABLE_LOCK_KEYS=1 is set in
the environment.

The new code sets the environment unconditionally
(it won't harm old versions which do not know it).

The workaround for SDL_KEYUP is only compiled with old SDL versions.

A similar patch without handling of old SDL versions was already
published by Benjamin Drung for Ubuntu.

Cc: Anthony Liguori <aliguori@us.ibm.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Benjamin Drung <benjamin.drung@gmail.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 4e79bcbb96)
2011-02-04 06:53:52 -06:00
Paolo Bonzini
366c2452b1 Unify alarm deadline computation
This patch shows how using the correct formula for
qemu_next_deadline_dyntick can simplify the code of
host_alarm_handler and eliminate useless duplication.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 4c3d45eb69)
2011-02-04 06:53:52 -06:00
Paolo Bonzini
bbd9827cc7 Correct alarm deadline computation
When the QEMU_CLOCK_HOST clock was added, computation of its
deadline was added to qemu_next_deadline, which is correct but
incomplete.

I noticed this by reading the very convoluted rules whereby
qemu_next_deadline_dyntick is computed, which miss QEMU_CLOCK_HOST
when use_icount is true.  This patch inlines qemu_next_deadline
into qemu_next_deadline_dyntick, and then corrects the logic to skip
only QEMU_CLOCK_VIRTUAL when use_icount is true.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 6ad0a1ed21)
2011-02-04 06:53:51 -06:00
Paolo Bonzini
d7f88b4bbd use nanoseconds everywhere for timeout computation
Suggested by Aurelien Jarno.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 9c13246ac1)
2011-02-04 06:53:51 -06:00
Yoshiaki Tamura
ea01a58014 savevm: fix corruption in vmstate_subsection_load().
Although it's rare to happen in live migration, when the head of a
byte stream contains 0x05 which is the marker of subsection, the
loader gets corrupted because vmstate_subsection_load() continues even
the device doesn't require it.  This patch adds a checker whether
subsection is needed, and skips following routines if not needed.

Signed-off-by: Yoshiaki Tamura <tamura.yoshiaki@lab.ntt.co.jp>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit eb60260de0)
2011-02-04 06:53:51 -06:00
Aurelien Jarno
0833073edf Revert "Open up the 0.15 development branch"
This reverts commit 0e1272f22b.
2011-02-02 08:39:44 +01:00
Anthony Liguori
0e1272f22b Open up the 0.15 development branch
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2011-02-01 20:15:26 -06:00
1098 changed files with 24839 additions and 127923 deletions

12
.gitignore vendored
View File

@@ -15,7 +15,6 @@ libdis*
libhw32
libhw64
libuser
qapi-generated
qemu-doc.html
qemu-tech.html
qemu-doc.info
@@ -33,7 +32,6 @@ qemu-options.texi
qemu-img-cmds.texi
qemu-img-cmds.h
qemu-io
qemu-ga
qemu-monitor.texi
QMP/qmp-commands.txt
.gdbinit
@@ -46,9 +44,6 @@ QMP/qmp-commands.txt
*.ky
*.log
*.pdf
*.cps
*.fns
*.kys
*.pg
*.pyc
*.toc
@@ -56,8 +51,6 @@ QMP/qmp-commands.txt
*.vr
*.d
*.o
*.swp
*.orig
.pc
patches
pc-bios/bios-pq/status
@@ -65,10 +58,5 @@ pc-bios/vgabios-pq/status
pc-bios/optionrom/linuxboot.bin
pc-bios/optionrom/multiboot.bin
pc-bios/optionrom/multiboot.raw
pc-bios/optionrom/extboot.bin
pc-bios/optionrom/vapic.bin
.stgit-*
cscope.*
tags
TAGS
*~

8
.gitmodules vendored
View File

@@ -1,12 +1,6 @@
[submodule "roms/vgabios"]
path = roms/vgabios
url = git://git.kernel.org/pub/scm/virt/kvm/vgabios.git/
url = git://git.qemu.org/vgabios.git/
[submodule "roms/seabios"]
path = roms/seabios
url = git://git.qemu.org/seabios.git/
[submodule "roms/SLOF"]
path = roms/SLOF
url = git://git.qemu.org/SLOF.git
[submodule "roms/ipxe"]
path = roms/ipxe
url = git://git.qemu.org/ipxe.git

View File

@@ -1,9 +1,3 @@
This file documents changes for QEMU releases 0.12 and earlier.
For changelog information for later releases, see
http://wiki.qemu.org/ChangeLog or look at the git history for
more detailed information.
version 0.12.0:
- Update to SeaBIOS 0.5.0
@@ -531,7 +525,7 @@ version 0.1.5:
- ppc64 support + personality() patch (Rusty Russell)
- first Alpha CPU patches (Falk Hueffner)
- removed bfd.h dependency
- removed bfd.h dependancy
- fixed shrd, shld, idivl and divl on PowerPC.
- fixed buggy glibc PowerPC rint() function (test-i386 passes now on PowerPC).

View File

@@ -120,3 +120,6 @@ gcc's printf attribute directive in the prototype.
This makes it so gcc's -Wformat and -Wformat-security options can do
their jobs and cross-check format strings with the number and types
of arguments.
Currently many functions in QEMU are not following this rule but
patches to add the attribute would be very much appreciated.

View File

@@ -56,8 +56,8 @@ M: Paul Brook <paul@codesourcery.com>
Guest CPU cores (TCG):
----------------------
Alpha
M: Richard Henderson <rth@twiddle.net>
S: Maintained
M: qemu-devel@nongnu.org
S: Orphan
F: target-alpha/
ARM
@@ -70,11 +70,6 @@ M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
S: Maintained
F: target-cris/
LM32
M: Michael Walle <michael@walle.cc>
S: Maintained
F: target-lm32/
M68K
M: Paul Brook <paul@codesourcery.com>
S: Maintained
@@ -207,18 +202,6 @@ M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
S: Maintained
F: hw/etraxfs.c
LM32 Machines
-------------
EVR32 and uclinux BSP
M: Michael Walle <michael@walle.cc>
S: Maintained
F: hw/lm32_boards.c
milkymist
M: Michael Walle <michael@walle.cc>
S: Maintained
F: hw/milkymist.c
M68K Machines
-------------
an5206
@@ -480,7 +463,7 @@ S: Maintained
F: tcg/ia64/
MIPS target
M: Aurelien Jarno <aurelien@aurel32.net>
M: Aurelien Jarno <aurelien@aurel32.ne>
S: Maintained
F: tcg/mips/

144
Makefile
View File

@@ -88,8 +88,6 @@ include $(SRC_PATH)/Makefile.objs
endif
$(common-obj-y): $(GENERATED_HEADERS)
subdir-libcacard: $(oslib-obj-y) $(trace-obj-y) qemu-malloc.o qemu-timer-common.o
$(filter %-softmmu,$(SUBDIR_RULES)): $(trace-obj-y) $(common-obj-y) subdir-libdis
$(filter %-user,$(SUBDIR_RULES)): $(GENERATED_HEADERS) $(trace-obj-y) subdir-libdis-user subdir-libuser
@@ -106,8 +104,6 @@ audio/audio.o audio/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS)
QEMU_CFLAGS+=$(CURL_CFLAGS)
QEMU_CFLAGS+=$(GLIB_CFLAGS)
ui/cocoa.o: ui/cocoa.m
ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o baum.o: QEMU_CFLAGS += $(SDL_CFLAGS)
@@ -116,31 +112,46 @@ ui/vnc.o: QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
ifeq ($(TRACE_BACKEND),dtrace)
trace.h: trace.h-timestamp trace-dtrace.h
else
trace.h: trace.h-timestamp
endif
trace.h-timestamp: $(SRC_PATH)/trace-events config-host.mak
$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -h < $< > $@," GEN trace.h")
@cmp -s $@ trace.h || cp $@ trace.h
trace.c: trace.c-timestamp
trace.c-timestamp: $(SRC_PATH)/trace-events config-host.mak
$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -c < $< > $@," GEN trace.c")
@cmp -s $@ trace.c || cp $@ trace.c
trace.o: trace.c $(GENERATED_HEADERS)
trace-dtrace.h: trace-dtrace.dtrace
$(call quiet-command,dtrace -o $@ -h -s $<, " GEN trace-dtrace.h")
# Normal practice is to name DTrace probe file with a '.d' extension
# but that gets picked up by QEMU's Makefile as an external dependancy
# rule file. So we use '.dtrace' instead
trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp
trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events config-host.mak
$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -d < $< > $@," GEN trace-dtrace.dtrace")
@cmp -s $@ trace-dtrace.dtrace || cp $@ trace-dtrace.dtrace
trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
$(call quiet-command,dtrace -o $@ -G -s $<, " GEN trace-dtrace.o")
simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
version.o: $(SRC_PATH)/version.rc config-host.mak
$(call quiet-command,$(WINDRES) -I. -o $@ $<," RC $(TARGET_DIR)$@")
version-obj-$(CONFIG_WIN32) += version.o
######################################################################
# Support building shared library libcacard
.PHONY: libcacard.la install-libcacard
ifeq ($(LIBTOOL),)
libcacard.la:
@echo "libtool is missing, please install and rerun configure"; exit 1
install-libcacard:
@echo "libtool is missing, please install and rerun configure"; exit 1
else
libcacard.la: $(GENERATED_HEADERS) $(oslib-obj-y) qemu-malloc.o qemu-timer-common.o $(addsuffix .lo, $(basename $(trace-obj-y)))
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" libcacard.la,)
install-libcacard: libcacard.la
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" install-libcacard,)
endif
######################################################################
qemu-img.o: qemu-img-cmds.h
qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o qemu-ga.o: $(GENERATED_HEADERS)
qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o: $(GENERATED_HEADERS)
qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
@@ -153,67 +164,27 @@ qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
check-qint.o check-qstring.o check-qdict.o check-qlist.o check-qfloat.o check-qjson.o: $(GENERATED_HEADERS)
CHECK_PROG_DEPS = qemu-malloc.o $(oslib-obj-y) $(trace-obj-y) qemu-tool.o
CHECK_PROG_DEPS = qemu-malloc.o $(oslib-obj-y) $(trace-obj-y)
check-qint: check-qint.o qint.o $(CHECK_PROG_DEPS)
check-qstring: check-qstring.o qstring.o $(CHECK_PROG_DEPS)
check-qdict: check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qlist.o $(CHECK_PROG_DEPS)
check-qlist: check-qlist.o qlist.o qint.o $(CHECK_PROG_DEPS)
check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS)
check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o error.o qerror.o qemu-error.o $(CHECK_PROG_DEPS)
$(qapi-obj-y): $(GENERATED_HEADERS)
qapi-dir := qapi-generated
test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir)
$(qapi-dir)/test-qapi-types.c: $(qapi-dir)/test-qapi-types.h
$(qapi-dir)/test-qapi-types.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@")
$(qapi-dir)/test-qapi-visit.c: $(qapi-dir)/test-qapi-visit.h
$(qapi-dir)/test-qapi-visit.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@")
$(qapi-dir)/test-qmp-commands.h: $(qapi-dir)/test-qmp-marshal.c
$(qapi-dir)/test-qmp-marshal.c: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@")
$(qapi-dir)/qga-qapi-types.c: $(qapi-dir)/qga-qapi-types.h
$(qapi-dir)/qga-qapi-types.h: $(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-types.py
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py -o "$(qapi-dir)" -p "qga-" < $<, " GEN $@")
$(qapi-dir)/qga-qapi-visit.c: $(qapi-dir)/qga-qapi-visit.h
$(qapi-dir)/qga-qapi-visit.h: $(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-visit.py
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py -o "$(qapi-dir)" -p "qga-" < $<, " GEN $@")
$(qapi-dir)/qga-qmp-marshal.c: $(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-commands.py
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py -o "$(qapi-dir)" -p "qga-" < $<, " GEN $@")
test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c test-qmp-commands.h) $(qapi-obj-y)
test-qmp-commands: test-qmp-commands.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o $(qapi-dir)/test-qmp-marshal.o module.o
QGALIB=qga/guest-agent-command-state.o qga/guest-agent-commands.o
QGALIB_GEN=$(addprefix $(qapi-dir)/, qga-qapi-types.c qga-qapi-types.h qga-qapi-visit.c qga-qmp-marshal.c)
$(QGALIB_GEN): $(GENERATED_HEADERS)
$(QGALIB) qemu-ga.o: $(QGALIB_GEN) $(qapi-obj-y)
qemu-ga$(EXESUF): qemu-ga.o $(QGALIB) qemu-tool.o qemu-error.o error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) $(qapi-obj-y) qemu-timer-common.o qemu-sockets.o module.o qapi/qmp-dispatch.o qapi/qmp-registry.o $(qapi-dir)/qga-qapi-visit.o $(qapi-dir)/qga-qapi-types.o $(qapi-dir)/qga-qmp-marshal.o
QEMULIBS=libhw32 libhw64 libuser libdis libdis-user
check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o $(CHECK_PROG_DEPS)
clean:
# avoid old build problems by removing potentially incorrect old files
rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
rm -f qemu-options.def
rm -f *.o *.d *.a *.lo $(TOOLS) qemu-ga TAGS cscope.* *.pod *~ */*~
rm -Rf .libs
rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d qga/*.o qga/*.d
rm -f *.o *.d *.a $(TOOLS) TAGS cscope.* *.pod *~ */*~
rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d
rm -f qemu-img-cmds.h
rm -f trace.c trace.h trace.c-timestamp trace.h-timestamp
rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp
rm -f trace-dtrace.h trace-dtrace.h-timestamp
rm -rf $(qapi-dir)
$(MAKE) -C tests clean
for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \
for d in $(ALL_SUBDIRS) libhw32 libhw64 libuser libdis libdis-user; do \
if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
rm -f $$d/qemu-options.def; \
done
@@ -222,12 +193,9 @@ distclean: clean
rm -f config-host.mak config-host.h* config-host.ld $(DOCS) qemu-options.texi qemu-img-cmds.texi qemu-monitor.texi
rm -f config-all-devices.mak
rm -f roms/seabios/config.mak roms/vgabios/config.mak
rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.cps qemu-doc.dvi
rm -f qemu-doc.fn qemu-doc.fns qemu-doc.info qemu-doc.ky qemu-doc.kys
rm -f qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc qemu-doc.tp
rm -f qemu-doc.vr
rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.dvi qemu-doc.fn qemu-doc.info qemu-doc.ky qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc qemu-doc.tp qemu-doc.vr
rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr
for d in $(TARGET_DIRS) $(QEMULIBS); do \
for d in $(TARGET_DIRS) libhw32 libhw64 libuser libdis libdis-user; do \
rm -rf $$d || exit 1 ; \
done
@@ -239,15 +207,13 @@ ifdef INSTALL_BLOBS
BLOBS=bios.bin vgabios.bin vgabios-cirrus.bin \
vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin \
ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc \
pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
mpc8544ds.dtb \
gpxe-eepro100-80861209.rom \
pxe-e1000.bin \
pxe-ne2k_pci.bin pxe-pcnet.bin \
pxe-rtl8139.bin pxe-virtio.bin \
bamboo.dtb petalogix-s3adsp1800.dtb \
multiboot.bin linuxboot.bin \
s390-zipl.rom \
spapr-rtas.bin slof.bin
BLOBS += extboot.bin
BLOBS += vapic.bin
s390-zipl.rom
else
BLOBS=
endif
@@ -274,12 +240,7 @@ endif
ifneq ($(BLOBS),)
$(INSTALL_DIR) "$(DESTDIR)$(datadir)"
set -e; for x in $(BLOBS); do \
if [ -f $(SRC_PATH)/pc-bios/$$x ];then \
$(INSTALL_DATA) $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \
fi \
; if [ -f pc-bios/optionrom/$$x ];then \
$(INSTALL_DATA) pc-bios/optionrom/$$x "$(DESTDIR)$(datadir)"; \
fi \
done
endif
$(INSTALL_DIR) "$(DESTDIR)$(datadir)/keymaps"
@@ -394,13 +355,10 @@ tarbin:
$(datadir)/openbios-sparc32 \
$(datadir)/openbios-sparc64 \
$(datadir)/openbios-ppc \
$(datadir)/pxe-e1000.rom \
$(datadir)/pxe-eepro100.rom \
$(datadir)/pxe-ne2k_pci.rom \
$(datadir)/pxe-pcnet.rom \
$(datadir)/pxe-rtl8139.rom \
$(datadir)/pxe-virtio.rom \
$(datadir)/extboot.bin \
$(datadir)/pxe-ne2k_pci.bin \
$(datadir)/pxe-rtl8139.bin \
$(datadir)/pxe-pcnet.bin \
$(datadir)/pxe-e1000.bin \
$(docdir)/qemu-doc.html \
$(docdir)/qemu-tech.html \
$(mandir)/man1/qemu.1 \
@@ -408,4 +366,4 @@ tarbin:
$(mandir)/man8/qemu-nbd.8
# Include automatically generated dependency files
-include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d qapi/*.d qga/*.d)
-include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d)

View File

@@ -2,22 +2,21 @@
# QObject
qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
qobject-obj-y += qerror.o error.o
qobject-obj-y += qerror.o
#######################################################################
# oslib-obj-y is code depending on the OS (win32 vs posix)
oslib-obj-y = osdep.o
oslib-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o
oslib-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o
oslib-obj-$(CONFIG_WIN32) += oslib-win32.o
oslib-obj-$(CONFIG_POSIX) += oslib-posix.o
#######################################################################
# block-obj-y is code used by both qemu system emulation and qemu-img
block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o async.o
block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o qemu-progress.o qemu-sockets.o
block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o
block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o
block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
block-obj-$(CONFIG_POSIX) += compatfd.o
block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o
@@ -46,14 +45,12 @@ net-nested-$(CONFIG_SLIRP) += slirp.o
net-nested-$(CONFIG_VDE) += vde.o
net-obj-y += $(addprefix net/, $(net-nested-y))
ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy)
ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS),yy)
# Lots of the fsdev/9pcode is pulled in by vl.c via qemu_fsdev_add.
# only pull in the actual virtio-9p device if we also enabled virtio.
CONFIG_REALLY_VIRTFS=y
fsdev-nested-y = qemu-fsdev.o
else
fsdev-nested-y = qemu-fsdev-dummy.o
endif
fsdev-nested-$(CONFIG_VIRTFS) = qemu-fsdev.o
fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y))
######################################################################
@@ -66,7 +63,7 @@ common-obj-y = $(block-obj-y) blockdev.o
common-obj-y += $(net-obj-y)
common-obj-y += $(qobject-obj-y)
common-obj-$(CONFIG_LINUX) += $(fsdev-obj-$(CONFIG_LINUX))
common-obj-y += readline.o console.o cursor.o qemu-error.o
common-obj-y += readline.o console.o cursor.o async.o qemu-error.o
common-obj-y += $(oslib-obj-y)
common-obj-$(CONFIG_WIN32) += os-win32.o
common-obj-$(CONFIG_POSIX) += os-posix.o
@@ -97,13 +94,12 @@ common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
common-obj-$(CONFIG_SD) += sd.o
common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
common-obj-y += bt-hci-csr.o
common-obj-y += buffered_file.o migration.o migration-tcp.o
common-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o
common-obj-y += qemu-char.o savevm.o #aio.o
common-obj-y += msmouse.o ps2.o
common-obj-y += qdev.o qdev-properties.o
common-obj-y += block-migration.o iohandler.o
common-obj-y += block-migration.o
common-obj-y += pflib.o
common-obj-y += bitmap.o bitops.o
common-obj-$(CONFIG_BRLAPI) += baum.o
common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
@@ -129,24 +125,23 @@ common-obj-y += $(addprefix audio/, $(audio-obj-y))
ui-obj-y += keymaps.o
ui-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o
ui-obj-$(CONFIG_COCOA) += cocoa.o
ui-obj-$(CONFIG_CURSES) += curses.o
vnc-obj-y += vnc.o d3des.o
vnc-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o
vnc-obj-y += vnc-enc-tight.o vnc-palette.o
vnc-obj-y += vnc-enc-zrle.o
vnc-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
vnc-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
ui-obj-y += vnc.o d3des.o
ui-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o
ui-obj-y += vnc-enc-tight.o vnc-palette.o
ui-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
ui-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
ui-obj-$(CONFIG_COCOA) += cocoa.o
ifdef CONFIG_VNC_THREAD
vnc-obj-y += vnc-jobs-async.o
ui-obj-y += vnc-jobs-async.o
else
vnc-obj-y += vnc-jobs-sync.o
ui-obj-y += vnc-jobs-sync.o
endif
common-obj-y += $(addprefix ui/, $(ui-obj-y))
common-obj-$(CONFIG_VNC) += $(addprefix ui/, $(vnc-obj-y))
common-obj-y += iov.o acl.o
#common-obj-$(CONFIG_POSIX) += compatfd.o
common-obj-$(CONFIG_THREAD) += qemu-thread.o
common-obj-$(CONFIG_IOTHREAD) += compatfd.o
common-obj-y += notify.o event_notifier.o
common-obj-y += qemu-timer.o qemu-timer-common.o
@@ -156,8 +151,8 @@ slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o
common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y))
# xen backend driver support
common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o
common-obj-$(CONFIG_XEN_BACKEND) += xen_console.o xenfb.o xen_disk.o xen_nic.o
common-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
common-obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
######################################################################
# libuser
@@ -171,11 +166,10 @@ user-obj-y += cutils.o cache-utils.o
# libhw
hw-obj-y =
hw-obj-y += loader.o
hw-obj-$(CONFIG_VIRTIO) += virtio-console.o
hw-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
hw-obj-y += vl.o loader.o
hw-obj-$(CONFIG_VIRTIO) += virtio.o virtio-console.o
hw-obj-y += fw_cfg.o
hw-obj-$(CONFIG_PCI) += pci_bridge.o
hw-obj-$(CONFIG_PCI) += pci.o pci_bridge.o
hw-obj-$(CONFIG_PCI) += msix.o msi.o
hw-obj-$(CONFIG_PCI) += pci_host.o pcie_host.o
hw-obj-$(CONFIG_PCI) += ioh3420.o xio3130_upstream.o xio3130_downstream.o
@@ -192,23 +186,15 @@ hw-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
hw-obj-$(CONFIG_SERIAL) += serial.o
hw-obj-$(CONFIG_PARALLEL) += parallel.o
# Moved back to Makefile.target due to #include qemu-kvm.h:
#hw-obj-$(CONFIG_I8254) += i8254.o
#hw-obj-$(CONFIG_PCSPK) += pcspk.o
hw-obj-$(CONFIG_I8254) += i8254.o
hw-obj-$(CONFIG_PCSPK) += pcspk.o
hw-obj-$(CONFIG_PCKBD) += pckbd.o
hw-obj-$(CONFIG_USB_UHCI) += usb-uhci.o
hw-obj-$(CONFIG_USB_OHCI) += usb-ohci.o
hw-obj-$(CONFIG_USB_EHCI) += usb-ehci.o
hw-obj-$(CONFIG_FDC) += fdc.o
# needs fixes for cpu hotplug, so moved to Makefile.target:
# hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o
hw-obj-$(CONFIG_DMA) += dma.o
hw-obj-$(CONFIG_HPET) += hpet.o
hw-obj-$(CONFIG_APPLESMC) += applesmc.o
hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
hw-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
hw-obj-$(CONFIG_USB_REDIR) += usb-redir.o
# PPC devices
hw-obj-$(CONFIG_OPENPIC) += openpic.o
@@ -249,7 +235,7 @@ hw-obj-$(CONFIG_LAN9118) += lan9118.o
hw-obj-$(CONFIG_NE2000_ISA) += ne2000-isa.o
# IDE
hw-obj-$(CONFIG_IDE_CORE) += ide/core.o ide/atapi.o
hw-obj-$(CONFIG_IDE_CORE) += ide/core.o
hw-obj-$(CONFIG_IDE_QDEV) += ide/qdev.o
hw-obj-$(CONFIG_IDE_PCI) += ide/pci.o
hw-obj-$(CONFIG_IDE_ISA) += ide/isa.o
@@ -272,7 +258,6 @@ hw-obj-$(CONFIG_VGA_PCI) += vga-pci.o
hw-obj-$(CONFIG_VGA_ISA) += vga-isa.o
hw-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o
hw-obj-$(CONFIG_VMWARE_VGA) += vmware_vga.o
hw-obj-$(CONFIG_VMMOUSE) += vmmouse.o
hw-obj-$(CONFIG_RC4030) += rc4030.o
hw-obj-$(CONFIG_DP8393X) += dp8393x.o
@@ -292,12 +277,9 @@ sound-obj-$(CONFIG_HDA) += intel-hda.o hda-audio.o
adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0
hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p.o virtio-9p-debug.o
9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o
9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o
hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
hw-obj-$(CONFIG_REALLY_VIRTFS) += virtio-9p-debug.o
hw-obj-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o
hw-obj-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o
######################################################################
# libdis
@@ -321,46 +303,6 @@ libdis-$(CONFIG_SPARC_DIS) += sparc-dis.o
######################################################################
# trace
ifeq ($(TRACE_BACKEND),dtrace)
trace.h: trace.h-timestamp trace-dtrace.h
else
trace.h: trace.h-timestamp
endif
trace.h-timestamp: $(SRC_PATH)/trace-events config-host.mak
$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -h < $< > $@," GEN trace.h")
@cmp -s $@ trace.h || cp $@ trace.h
trace.c: trace.c-timestamp
trace.c-timestamp: $(SRC_PATH)/trace-events config-host.mak
$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -c < $< > $@," GEN trace.c")
@cmp -s $@ trace.c || cp $@ trace.c
trace.o: trace.c $(GENERATED_HEADERS)
trace-dtrace.h: trace-dtrace.dtrace
$(call quiet-command,dtrace -o $@ -h -s $<, " GEN trace-dtrace.h")
# Normal practice is to name DTrace probe file with a '.d' extension
# but that gets picked up by QEMU's Makefile as an external dependency
# rule file. So we use '.dtrace' instead
trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp
trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events config-host.mak
$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -d < $< > $@," GEN trace-dtrace.dtrace")
@cmp -s $@ trace-dtrace.dtrace || cp $@ trace-dtrace.dtrace
trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
$(call quiet-command,dtrace -o $@ -G -s $<, " GEN trace-dtrace.o")
ifeq ($(LIBTOOL),)
trace-dtrace.lo: trace-dtrace.dtrace
@echo "missing libtool. please install and rerun configure."; exit 1
else
trace-dtrace.lo: trace-dtrace.dtrace
$(call quiet-command,libtool --mode=compile --tag=CC dtrace -o $@ -G -s $<, " lt GEN trace-dtrace.o")
endif
simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
ifeq ($(TRACE_BACKEND),dtrace)
trace-obj-y = trace-dtrace.o
else
@@ -371,20 +313,7 @@ user-obj-y += qemu-timer-common.o
endif
endif
######################################################################
# smartcard
libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o card_7816.o
######################################################################
# qapi
qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qmp-output-visitor.o qapi-dealloc-visitor.o
qapi-nested-y += qmp-registry.o qmp-dispatch.o
qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y))
vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
vl.o: QEMU_CFLAGS+=$(GLIB_CFLAGS)

View File

@@ -3,7 +3,6 @@
GENERATED_HEADERS = config-target.h
CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y)
CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y)
CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y)
include ../config-host.mak
include config-devices.mak
@@ -15,10 +14,7 @@ endif
TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)
$(call set-vpath, $(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw)
ifdef CONFIG_LINUX
QEMU_CFLAGS += -I../linux-headers
endif
QEMU_CFLAGS += -I.. -I$(TARGET_PATH) -DNEED_CPU_H
QEMU_CFLAGS+= -I.. -I$(TARGET_PATH) -DNEED_CPU_H
include $(SRC_PATH)/Makefile.objs
@@ -41,6 +37,8 @@ ifndef CONFIG_HAIKU
LIBS+=-lm
endif
kvm.o kvm-all.o vhost.o vhost_net.o: QEMU_CFLAGS+=$(KVM_CFLAGS)
config-target.h: config-target.h-timestamp
config-target.h-timestamp: config-target.mak
@@ -71,19 +69,15 @@ all: $(PROGS) stap
#########################################################
# cpu emulator library
libobj-y = exec.o cpu-exec.o
libobj-$(CONFIG_NO_CPU_EMULATION) += fake-exec.o
libobj-$(CONFIG_CPU_EMULATION) += translate-all.o translate.o
libobj-$(CONFIG_CPU_EMULATION) += tcg/tcg.o
libobj-y += fpu/softfloat.o
libobj-y = exec.o translate-all.o cpu-exec.o translate.o
libobj-y += tcg/tcg.o
libobj-$(CONFIG_SOFTFLOAT) += fpu/softfloat.o
libobj-$(CONFIG_NOSOFTFLOAT) += fpu/softfloat-native.o
libobj-y += op_helper.o helper.o
ifeq ($(TARGET_BASE_ARCH), i386)
libobj-y += cpuid.o
endif
libobj-$(CONFIG_NEED_MMU) += mmu.o
libobj-$(CONFIG_KVM) += kvm-tpr-opt.o
libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
libobj-y += disas.o
@@ -100,10 +94,10 @@ tcg/tcg.o: cpu.h
# HELPER_CFLAGS is used for all the code compiled with static register
# variables
op_helper.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
op_helper.o cpu-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
# Note: this is a workaround. The real fix is to avoid compiling
# cpu_signal_handler() in user-exec.c.
# cpu_signal_handler() in cpu-exec.c.
signal.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
#########################################################
@@ -113,10 +107,10 @@ ifdef CONFIG_LINUX_USER
$(call set-vpath, $(SRC_PATH)/linux-user:$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR))
QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR)
obj-y = main.o syscall.o strace.o mmap.o signal.o thunk.o \
elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \
qemu-malloc.o user-exec.o $(oslib-obj-y)
qemu-malloc.o $(oslib-obj-y)
obj-$(TARGET_HAS_BFLT) += flatload.o
@@ -154,7 +148,7 @@ LDFLAGS+=-Wl,-segaddr,__STD_PROG_ZONE,0x1000 -image_base 0x0e000000
LIBS+=-lmx
obj-y = main.o commpage.o machload.o mmap.o signal.o syscall.o thunk.o \
gdbstub.o user-exec.o
gdbstub.o
obj-i386-y += ioport-user.o
@@ -176,7 +170,7 @@ $(call set-vpath, $(SRC_PATH)/bsd-user)
QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ARCH)
obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \
gdbstub.o uaccess.o user-exec.o
gdbstub.o uaccess.o
obj-i386-y += ioport-user.o
@@ -192,15 +186,15 @@ endif #CONFIG_BSD_USER
# System emulator target
ifdef CONFIG_SOFTMMU
obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o vl.o balloon.o
obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o
# virtio has to be here due to weird dependency between PCI and virtio-net.
# need to fix this properly
obj-$(CONFIG_NO_PCI) += pci-stub.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
obj-$(CONFIG_VIRTIO) += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
obj-y += vhost_net.o
obj-$(CONFIG_VHOST_NET) += vhost.o
obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
obj-$(CONFIG_REALLY_VIRTFS) += virtio-9p.o
obj-y += rwhandler.o
obj-$(CONFIG_KVM) += kvm.o kvm-all.o
obj-$(CONFIG_NO_KVM) += kvm-stub.o
@@ -210,47 +204,22 @@ QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
QEMU_CFLAGS += $(VNC_SASL_CFLAGS)
QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
QEMU_CFLAGS += $(GLIB_CFLAGS)
# xen support
obj-$(CONFIG_XEN) += xen-all.o xen_machine_pv.o xen_domainbuild.o xen-mapcache.o
obj-$(CONFIG_NO_XEN) += xen-stub.o
obj-i386-$(CONFIG_XEN) += xen_platform.o
# xen backend driver support
obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
# Inter-VM PCI shared memory
CONFIG_IVSHMEM =
ifeq ($(CONFIG_KVM), y)
ifeq ($(CONFIG_PCI), y)
CONFIG_IVSHMEM = y
endif
endif
obj-$(CONFIG_IVSHMEM) += ivshmem.o
obj-$(CONFIG_KVM) += ivshmem.o
# Hardware support
obj-i386-y += vga.o
obj-i386-y += mc146818rtc.o i8259.o pc.o
obj-i386-y += cirrus_vga.o sga.o apic.o ioapic.o piix_pci.o
obj-i386-y += vmport.o
obj-i386-y += cirrus_vga.o apic.o ioapic.o piix_pci.o
obj-i386-y += vmmouse.o vmport.o hpet.o applesmc.o
obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
obj-i386-y += extboot.o
obj-i386-y += debugcon.o multiboot.o
obj-i386-y += pc_piix.o
obj-i386-$(CONFIG_KVM) += kvmclock.o
obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o
obj-i386-y += testdev.o
obj-i386-y += acpi.o acpi_piix4.o
obj-i386-y += pcspk.o i8254.o
obj-i386-$(CONFIG_KVM_PIT) += i8254-kvm.o
obj-i386-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += device-assignment.o
# Hardware support
obj-ia64-y += ide.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
obj-ia64-y += fdc.o mc146818rtc.o serial.o i8259.o ipf.o
obj-ia64-y += cirrus_vga.o parallel.o acpi.o piix_pci.o
obj-ia64-y += usb-uhci.o
obj-ia64-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += device-assignment.o
# shared objects
obj-ppc-y = ppc.o
@@ -262,16 +231,11 @@ obj-ppc-y += ppc_prep.o
obj-ppc-y += ppc_oldworld.o
# NewWorld PowerMac
obj-ppc-y += ppc_newworld.o
# IBM pSeries (sPAPR)
ifeq ($(CONFIG_FDT)$(TARGET_PPC64),yy)
obj-ppc-y += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o
obj-ppc-y += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o
endif
# PowerPC 4xx boards
obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
obj-ppc-y += ppc440.o ppc440_bamboo.o
# PowerPC E500 boards
obj-ppc-y += ppce500_mpc8544ds.o mpc8544_guts.o
obj-ppc-y += ppce500_mpc8544ds.o
# PowerPC 440 Xilinx ML507 reference board.
obj-ppc-y += virtex_ml507.o
obj-ppc-$(CONFIG_KVM) += kvm_ppc.o
@@ -283,31 +247,7 @@ obj-ppc-y += xilinx_timer.o
obj-ppc-y += xilinx_uartlite.o
obj-ppc-y += xilinx_ethlite.o
# LM32 boards
obj-lm32-y += lm32_boards.o
obj-lm32-y += milkymist.o
# LM32 peripherals
obj-lm32-y += lm32_pic.o
obj-lm32-y += lm32_juart.o
obj-lm32-y += lm32_timer.o
obj-lm32-y += lm32_uart.o
obj-lm32-y += lm32_sys.o
obj-lm32-y += milkymist-ac97.o
obj-lm32-y += milkymist-hpdmc.o
obj-lm32-y += milkymist-memcard.o
obj-lm32-y += milkymist-minimac2.o
obj-lm32-y += milkymist-pfpu.o
obj-lm32-y += milkymist-softusb.o
obj-lm32-y += milkymist-sysctl.o
obj-lm32-$(CONFIG_OPENGL) += milkymist-tmu2.o
obj-lm32-y += milkymist-uart.o
obj-lm32-y += milkymist-vgafb.o
obj-lm32-y += framebuffer.o
obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o
obj-mips-y += pcspk.o i8254.o
obj-mips-y += acpi.o acpi_piix4.o
obj-mips-y += mips_addr.o mips_timer.o mips_int.o
obj-mips-y += vga.o i8259.o
obj-mips-y += g364fb.o jazz_led.o
@@ -316,15 +256,12 @@ obj-mips-y += cirrus_vga.o
obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o
obj-microblaze-y = petalogix_s3adsp1800_mmu.o
obj-microblaze-y += petalogix_ml605_mmu.o
obj-microblaze-y += microblaze_pic_cpu.o
obj-microblaze-y += xilinx_intc.o
obj-microblaze-y += xilinx_timer.o
obj-microblaze-y += xilinx_uartlite.o
obj-microblaze-y += xilinx_ethlite.o
obj-microblaze-y += xilinx_axidma.o
obj-microblaze-y += xilinx_axienet.o
obj-microblaze-$(CONFIG_FDT) += device_tree.o
@@ -378,9 +315,6 @@ obj-arm-y += framebuffer.o
obj-arm-y += syborg.o syborg_fb.o syborg_interrupt.o syborg_keyboard.o
obj-arm-y += syborg_serial.o syborg_timer.o syborg_pointer.o syborg_rtc.o
obj-arm-y += syborg_virtio.o
obj-arm-y += vexpress.o
obj-arm-y += strongarm.o
obj-arm-y += collie.o
obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o
@@ -391,13 +325,7 @@ obj-m68k-y += m68k-semi.o dummy_m68k.o
obj-s390x-y = s390-virtio-bus.o s390-virtio.o
obj-alpha-y = i8259.o mc146818rtc.o
obj-alpha-y += vga.o cirrus_vga.o
ifeq ($(TARGET_ARCH), ia64)
firmware.o: firmware.c
$(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
endif
obj-alpha-y = alpha_palcode.o
main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
@@ -412,12 +340,6 @@ obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y))
endif # CONFIG_SOFTMMU
ifndef CONFIG_LINUX_USER
# libcacard needs qemu-thread support, and besides is only needed by devices
# so not requires with linux-user targets
obj-$(CONFIG_SMARTCARD_NSS) += $(addprefix ../libcacard/, $(libcacard-y))
endif # CONFIG_LINUX_USER
obj-y += $(addprefix ../, $(trace-obj-y))
obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
@@ -436,7 +358,7 @@ qmp-commands.h: $(SRC_PATH)/qmp-commands.hx
clean:
rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o
rm -f *.d */*.d tcg/*.o ide/*.o 9pfs/*.o
rm -f *.d */*.d tcg/*.o ide/*.o
rm -f hmp-commands.h qmp-commands.h gdbstub-xml.c
ifdef CONFIG_SYSTEMTAP_TRACE
rm -f *.stp

View File

@@ -22,24 +22,19 @@ class QMPCapabilitiesError(QMPError):
pass
class QEMUMonitorProtocol:
def __init__(self, address, server=False):
def __init__(self, address):
"""
Create a QEMUMonitorProtocol class.
@param address: QEMU address, can be either a unix socket path (string)
or a tuple in the form ( address, port ) for a TCP
connection
@param server: server mode listens on the socket (bool)
@raise socket.error on socket connection errors
@note No connection is established, this is done by the connect() or
accept() methods
@note No connection is established, this is done by the connect() method
"""
self.__events = []
self.__address = address
self.__sock = self.__get_sock()
if server:
self.__sock.bind(self.__address)
self.__sock.listen(1)
self.__sockfile = self.__sock.makefile()
def __get_sock(self):
if isinstance(self.__address, tuple):
@@ -48,18 +43,7 @@ class QEMUMonitorProtocol:
family = socket.AF_UNIX
return socket.socket(family, socket.SOCK_STREAM)
def __negotiate_capabilities(self):
self.__sockfile = self.__sock.makefile()
greeting = self.__json_read()
if greeting is None or not greeting.has_key('QMP'):
raise QMPConnectError
# Greeting seems ok, negotiate capabilities
resp = self.cmd('qmp_capabilities')
if "return" in resp:
return greeting
raise QMPCapabilitiesError
def __json_read(self, only_event=False):
def __json_read(self):
while True:
data = self.__sockfile.readline()
if not data:
@@ -67,8 +51,7 @@ class QEMUMonitorProtocol:
resp = json.loads(data)
if 'event' in resp:
self.__events.append(resp)
if not only_event:
continue
continue
return resp
error = socket.error
@@ -83,19 +66,14 @@ class QEMUMonitorProtocol:
@raise QMPCapabilitiesError if fails to negotiate capabilities
"""
self.__sock.connect(self.__address)
return self.__negotiate_capabilities()
def accept(self):
"""
Await connection from QMP Monitor and perform capabilities negotiation.
@return QMP greeting dict
@raise socket.error on socket connection errors
@raise QMPConnectError if the greeting is not received
@raise QMPCapabilitiesError if fails to negotiate capabilities
"""
self.__sock, _ = self.__sock.accept()
return self.__negotiate_capabilities()
greeting = self.__json_read()
if greeting is None or not greeting.has_key('QMP'):
raise QMPConnectError
# Greeting seems ok, negotiate capabilities
resp = self.cmd('qmp_capabilities')
if "return" in resp:
return greeting
raise QMPCapabilitiesError
def cmd_obj(self, qmp_cmd):
"""
@@ -128,11 +106,9 @@ class QEMUMonitorProtocol:
qmp_cmd['id'] = id
return self.cmd_obj(qmp_cmd)
def get_events(self, wait=False):
def get_events(self):
"""
Get a list of available QMP events.
@param wait: block until an event is available (bool)
"""
self.__sock.setblocking(0)
try:
@@ -142,8 +118,6 @@ class QEMUMonitorProtocol:
# No data available
pass
self.__sock.setblocking(1)
if not self.__events and wait:
self.__json_read(only_event=True)
return self.__events
def clear_events(self):

View File

@@ -1 +1 @@
0.15.1
0.14.1

1
acl.c
View File

@@ -24,6 +24,7 @@
#include "qemu-common.h"
#include "sysemu.h"
#include "acl.h"
#ifdef CONFIG_FNMATCH

View File

@@ -238,6 +238,10 @@ extern const unsigned alpha_num_operands;
#define AXP_REG_SP 30
#define AXP_REG_ZERO 31
#define bfd_mach_alpha_ev4 0x10
#define bfd_mach_alpha_ev5 0x20
#define bfd_mach_alpha_ev6 0x30
enum bfd_reloc_code_real {
BFD_RELOC_23_PCREL_S2,
BFD_RELOC_ALPHA_HINT

View File

@@ -64,8 +64,6 @@ const char arch_config_name[] = CONFIG_QEMU_CONFDIR "/target-" TARGET_ARCH ".con
#define QEMU_ARCH QEMU_ARCH_I386
#elif defined(TARGET_M68K)
#define QEMU_ARCH QEMU_ARCH_M68K
#elif defined(TARGET_LM32)
#define QEMU_ARCH QEMU_ARCH_LM32
#elif defined(TARGET_MICROBLAZE)
#define QEMU_ARCH QEMU_ARCH_MICROBLAZE
#elif defined(TARGET_MIPS)
@@ -709,11 +707,6 @@ int audio_available(void)
#endif
}
int tcg_available(void)
{
return 1;
}
int kvm_available(void)
{
#ifdef CONFIG_KVM

View File

@@ -10,24 +10,24 @@ enum {
QEMU_ARCH_CRIS = 4,
QEMU_ARCH_I386 = 8,
QEMU_ARCH_M68K = 16,
QEMU_ARCH_LM32 = 32,
QEMU_ARCH_MICROBLAZE = 64,
QEMU_ARCH_MIPS = 128,
QEMU_ARCH_PPC = 256,
QEMU_ARCH_S390X = 512,
QEMU_ARCH_SH4 = 1024,
QEMU_ARCH_SPARC = 2048,
QEMU_ARCH_MICROBLAZE = 32,
QEMU_ARCH_MIPS = 64,
QEMU_ARCH_PPC = 128,
QEMU_ARCH_S390X = 256,
QEMU_ARCH_SH4 = 512,
QEMU_ARCH_SPARC = 1024,
};
extern const uint32_t arch_type;
void select_soundhw(const char *optarg);
int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque);
int ram_load(QEMUFile *f, void *opaque, int version_id);
void do_acpitable_option(const char *optarg);
void do_smbios_option(const char *optarg);
void cpudef_init(void);
int audio_available(void);
void audio_init(qemu_irq *isa_pic, PCIBus *pci_bus);
int tcg_available(void);
int kvm_available(void);
int xen_available(void);

View File

@@ -33,8 +33,8 @@
#define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024)
#else
#include "qemu-common.h"
#include "sysemu.h"
#include "gdbstub.h"
#include "hw/arm-misc.h"
#endif
#define SYS_OPEN 0x01
@@ -370,88 +370,68 @@ uint32_t do_arm_semihosting(CPUState *env)
return syscall_err;
#endif
case SYS_GET_CMDLINE:
#ifdef CONFIG_USER_ONLY
/* Build a commandline from the original argv. */
{
/* Build a command-line from the original argv.
*
* The inputs are:
* * ARG(0), pointer to a buffer of at least the size
* specified in ARG(1).
* * ARG(1), size of the buffer pointed to by ARG(0) in
* bytes.
*
* The outputs are:
* * ARG(0), pointer to null-terminated string of the
* command line.
* * ARG(1), length of the string pointed to by ARG(0).
*/
char *arm_cmdline_buffer;
const char *host_cmdline_buffer;
char *output_buffer;
size_t input_size = ARG(1);
size_t output_size;
int status = 0;
/* Compute the size of the output string. */
#if !defined(CONFIG_USER_ONLY)
output_size = strlen(ts->boot_info->kernel_filename)
+ 1 /* Separating space. */
+ strlen(ts->boot_info->kernel_cmdline)
+ 1; /* Terminating null byte. */
#else
unsigned int i;
unsigned int arm_cmdline_len = ARG(1);
unsigned int host_cmdline_len =
ts->info->arg_end-ts->info->arg_start;
output_size = ts->info->arg_end - ts->info->arg_start;
if (!output_size) {
if (!arm_cmdline_len || host_cmdline_len > arm_cmdline_len) {
return -1; /* not enough space to store command line */
}
if (!host_cmdline_len) {
/* We special-case the "empty command line" case (argc==0).
Just provide the terminating 0. */
output_size = 1;
}
#endif
arm_cmdline_buffer = lock_user(VERIFY_WRITE, ARG(0), 1, 0);
arm_cmdline_buffer[0] = 0;
unlock_user(arm_cmdline_buffer, ARG(0), 1);
if (output_size > input_size) {
/* Not enough space to store command-line arguments. */
return -1;
/* Adjust the commandline length argument. */
SET_ARG(1, 0);
return 0;
}
/* Adjust the command-line length. */
SET_ARG(1, output_size - 1);
/* lock the buffers on the ARM side */
arm_cmdline_buffer =
lock_user(VERIFY_WRITE, ARG(0), host_cmdline_len, 0);
host_cmdline_buffer =
lock_user(VERIFY_READ, ts->info->arg_start,
host_cmdline_len, 1);
/* Lock the buffer on the ARM side. */
output_buffer = lock_user(VERIFY_WRITE, ARG(0), output_size, 0);
if (!output_buffer) {
return -1;
}
if (arm_cmdline_buffer && host_cmdline_buffer)
{
/* the last argument is zero-terminated;
no need for additional termination */
memcpy(arm_cmdline_buffer, host_cmdline_buffer,
host_cmdline_len);
/* Copy the command-line arguments. */
#if !defined(CONFIG_USER_ONLY)
pstrcpy(output_buffer, output_size, ts->boot_info->kernel_filename);
pstrcat(output_buffer, output_size, " ");
pstrcat(output_buffer, output_size, ts->boot_info->kernel_cmdline);
#else
if (output_size == 1) {
/* Empty command-line. */
output_buffer[0] = '\0';
goto out;
}
if (copy_from_user(output_buffer, ts->info->arg_start,
output_size)) {
status = -1;
goto out;
}
/* Separate arguments by white spaces. */
for (i = 0; i < output_size - 1; i++) {
if (output_buffer[i] == 0) {
output_buffer[i] = ' ';
/* separate arguments by white spaces */
for (i = 0; i < host_cmdline_len-1; i++) {
if (arm_cmdline_buffer[i] == 0) {
arm_cmdline_buffer[i] = ' ';
}
}
}
out:
#endif
/* Unlock the buffer on the ARM side. */
unlock_user(output_buffer, ARG(0), output_size);
return status;
/* Adjust the commandline length argument. */
SET_ARG(1, host_cmdline_len-1);
}
/* Unlock the buffers on the ARM side. */
unlock_user(arm_cmdline_buffer, ARG(0), host_cmdline_len);
unlock_user((void*)host_cmdline_buffer, ts->info->arg_start, 0);
/* Return success if we could return a commandline. */
return (arm_cmdline_buffer && host_cmdline_buffer) ? 0 : -1;
}
#else
return -1;
#endif
case SYS_HEAPINFO:
{
uint32_t *ptr;
@@ -461,16 +441,15 @@ uint32_t do_arm_semihosting(CPUState *env)
/* Some C libraries assume the heap immediately follows .bss, so
allocate it using sbrk. */
if (!ts->heap_limit) {
abi_ulong ret;
long ret;
ts->heap_base = do_brk(0);
limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;
/* Try a big heap, and reduce the size if that fails. */
for (;;) {
ret = do_brk(limit);
if (ret >= limit) {
if (ret != -1)
break;
}
limit = (ts->heap_base >> 1) + (limit >> 1);
}
ts->heap_limit = limit;

12
arm.ld
View File

@@ -71,23 +71,23 @@ SECTIONS
.data1 : { *(.data1) }
.preinit_array :
{
PROVIDE (__preinit_array_start = .);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE (__init_array_start = .);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE (__init_array_end = .);
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE (__fini_array_start = .);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE (__fini_array_end = .);
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{

View File

@@ -137,12 +137,11 @@ QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
int qemu_bh_poll(void)
{
QEMUBH *bh, **bhp, *next;
QEMUBH *bh, **bhp;
int ret;
ret = 0;
for (bh = async_context->first_bh; bh; bh = next) {
next = bh->next;
for (bh = async_context->first_bh; bh; bh = bh->next) {
if (!bh->deleted && bh->scheduled) {
bh->scheduled = 0;
if (!bh->idle)

View File

@@ -1114,7 +1114,7 @@ static int audio_is_timer_needed (void)
static void audio_reset_timer (AudioState *s)
{
if (audio_is_timer_needed ()) {
qemu_mod_timer (s->ts, qemu_get_clock_ns (vm_clock) + 1);
qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
}
else {
qemu_del_timer (s->ts);
@@ -1820,7 +1820,7 @@ static void audio_init (void)
QLIST_INIT (&s->cap_head);
atexit (audio_atexit);
s->ts = qemu_new_timer_ns (vm_clock, audio_timer, s);
s->ts = qemu_new_timer (vm_clock, audio_timer, s);
if (!s->ts) {
hw_error("Could not create audio timer\n");
}

View File

@@ -6,6 +6,8 @@
#include "audio_int.h"
#include "audio_pt_int.h"
#include <signal.h>
static void GCC_FMT_ATTR(3, 4) logerr (struct audio_pt *pt, int err,
const char *fmt, ...)
{

View File

@@ -56,7 +56,7 @@ typedef struct coreaudioVoiceOut {
static void coreaudio_logstatus (OSStatus status)
{
const char *str = "BUG";
char *str = "BUG";
switch(status) {
case kAudioHardwareNoError:
@@ -104,7 +104,7 @@ static void coreaudio_logstatus (OSStatus status)
break;
default:
AUD_log (AUDIO_CAP, "Reason: status code %" PRId32 "\n", (int32_t)status);
AUD_log (AUDIO_CAP, "Reason: status code %ld\n", status);
return;
}
@@ -360,8 +360,8 @@ static int coreaudio_init_out (HWVoiceOut *hw, struct audsettings *as)
&core->audioDevicePropertyBufferFrameSize);
if (status != kAudioHardwareNoError) {
coreaudio_logerr2 (status, typ,
"Could not set device buffer frame size %" PRIu32 "\n",
(uint32_t)core->audioDevicePropertyBufferFrameSize);
"Could not set device buffer frame size %ld\n",
core->audioDevicePropertyBufferFrameSize);
return -1;
}

View File

@@ -46,7 +46,7 @@ static mixeng_real inline glue (conv_, ET) (IN_T v)
#endif
#else /* !RECIPROCAL */
#ifdef SIGNED
return nv / (mixeng_real) ((mixeng_real) IN_MAX - IN_MIN);
return nv / (mixeng_real) (IN_MAX - IN_MIN);
#else
return (nv - HALF) / (mixeng_real) IN_MAX;
#endif
@@ -63,7 +63,7 @@ static IN_T inline glue (clip_, ET) (mixeng_real v)
}
#ifdef SIGNED
return ENDIAN_CONVERT ((IN_T) (v * ((mixeng_real) IN_MAX - IN_MIN)));
return ENDIAN_CONVERT ((IN_T) (v * (IN_MAX - IN_MIN)));
#else
return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF));
#endif

View File

@@ -46,7 +46,7 @@ static int no_run_out (HWVoiceOut *hw, int live)
int64_t ticks;
int64_t bytes;
now = qemu_get_clock_ns (vm_clock);
now = qemu_get_clock (vm_clock);
ticks = now - no->old_ticks;
bytes = muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());
bytes = audio_MIN (bytes, INT_MAX);
@@ -102,7 +102,7 @@ static int no_run_in (HWVoiceIn *hw)
int samples = 0;
if (dead) {
int64_t now = qemu_get_clock_ns (vm_clock);
int64_t now = qemu_get_clock (vm_clock);
int64_t ticks = now - no->old_ticks;
int64_t bytes =
muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());

View File

@@ -32,6 +32,7 @@
#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
#include <pthread.h>
#endif
#include <signal.h>
#endif
#define AUDIO_CAP "sdl"
@@ -138,36 +139,36 @@ static int aud_to_sdlfmt (audfmt_e fmt)
}
}
static int sdl_to_audfmt(int sdlfmt, audfmt_e *fmt, int *endianness)
static int sdl_to_audfmt (int sdlfmt, audfmt_e *fmt, int *endianess)
{
switch (sdlfmt) {
case AUDIO_S8:
*endianness = 0;
*endianess = 0;
*fmt = AUD_FMT_S8;
break;
case AUDIO_U8:
*endianness = 0;
*endianess = 0;
*fmt = AUD_FMT_U8;
break;
case AUDIO_S16LSB:
*endianness = 0;
*endianess = 0;
*fmt = AUD_FMT_S16;
break;
case AUDIO_U16LSB:
*endianness = 0;
*endianess = 0;
*fmt = AUD_FMT_U16;
break;
case AUDIO_S16MSB:
*endianness = 1;
*endianess = 1;
*fmt = AUD_FMT_S16;
break;
case AUDIO_U16MSB:
*endianness = 1;
*endianess = 1;
*fmt = AUD_FMT_U16;
break;
@@ -337,7 +338,7 @@ static int sdl_init_out (HWVoiceOut *hw, struct audsettings *as)
SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
SDLAudioState *s = &glob_sdl;
SDL_AudioSpec req, obt;
int endianness;
int endianess;
int err;
audfmt_e effective_fmt;
struct audsettings obt_as;
@@ -353,7 +354,7 @@ static int sdl_init_out (HWVoiceOut *hw, struct audsettings *as)
return -1;
}
err = sdl_to_audfmt(obt.format, &effective_fmt, &endianness);
err = sdl_to_audfmt (obt.format, &effective_fmt, &endianess);
if (err) {
sdl_close (s);
return -1;
@@ -362,7 +363,7 @@ static int sdl_init_out (HWVoiceOut *hw, struct audsettings *as)
obt_as.freq = obt.freq;
obt_as.nchannels = obt.channels;
obt_as.fmt = effective_fmt;
obt_as.endianness = endianness;
obt_as.endianness = endianess;
audio_pcm_init_info (&hw->info, &obt_as);
hw->samples = obt.samples;

View File

@@ -81,7 +81,7 @@ static void spice_audio_fini (void *opaque)
static void rate_start (SpiceRateCtl *rate)
{
memset (rate, 0, sizeof (*rate));
rate->start_ticks = qemu_get_clock_ns (vm_clock);
rate->start_ticks = qemu_get_clock (vm_clock);
}
static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate)
@@ -91,7 +91,7 @@ static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate)
int64_t bytes;
int64_t samples;
now = qemu_get_clock_ns (vm_clock);
now = qemu_get_clock (vm_clock);
ticks = now - rate->start_ticks;
bytes = muldiv64 (ticks, info->bytes_per_second, get_ticks_per_sec ());
samples = (bytes - rate->bytes_sent) >> info->shift;

View File

@@ -52,7 +52,7 @@ static int wav_run_out (HWVoiceOut *hw, int live)
int rpos, decr, samples;
uint8_t *dst;
struct st_sample *src;
int64_t now = qemu_get_clock_ns (vm_clock);
int64_t now = qemu_get_clock (vm_clock);
int64_t ticks = now - wav->old_ticks;
int64_t bytes =
muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());

View File

@@ -1,9 +1,7 @@
/*
* Generic Balloon handlers and management
* QEMU System Emulator
*
* Copyright (c) 2003-2008 Fabrice Bellard
* Copyright (C) 2011 Red Hat, Inc.
* Copyright (C) 2011 Amit Shah <amit.shah@redhat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,6 +22,7 @@
* THE SOFTWARE.
*/
#include "sysemu.h"
#include "monitor.h"
#include "qjson.h"
#include "qint.h"
@@ -32,53 +31,44 @@
#include "balloon.h"
#include "trace.h"
static QEMUBalloonEvent *balloon_event_fn;
static QEMUBalloonStatus *balloon_stat_fn;
static void *balloon_opaque;
int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
QEMUBalloonStatus *stat_func, void *opaque)
static QEMUBalloonEvent *qemu_balloon_event;
void *qemu_balloon_event_opaque;
void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
{
if (balloon_event_fn || balloon_stat_fn || balloon_opaque) {
/* We're already registered one balloon handler. How many can
* a guest really have?
*/
error_report("Another balloon device already registered");
return -1;
}
balloon_event_fn = event_func;
balloon_stat_fn = stat_func;
balloon_opaque = opaque;
return 0;
qemu_balloon_event = func;
qemu_balloon_event_opaque = opaque;
}
static int qemu_balloon(ram_addr_t target)
int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque)
{
if (!balloon_event_fn) {
if (qemu_balloon_event) {
trace_balloon_event(qemu_balloon_event_opaque, target);
qemu_balloon_event(qemu_balloon_event_opaque, target, cb, opaque);
return 1;
} else {
return 0;
}
trace_balloon_event(balloon_opaque, target);
balloon_event_fn(balloon_opaque, target);
return 1;
}
static int qemu_balloon_status(MonitorCompletion cb, void *opaque)
int qemu_balloon_status(MonitorCompletion cb, void *opaque)
{
if (!balloon_stat_fn) {
if (qemu_balloon_event) {
qemu_balloon_event(qemu_balloon_event_opaque, 0, cb, opaque);
return 1;
} else {
return 0;
}
balloon_stat_fn(balloon_opaque, cb, opaque);
return 1;
}
static void print_balloon_stat(const char *key, QObject *obj, void *opaque)
{
Monitor *mon = opaque;
if (strcmp(key, "actual")) {
if (strcmp(key, "actual"))
monitor_printf(mon, ",%s=%" PRId64, key,
qint_get_int(qobject_to_qint(obj)));
}
}
void monitor_print_balloon(Monitor *mon, const QObject *data)
@@ -86,9 +76,9 @@ void monitor_print_balloon(Monitor *mon, const QObject *data)
QDict *qdict;
qdict = qobject_to_qdict(data);
if (!qdict_haskey(qdict, "actual")) {
if (!qdict_haskey(qdict, "actual"))
return;
}
monitor_printf(mon, "balloon: actual=%" PRId64,
qdict_get_int(qdict, "actual") >> 20);
qdict_iter(qdict, print_balloon_stat, mon);
@@ -140,7 +130,6 @@ int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque)
int do_balloon(Monitor *mon, const QDict *params,
MonitorCompletion cb, void *opaque)
{
int64_t target;
int ret;
if (kvm_enabled() && !kvm_has_sync_mmu()) {
@@ -148,12 +137,7 @@ int do_balloon(Monitor *mon, const QDict *params,
return -1;
}
target = qdict_get_int(params, "value");
if (target <= 0) {
qerror_report(QERR_INVALID_PARAMETER_VALUE, "target", "a size");
return -1;
}
ret = qemu_balloon(target);
ret = qemu_balloon(qdict_get_int(params, "value"), cb, opaque);
if (ret == 0) {
qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
return -1;

View File

@@ -16,12 +16,14 @@
#include "monitor.h"
typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target);
typedef void (QEMUBalloonStatus)(void *opaque, MonitorCompletion cb,
void *cb_data);
typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target,
MonitorCompletion cb, void *cb_data);
int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
QEMUBalloonStatus *stat_func, void *opaque);
void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque);
int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque);
int qemu_balloon_status(MonitorCompletion cb, void *opaque);
void monitor_print_balloon(Monitor *mon, const QObject *data);
int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque);

256
bitmap.c
View File

@@ -1,256 +0,0 @@
/*
* Bitmap Module
*
* Stolen from linux/src/lib/bitmap.c
*
* Copyright (C) 2010 Corentin Chary
*
* This source code is licensed under the GNU General Public License,
* Version 2.
*/
#include "bitops.h"
#include "bitmap.h"
/*
* bitmaps provide an array of bits, implemented using an an
* array of unsigned longs. The number of valid bits in a
* given bitmap does _not_ need to be an exact multiple of
* BITS_PER_LONG.
*
* The possible unused bits in the last, partially used word
* of a bitmap are 'don't care'. The implementation makes
* no particular effort to keep them zero. It ensures that
* their value will not affect the results of any operation.
* The bitmap operations that return Boolean (bitmap_empty,
* for example) or scalar (bitmap_weight, for example) results
* carefully filter out these unused bits from impacting their
* results.
*
* These operations actually hold to a slightly stronger rule:
* if you don't input any bitmaps to these ops that have some
* unused bits set, then they won't output any set unused bits
* in output bitmaps.
*
* The byte ordering of bitmaps is more natural on little
* endian architectures.
*/
int slow_bitmap_empty(const unsigned long *bitmap, int bits)
{
int k, lim = bits/BITS_PER_LONG;
for (k = 0; k < lim; ++k) {
if (bitmap[k]) {
return 0;
}
}
if (bits % BITS_PER_LONG) {
if (bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) {
return 0;
}
}
return 1;
}
int slow_bitmap_full(const unsigned long *bitmap, int bits)
{
int k, lim = bits/BITS_PER_LONG;
for (k = 0; k < lim; ++k) {
if (~bitmap[k]) {
return 0;
}
}
if (bits % BITS_PER_LONG) {
if (~bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) {
return 0;
}
}
return 1;
}
int slow_bitmap_equal(const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits)
{
int k, lim = bits/BITS_PER_LONG;
for (k = 0; k < lim; ++k) {
if (bitmap1[k] != bitmap2[k]) {
return 0;
}
}
if (bits % BITS_PER_LONG) {
if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) {
return 0;
}
}
return 1;
}
void slow_bitmap_complement(unsigned long *dst, const unsigned long *src,
int bits)
{
int k, lim = bits/BITS_PER_LONG;
for (k = 0; k < lim; ++k) {
dst[k] = ~src[k];
}
if (bits % BITS_PER_LONG) {
dst[k] = ~src[k] & BITMAP_LAST_WORD_MASK(bits);
}
}
int slow_bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits)
{
int k;
int nr = BITS_TO_LONGS(bits);
unsigned long result = 0;
for (k = 0; k < nr; k++) {
result |= (dst[k] = bitmap1[k] & bitmap2[k]);
}
return result != 0;
}
void slow_bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits)
{
int k;
int nr = BITS_TO_LONGS(bits);
for (k = 0; k < nr; k++) {
dst[k] = bitmap1[k] | bitmap2[k];
}
}
void slow_bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits)
{
int k;
int nr = BITS_TO_LONGS(bits);
for (k = 0; k < nr; k++) {
dst[k] = bitmap1[k] ^ bitmap2[k];
}
}
int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits)
{
int k;
int nr = BITS_TO_LONGS(bits);
unsigned long result = 0;
for (k = 0; k < nr; k++) {
result |= (dst[k] = bitmap1[k] & ~bitmap2[k]);
}
return result != 0;
}
#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG))
void bitmap_set(unsigned long *map, int start, int nr)
{
unsigned long *p = map + BIT_WORD(start);
const int size = start + nr;
int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
while (nr - bits_to_set >= 0) {
*p |= mask_to_set;
nr -= bits_to_set;
bits_to_set = BITS_PER_LONG;
mask_to_set = ~0UL;
p++;
}
if (nr) {
mask_to_set &= BITMAP_LAST_WORD_MASK(size);
*p |= mask_to_set;
}
}
void bitmap_clear(unsigned long *map, int start, int nr)
{
unsigned long *p = map + BIT_WORD(start);
const int size = start + nr;
int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
while (nr - bits_to_clear >= 0) {
*p &= ~mask_to_clear;
nr -= bits_to_clear;
bits_to_clear = BITS_PER_LONG;
mask_to_clear = ~0UL;
p++;
}
if (nr) {
mask_to_clear &= BITMAP_LAST_WORD_MASK(size);
*p &= ~mask_to_clear;
}
}
#define ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
/**
* bitmap_find_next_zero_area - find a contiguous aligned zero area
* @map: The address to base the search on
* @size: The bitmap size in bits
* @start: The bitnumber to start searching at
* @nr: The number of zeroed bits we're looking for
* @align_mask: Alignment mask for zero area
*
* The @align_mask should be one less than a power of 2; the effect is that
* the bit offset of all zero areas this function finds is multiples of that
* power of 2. A @align_mask of 0 means no alignment is required.
*/
unsigned long bitmap_find_next_zero_area(unsigned long *map,
unsigned long size,
unsigned long start,
unsigned int nr,
unsigned long align_mask)
{
unsigned long index, end, i;
again:
index = find_next_zero_bit(map, size, start);
/* Align allocation */
index = ALIGN_MASK(index, align_mask);
end = index + nr;
if (end > size) {
return end;
}
i = find_next_bit(map, end, index);
if (i < end) {
start = i + 1;
goto again;
}
return index;
}
int slow_bitmap_intersects(const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits)
{
int k, lim = bits/BITS_PER_LONG;
for (k = 0; k < lim; ++k) {
if (bitmap1[k] & bitmap2[k]) {
return 1;
}
}
if (bits % BITS_PER_LONG) {
if ((bitmap1[k] & bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) {
return 1;
}
}
return 0;
}

222
bitmap.h
View File

@@ -1,222 +0,0 @@
/*
* Bitmap Module
*
* Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
*
* Mostly inspired by (stolen from) linux/bitmap.h and linux/bitops.h
*
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
* See the COPYING.LIB file in the top-level directory.
*/
#ifndef BITMAP_H
#define BITMAP_H
#include "qemu-common.h"
#include "bitops.h"
/*
* The available bitmap operations and their rough meaning in the
* case that the bitmap is a single unsigned long are thus:
*
* Note that nbits should be always a compile time evaluable constant.
* Otherwise many inlines will generate horrible code.
*
* bitmap_zero(dst, nbits) *dst = 0UL
* bitmap_fill(dst, nbits) *dst = ~0UL
* bitmap_copy(dst, src, nbits) *dst = *src
* bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2
* bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2
* bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2
* bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2)
* bitmap_complement(dst, src, nbits) *dst = ~(*src)
* bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal?
* bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap?
* bitmap_empty(src, nbits) Are all bits zero in *src?
* bitmap_full(src, nbits) Are all bits set in *src?
* bitmap_set(dst, pos, nbits) Set specified bit area
* bitmap_clear(dst, pos, nbits) Clear specified bit area
* bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area
*/
/*
* Also the following operations apply to bitmaps.
*
* set_bit(bit, addr) *addr |= bit
* clear_bit(bit, addr) *addr &= ~bit
* change_bit(bit, addr) *addr ^= bit
* test_bit(bit, addr) Is bit set in *addr?
* test_and_set_bit(bit, addr) Set bit and return old value
* test_and_clear_bit(bit, addr) Clear bit and return old value
* test_and_change_bit(bit, addr) Change bit and return old value
* find_first_zero_bit(addr, nbits) Position first zero bit in *addr
* find_first_bit(addr, nbits) Position first set bit in *addr
* find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit
* find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit
*/
#define BITMAP_LAST_WORD_MASK(nbits) \
( \
((nbits) % BITS_PER_LONG) ? \
(1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \
)
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
#define small_nbits(nbits) \
((nbits) <= BITS_PER_LONG)
int slow_bitmap_empty(const unsigned long *bitmap, int bits);
int slow_bitmap_full(const unsigned long *bitmap, int bits);
int slow_bitmap_equal(const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits);
void slow_bitmap_complement(unsigned long *dst, const unsigned long *src,
int bits);
void slow_bitmap_shift_right(unsigned long *dst,
const unsigned long *src, int shift, int bits);
void slow_bitmap_shift_left(unsigned long *dst,
const unsigned long *src, int shift, int bits);
int slow_bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits);
void slow_bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits);
void slow_bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits);
int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits);
int slow_bitmap_intersects(const unsigned long *bitmap1,
const unsigned long *bitmap2, int bits);
static inline unsigned long *bitmap_new(int nbits)
{
int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
return qemu_mallocz(len);
}
static inline void bitmap_zero(unsigned long *dst, int nbits)
{
if (small_nbits(nbits)) {
*dst = 0UL;
} else {
int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
memset(dst, 0, len);
}
}
static inline void bitmap_fill(unsigned long *dst, int nbits)
{
size_t nlongs = BITS_TO_LONGS(nbits);
if (!small_nbits(nbits)) {
int len = (nlongs - 1) * sizeof(unsigned long);
memset(dst, 0xff, len);
}
dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
}
static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
int nbits)
{
if (small_nbits(nbits)) {
*dst = *src;
} else {
int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
memcpy(dst, src, len);
}
}
static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
const unsigned long *src2, int nbits)
{
if (small_nbits(nbits)) {
return (*dst = *src1 & *src2) != 0;
}
return slow_bitmap_and(dst, src1, src2, nbits);
}
static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
const unsigned long *src2, int nbits)
{
if (small_nbits(nbits)) {
*dst = *src1 | *src2;
} else {
slow_bitmap_or(dst, src1, src2, nbits);
}
}
static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
const unsigned long *src2, int nbits)
{
if (small_nbits(nbits)) {
*dst = *src1 ^ *src2;
} else {
slow_bitmap_xor(dst, src1, src2, nbits);
}
}
static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1,
const unsigned long *src2, int nbits)
{
if (small_nbits(nbits)) {
return (*dst = *src1 & ~(*src2)) != 0;
}
return slow_bitmap_andnot(dst, src1, src2, nbits);
}
static inline void bitmap_complement(unsigned long *dst, const unsigned long *src,
int nbits)
{
if (small_nbits(nbits)) {
*dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits);
} else {
slow_bitmap_complement(dst, src, nbits);
}
}
static inline int bitmap_equal(const unsigned long *src1,
const unsigned long *src2, int nbits)
{
if (small_nbits(nbits)) {
return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
} else {
return slow_bitmap_equal(src1, src2, nbits);
}
}
static inline int bitmap_empty(const unsigned long *src, int nbits)
{
if (small_nbits(nbits)) {
return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
} else {
return slow_bitmap_empty(src, nbits);
}
}
static inline int bitmap_full(const unsigned long *src, int nbits)
{
if (small_nbits(nbits)) {
return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
} else {
return slow_bitmap_full(src, nbits);
}
}
static inline int bitmap_intersects(const unsigned long *src1,
const unsigned long *src2, int nbits)
{
if (small_nbits(nbits)) {
return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
} else {
return slow_bitmap_intersects(src1, src2, nbits);
}
}
void bitmap_set(unsigned long *map, int i, int len);
void bitmap_clear(unsigned long *map, int start, int nr);
unsigned long bitmap_find_next_zero_area(unsigned long *map,
unsigned long size,
unsigned long start,
unsigned int nr,
unsigned long align_mask);
#endif /* BITMAP_H */

142
bitops.c
View File

@@ -1,142 +0,0 @@
/*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
* Copyright (C) 2008 IBM Corporation
* Written by Rusty Russell <rusty@rustcorp.com.au>
* (Inspired by David Howell's find_next_bit implementation)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include "bitops.h"
#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
/*
* Find the next set bit in a memory region.
*/
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
const unsigned long *p = addr + BITOP_WORD(offset);
unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;
if (offset >= size) {
return size;
}
size -= result;
offset %= BITS_PER_LONG;
if (offset) {
tmp = *(p++);
tmp &= (~0UL << offset);
if (size < BITS_PER_LONG) {
goto found_first;
}
if (tmp) {
goto found_middle;
}
size -= BITS_PER_LONG;
result += BITS_PER_LONG;
}
while (size & ~(BITS_PER_LONG-1)) {
if ((tmp = *(p++))) {
goto found_middle;
}
result += BITS_PER_LONG;
size -= BITS_PER_LONG;
}
if (!size) {
return result;
}
tmp = *p;
found_first:
tmp &= (~0UL >> (BITS_PER_LONG - size));
if (tmp == 0UL) { /* Are any bits set? */
return result + size; /* Nope. */
}
found_middle:
return result + bitops_ffsl(tmp);
}
/*
* This implementation of find_{first,next}_zero_bit was stolen from
* Linus' asm-alpha/bitops.h.
*/
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
const unsigned long *p = addr + BITOP_WORD(offset);
unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;
if (offset >= size) {
return size;
}
size -= result;
offset %= BITS_PER_LONG;
if (offset) {
tmp = *(p++);
tmp |= ~0UL >> (BITS_PER_LONG - offset);
if (size < BITS_PER_LONG) {
goto found_first;
}
if (~tmp) {
goto found_middle;
}
size -= BITS_PER_LONG;
result += BITS_PER_LONG;
}
while (size & ~(BITS_PER_LONG-1)) {
if (~(tmp = *(p++))) {
goto found_middle;
}
result += BITS_PER_LONG;
size -= BITS_PER_LONG;
}
if (!size) {
return result;
}
tmp = *p;
found_first:
tmp |= ~0UL << size;
if (tmp == ~0UL) { /* Are any bits zero? */
return result + size; /* Nope. */
}
found_middle:
return result + ffz(tmp);
}
unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
{
unsigned long words;
unsigned long tmp;
/* Start at final word. */
words = size / BITS_PER_LONG;
/* Partial final word? */
if (size & (BITS_PER_LONG-1)) {
tmp = (addr[words] & (~0UL >> (BITS_PER_LONG
- (size & (BITS_PER_LONG-1)))));
if (tmp) {
goto found;
}
}
while (words) {
tmp = addr[--words];
if (tmp) {
found:
return words * BITS_PER_LONG + bitops_flsl(tmp);
}
}
/* Not found */
return size;
}

272
bitops.h
View File

@@ -1,272 +0,0 @@
/*
* Bitops Module
*
* Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
*
* Mostly inspired by (stolen from) linux/bitmap.h and linux/bitops.h
*
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
* See the COPYING.LIB file in the top-level directory.
*/
#ifndef BITOPS_H
#define BITOPS_H
#include "qemu-common.h"
#define BITS_PER_BYTE CHAR_BIT
#define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE)
#define BIT(nr) (1UL << (nr))
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
/**
* bitops_ffs - find first bit in word.
* @word: The word to search
*
* Undefined if no bit exists, so code should check against 0 first.
*/
static unsigned long bitops_ffsl(unsigned long word)
{
int num = 0;
#if LONG_MAX > 0x7FFFFFFF
if ((word & 0xffffffff) == 0) {
num += 32;
word >>= 32;
}
#endif
if ((word & 0xffff) == 0) {
num += 16;
word >>= 16;
}
if ((word & 0xff) == 0) {
num += 8;
word >>= 8;
}
if ((word & 0xf) == 0) {
num += 4;
word >>= 4;
}
if ((word & 0x3) == 0) {
num += 2;
word >>= 2;
}
if ((word & 0x1) == 0) {
num += 1;
}
return num;
}
/**
* bitops_fls - find last (most-significant) set bit in a long word
* @word: the word to search
*
* Undefined if no set bit exists, so code should check against 0 first.
*/
static inline unsigned long bitops_flsl(unsigned long word)
{
int num = BITS_PER_LONG - 1;
#if LONG_MAX > 0x7FFFFFFF
if (!(word & (~0ul << 32))) {
num -= 32;
word <<= 32;
}
#endif
if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
num -= 16;
word <<= 16;
}
if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
num -= 8;
word <<= 8;
}
if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
num -= 4;
word <<= 4;
}
if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
num -= 2;
word <<= 2;
}
if (!(word & (~0ul << (BITS_PER_LONG-1))))
num -= 1;
return num;
}
/**
* ffz - find first zero in word.
* @word: The word to search
*
* Undefined if no zero exists, so code should check against ~0UL first.
*/
static inline unsigned long ffz(unsigned long word)
{
return bitops_ffsl(~word);
}
/**
* set_bit - Set a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*/
static inline void set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
*p |= mask;
}
/**
* clear_bit - Clears a bit in memory
* @nr: Bit to clear
* @addr: Address to start counting from
*/
static inline void clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
*p &= ~mask;
}
/**
* change_bit - Toggle a bit in memory
* @nr: Bit to change
* @addr: Address to start counting from
*/
static inline void change_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
*p ^= mask;
}
/**
* test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*/
static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old = *p;
*p = old | mask;
return (old & mask) != 0;
}
/**
* test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to clear
* @addr: Address to count from
*/
static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old = *p;
*p = old & ~mask;
return (old & mask) != 0;
}
/**
* test_and_change_bit - Change a bit and return its old value
* @nr: Bit to change
* @addr: Address to count from
*/
static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old = *p;
*p = old ^ mask;
return (old & mask) != 0;
}
/**
* test_bit - Determine whether a bit is set
* @nr: bit number to test
* @addr: Address to start counting from
*/
static inline int test_bit(int nr, const volatile unsigned long *addr)
{
return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
}
/**
* find_last_bit - find the last set bit in a memory region
* @addr: The address to start the search at
* @size: The maximum size to search
*
* Returns the bit number of the first set bit, or size.
*/
unsigned long find_last_bit(const unsigned long *addr,
unsigned long size);
/**
* find_next_bit - find the next set bit in a memory region
* @addr: The address to base the search on
* @offset: The bitnumber to start searching at
* @size: The bitmap size in bits
*/
unsigned long find_next_bit(const unsigned long *addr,
unsigned long size, unsigned long offset);
/**
* find_next_zero_bit - find the next cleared bit in a memory region
* @addr: The address to base the search on
* @offset: The bitnumber to start searching at
* @size: The bitmap size in bits
*/
unsigned long find_next_zero_bit(const unsigned long *addr,
unsigned long size,
unsigned long offset);
/**
* find_first_bit - find the first set bit in a memory region
* @addr: The address to start the search at
* @size: The maximum size to search
*
* Returns the bit number of the first set bit.
*/
static inline unsigned long find_first_bit(const unsigned long *addr,
unsigned long size)
{
return find_next_bit(addr, size, 0);
}
/**
* find_first_zero_bit - find the first cleared bit in a memory region
* @addr: The address to start the search at
* @size: The maximum size to search
*
* Returns the bit number of the first cleared bit.
*/
static inline unsigned long find_first_zero_bit(const unsigned long *addr,
unsigned long size)
{
return find_next_zero_bit(addr, size, 0);
}
static inline unsigned long hweight_long(unsigned long w)
{
unsigned long count;
for (count = 0; w; w >>= 1) {
count += w & 1;
}
return count;
}
#endif

View File

@@ -62,6 +62,7 @@ typedef struct BlkMigBlock {
QEMUIOVector qiov;
BlockDriverAIOCB *aiocb;
int ret;
int64_t time;
QSIMPLEQ_ENTRY(BlkMigBlock) entry;
} BlkMigBlock;
@@ -77,7 +78,6 @@ typedef struct BlkMigState {
int prev_progress;
int bulk_completed;
long double total_time;
long double prev_time_offset;
int reads;
} BlkMigState;
@@ -131,10 +131,16 @@ uint64_t blk_mig_bytes_total(void)
return sum << BDRV_SECTOR_BITS;
}
static inline void add_avg_read_time(int64_t time)
{
block_mig_state.reads++;
block_mig_state.total_time += time;
}
static inline long double compute_read_bwidth(void)
{
assert(block_mig_state.total_time != 0);
return (block_mig_state.reads / block_mig_state.total_time) * BLOCK_SIZE;
return (block_mig_state.reads * BLOCK_SIZE)/ block_mig_state.total_time;
}
static int bmds_aio_inflight(BlkMigDevState *bmds, int64_t sector)
@@ -185,14 +191,13 @@ static void alloc_aio_bitmap(BlkMigDevState *bmds)
static void blk_mig_read_cb(void *opaque, int ret)
{
long double curr_time = qemu_get_clock_ns(rt_clock);
BlkMigBlock *blk = opaque;
blk->ret = ret;
block_mig_state.reads++;
block_mig_state.total_time += (curr_time - block_mig_state.prev_time_offset);
block_mig_state.prev_time_offset = curr_time;
blk->time = qemu_get_clock_ns(rt_clock) - blk->time;
add_avg_read_time(blk->time);
QSIMPLEQ_INSERT_TAIL(&block_mig_state.blk_list, blk, entry);
bmds_set_aio_inflight(blk->bmds, blk->sector, blk->nr_sectors, 0);
@@ -245,9 +250,7 @@ static int mig_save_device_bulk(Monitor *mon, QEMUFile *f,
blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);
if (block_mig_state.submitted == 0) {
block_mig_state.prev_time_offset = qemu_get_clock_ns(rt_clock);
}
blk->time = qemu_get_clock_ns(rt_clock);
blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov,
nr_sectors, blk_mig_read_cb, blk);
@@ -406,9 +409,7 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f,
blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;
qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);
if (block_mig_state.submitted == 0) {
block_mig_state.prev_time_offset = qemu_get_clock_ns(rt_clock);
}
blk->time = qemu_get_clock_ns(rt_clock);
blk->aiocb = bdrv_aio_readv(bmds->bs, sector, &blk->qiov,
nr_sectors, blk_mig_read_cb, blk);
@@ -671,7 +672,7 @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
bs_prev = bs;
total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
if (total_sectors <= 0) {
error_report("Error getting length of block device %s",
error_report("Error getting length of block device %s\n",
device_name);
return -EINVAL;
}

181
block.c
View File

@@ -439,7 +439,13 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename,
bs->drv = drv;
bs->opaque = qemu_mallocz(drv->instance_size);
if (flags & BDRV_O_CACHE_WB)
/*
* Yes, BDRV_O_NOCACHE aka O_DIRECT means we have to present a
* write cache to the guest. We do need the fdatasync to flush
* out transactions for block allocations, and we maybe have a
* volatile write cache in our backing device to deal with.
*/
if (flags & (BDRV_O_CACHE_WB|BDRV_O_NOCACHE))
bs->enable_write_cache = 1;
/*
@@ -449,7 +455,7 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename,
open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
/*
* Snapshots should be writable.
* Snapshots should be writeable.
*/
if (bs->is_temporary) {
open_flags |= BDRV_O_RDWR;
@@ -741,7 +747,7 @@ DeviceState *bdrv_get_attached(BlockDriverState *bs)
* Run consistency checks on an image
*
* Returns 0 if the check could be completed (it doesn't mean that the image is
* free of errors) or -errno when an internal error occurred. The results of the
* free of errors) or -errno when an internal error occured. The results of the
* check are stored in res.
*/
int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
@@ -1146,25 +1152,6 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset)
return ret;
}
/**
* Length of a allocated file in bytes. Sparse files are counted by actual
* allocated space. Return < 0 if error or unknown.
*/
int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
{
BlockDriver *drv = bs->drv;
if (!drv) {
return -ENOMEDIUM;
}
if (drv->bdrv_get_allocated_file_size) {
return drv->bdrv_get_allocated_file_size(bs);
}
if (bs->file) {
return bdrv_get_allocated_file_size(bs->file);
}
return -ENOTSUP;
}
/**
* Length of a file in bytes. Return < 0 if error or unknown.
*/
@@ -1174,12 +1161,14 @@ int64_t bdrv_getlength(BlockDriverState *bs)
if (!drv)
return -ENOMEDIUM;
if (bs->growable || bs->removable) {
if (drv->bdrv_getlength) {
return drv->bdrv_getlength(bs);
}
/* Fixed size devices use the total_sectors value for speed instead of
issuing a length query (like lseek) on each call. Also, legacy block
drivers don't provide a bdrv_getlength function and must use
total_sectors. */
if (!bs->growable || !drv->bdrv_getlength) {
return bs->total_sectors * BDRV_SECTOR_SIZE;
}
return bs->total_sectors * BDRV_SECTOR_SIZE;
return drv->bdrv_getlength(bs);
}
/* return 0 as number of sectors if no device present or error */
@@ -1318,6 +1307,13 @@ void bdrv_set_geometry_hint(BlockDriverState *bs,
bs->secs = secs;
}
void bdrv_set_type_hint(BlockDriverState *bs, int type)
{
bs->type = type;
bs->removable = ((type == BDRV_TYPE_CDROM ||
type == BDRV_TYPE_FLOPPY));
}
void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
{
bs->translation = translation;
@@ -1331,107 +1327,9 @@ void bdrv_get_geometry_hint(BlockDriverState *bs,
*psecs = bs->secs;
}
/* Recognize floppy formats */
typedef struct FDFormat {
FDriveType drive;
uint8_t last_sect;
uint8_t max_track;
uint8_t max_head;
} FDFormat;
static const FDFormat fd_formats[] = {
/* First entry is default format */
/* 1.44 MB 3"1/2 floppy disks */
{ FDRIVE_DRV_144, 18, 80, 1, },
{ FDRIVE_DRV_144, 20, 80, 1, },
{ FDRIVE_DRV_144, 21, 80, 1, },
{ FDRIVE_DRV_144, 21, 82, 1, },
{ FDRIVE_DRV_144, 21, 83, 1, },
{ FDRIVE_DRV_144, 22, 80, 1, },
{ FDRIVE_DRV_144, 23, 80, 1, },
{ FDRIVE_DRV_144, 24, 80, 1, },
/* 2.88 MB 3"1/2 floppy disks */
{ FDRIVE_DRV_288, 36, 80, 1, },
{ FDRIVE_DRV_288, 39, 80, 1, },
{ FDRIVE_DRV_288, 40, 80, 1, },
{ FDRIVE_DRV_288, 44, 80, 1, },
{ FDRIVE_DRV_288, 48, 80, 1, },
/* 720 kB 3"1/2 floppy disks */
{ FDRIVE_DRV_144, 9, 80, 1, },
{ FDRIVE_DRV_144, 10, 80, 1, },
{ FDRIVE_DRV_144, 10, 82, 1, },
{ FDRIVE_DRV_144, 10, 83, 1, },
{ FDRIVE_DRV_144, 13, 80, 1, },
{ FDRIVE_DRV_144, 14, 80, 1, },
/* 1.2 MB 5"1/4 floppy disks */
{ FDRIVE_DRV_120, 15, 80, 1, },
{ FDRIVE_DRV_120, 18, 80, 1, },
{ FDRIVE_DRV_120, 18, 82, 1, },
{ FDRIVE_DRV_120, 18, 83, 1, },
{ FDRIVE_DRV_120, 20, 80, 1, },
/* 720 kB 5"1/4 floppy disks */
{ FDRIVE_DRV_120, 9, 80, 1, },
{ FDRIVE_DRV_120, 11, 80, 1, },
/* 360 kB 5"1/4 floppy disks */
{ FDRIVE_DRV_120, 9, 40, 1, },
{ FDRIVE_DRV_120, 9, 40, 0, },
{ FDRIVE_DRV_120, 10, 41, 1, },
{ FDRIVE_DRV_120, 10, 42, 1, },
/* 320 kB 5"1/4 floppy disks */
{ FDRIVE_DRV_120, 8, 40, 1, },
{ FDRIVE_DRV_120, 8, 40, 0, },
/* 360 kB must match 5"1/4 better than 3"1/2... */
{ FDRIVE_DRV_144, 9, 80, 0, },
/* end */
{ FDRIVE_DRV_NONE, -1, -1, 0, },
};
void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
int *max_track, int *last_sect,
FDriveType drive_in, FDriveType *drive)
int bdrv_get_type_hint(BlockDriverState *bs)
{
const FDFormat *parse;
uint64_t nb_sectors, size;
int i, first_match, match;
bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect);
if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) {
/* User defined disk */
} else {
bdrv_get_geometry(bs, &nb_sectors);
match = -1;
first_match = -1;
for (i = 0; ; i++) {
parse = &fd_formats[i];
if (parse->drive == FDRIVE_DRV_NONE) {
break;
}
if (drive_in == parse->drive ||
drive_in == FDRIVE_DRV_NONE) {
size = (parse->max_head + 1) * parse->max_track *
parse->last_sect;
if (nb_sectors == size) {
match = i;
break;
}
if (first_match == -1) {
first_match = i;
}
}
}
if (match == -1) {
if (first_match == -1) {
match = 1;
} else {
match = first_match;
}
parse = &fd_formats[match];
}
*nb_heads = parse->max_head + 1;
*max_track = parse->max_track;
*last_sect = parse->last_sect;
*drive = parse->drive;
}
return bs->type;
}
int bdrv_get_translation_hint(BlockDriverState *bs)
@@ -1705,8 +1603,9 @@ static void bdrv_print_dict(QObject *obj, void *opaque)
bs_dict = qobject_to_qdict(obj);
monitor_printf(mon, "%s: removable=%d",
monitor_printf(mon, "%s: type=%s removable=%d",
qdict_get_str(bs_dict, "device"),
qdict_get_str(bs_dict, "type"),
qdict_get_bool(bs_dict, "removable"));
if (qdict_get_bool(bs_dict, "removable")) {
@@ -1747,10 +1646,23 @@ void bdrv_info(Monitor *mon, QObject **ret_data)
QTAILQ_FOREACH(bs, &bdrv_states, list) {
QObject *bs_obj;
const char *type = "unknown";
bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', "
switch(bs->type) {
case BDRV_TYPE_HD:
type = "hd";
break;
case BDRV_TYPE_CDROM:
type = "cdrom";
break;
case BDRV_TYPE_FLOPPY:
type = "floppy";
break;
}
bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': %s, "
"'removable': %i, 'locked': %i }",
bs->device_name, bs->removable,
bs->device_name, type, bs->removable,
bs->locked);
if (bs->drv) {
@@ -2478,8 +2390,6 @@ BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
{
BlockDriver *drv = bs->drv;
trace_bdrv_aio_flush(bs, opaque);
if (bs->open_flags & BDRV_O_NO_FLUSH) {
return bdrv_aio_noop_em(bs, cb, opaque);
}
@@ -2802,8 +2712,6 @@ void bdrv_set_locked(BlockDriverState *bs, int locked)
{
BlockDriver *drv = bs->drv;
trace_bdrv_set_locked(bs, locked);
bs->locked = locked;
if (drv && drv->bdrv_set_locked) {
drv->bdrv_set_locked(bs, locked);
@@ -2900,7 +2808,7 @@ int bdrv_img_create(const char *filename, const char *fmt,
char *options, uint64_t img_size, int flags)
{
QEMUOptionParameter *param = NULL, *create_options = NULL;
QEMUOptionParameter *backing_fmt, *backing_file, *size;
QEMUOptionParameter *backing_fmt, *backing_file;
BlockDriverState *bs = NULL;
BlockDriver *drv, *proto_drv;
BlockDriver *backing_drv = NULL;
@@ -2983,8 +2891,7 @@ int bdrv_img_create(const char *filename, const char *fmt,
// The size for the image must always be specified, with one exception:
// If we are using a backing file, we can obtain the size from there
size = get_option_parameter(param, BLOCK_OPT_SIZE);
if (size && size->value.n == -1) {
if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == -1) {
if (backing_file && backing_file->value.s) {
uint64_t size;
char buf[32];

22
block.h
View File

@@ -89,7 +89,6 @@ int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
int bdrv_truncate(BlockDriverState *bs, int64_t offset);
int64_t bdrv_getlength(BlockDriverState *bs);
int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs);
int bdrv_commit(BlockDriverState *bs);
@@ -111,7 +110,7 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res);
typedef struct BlockDriverAIOCB BlockDriverAIOCB;
typedef void BlockDriverCompletionFunc(void *opaque, int ret);
typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector,
int sector_num);
int sector_num);
BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
QEMUIOVector *iov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque);
@@ -119,7 +118,7 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
QEMUIOVector *iov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque);
BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque);
BlockDriverCompletionFunc *cb, void *opaque);
void bdrv_aio_cancel(BlockDriverAIOCB *acb);
typedef struct BlockRequest {
@@ -151,8 +150,11 @@ void bdrv_close_all(void);
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
int bdrv_has_zero_init(BlockDriverState *bs);
int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
int *pnum);
int *pnum);
#define BDRV_TYPE_HD 0
#define BDRV_TYPE_CDROM 1
#define BDRV_TYPE_FLOPPY 2
#define BIOS_ATA_TRANSLATION_AUTO 0
#define BIOS_ATA_TRANSLATION_NONE 1
#define BIOS_ATA_TRANSLATION_LBA 2
@@ -161,19 +163,11 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
void bdrv_set_geometry_hint(BlockDriverState *bs,
int cyls, int heads, int secs);
void bdrv_set_type_hint(BlockDriverState *bs, int type);
void bdrv_set_translation_hint(BlockDriverState *bs, int translation);
void bdrv_get_geometry_hint(BlockDriverState *bs,
int *pcyls, int *pheads, int *psecs);
typedef enum FDriveType {
FDRIVE_DRV_144 = 0x00, /* 1.44 MB 3"5 drive */
FDRIVE_DRV_288 = 0x01, /* 2.88 MB 3"5 drive */
FDRIVE_DRV_120 = 0x02, /* 1.2 MB 5"25 drive */
FDRIVE_DRV_NONE = 0x03, /* No drive connected */
} FDriveType;
void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads,
int *max_track, int *last_sect,
FDriveType drive_in, FDriveType *drive);
int bdrv_get_type_hint(BlockDriverState *bs);
int bdrv_get_translation_hint(BlockDriverState *bs);
void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
BlockErrorAction on_write_error);

View File

@@ -29,152 +29,96 @@
#include "qemu-common.h"
#include "nbd.h"
#include "module.h"
#include "qemu_socket.h"
#include <sys/types.h>
#include <unistd.h>
#define EN_OPTSTR ":exportname="
/* #define DEBUG_NBD */
#if defined(DEBUG_NBD)
#define logout(fmt, ...) \
fprintf(stderr, "nbd\t%-24s" fmt, __func__, ##__VA_ARGS__)
#else
#define logout(fmt, ...) ((void)0)
#endif
typedef struct BDRVNBDState {
int sock;
off_t size;
size_t blocksize;
char *export_name; /* An NBD server may export several devices */
/* If it begins with '/', this is a UNIX domain socket. Otherwise,
* it's a string of the form <hostname|ip4|\[ip6\]>:port
*/
char *host_spec;
} BDRVNBDState;
static int nbd_config(BDRVNBDState *s, const char *filename, int flags)
{
char *file;
char *export_name;
const char *host_spec;
const char *unixpath;
int err = -EINVAL;
file = qemu_strdup(filename);
export_name = strstr(file, EN_OPTSTR);
if (export_name) {
if (export_name[strlen(EN_OPTSTR)] == 0) {
goto out;
}
export_name[0] = 0; /* truncate 'file' */
export_name += strlen(EN_OPTSTR);
s->export_name = qemu_strdup(export_name);
}
/* extract the host_spec - fail if it's not nbd:... */
if (!strstart(file, "nbd:", &host_spec)) {
goto out;
}
/* are we a UNIX or TCP socket? */
if (strstart(host_spec, "unix:", &unixpath)) {
if (unixpath[0] != '/') { /* We demand an absolute path*/
goto out;
}
s->host_spec = qemu_strdup(unixpath);
} else {
s->host_spec = qemu_strdup(host_spec);
}
err = 0;
out:
qemu_free(file);
if (err != 0) {
qemu_free(s->export_name);
qemu_free(s->host_spec);
}
return err;
}
static int nbd_establish_connection(BlockDriverState *bs)
{
BDRVNBDState *s = bs->opaque;
int sock;
int ret;
off_t size;
size_t blocksize;
uint32_t nbdflags;
if (s->host_spec[0] == '/') {
sock = unix_socket_outgoing(s->host_spec);
} else {
sock = tcp_socket_outgoing_spec(s->host_spec);
}
/* Failed to establish connection */
if (sock == -1) {
logout("Failed to establish connection to NBD server\n");
return -errno;
}
/* NBD handshake */
ret = nbd_receive_negotiate(sock, s->export_name, &nbdflags, &size,
&blocksize);
if (ret == -1) {
logout("Failed to negotiate with the NBD server\n");
closesocket(sock);
return -errno;
}
/* Now that we're connected, set the socket to be non-blocking */
socket_set_nonblock(sock);
s->sock = sock;
s->size = size;
s->blocksize = blocksize;
logout("Established connection with NBD server\n");
return 0;
}
static void nbd_teardown_connection(BlockDriverState *bs)
{
BDRVNBDState *s = bs->opaque;
struct nbd_request request;
request.type = NBD_CMD_DISC;
request.handle = (uint64_t)(intptr_t)bs;
request.from = 0;
request.len = 0;
nbd_send_request(s->sock, &request);
closesocket(s->sock);
}
static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
{
BDRVNBDState *s = bs->opaque;
int result;
uint32_t nbdflags;
/* Pop the config into our state object. Exit if invalid. */
result = nbd_config(s, filename, flags);
if (result != 0) {
return result;
char *file;
char *name;
const char *host;
const char *unixpath;
int sock;
off_t size;
size_t blocksize;
int ret;
int err = -EINVAL;
file = qemu_strdup(filename);
name = strstr(file, EN_OPTSTR);
if (name) {
if (name[strlen(EN_OPTSTR)] == 0) {
goto out;
}
name[0] = 0;
name += strlen(EN_OPTSTR);
}
/* establish TCP connection, return error if it fails
* TODO: Configurable retry-until-timeout behaviour.
*/
result = nbd_establish_connection(bs);
if (!strstart(file, "nbd:", &host)) {
goto out;
}
return result;
if (strstart(host, "unix:", &unixpath)) {
if (unixpath[0] != '/') {
goto out;
}
sock = unix_socket_outgoing(unixpath);
} else {
uint16_t port = NBD_DEFAULT_PORT;
char *p, *r;
char hostname[128];
pstrcpy(hostname, 128, host);
p = strchr(hostname, ':');
if (p != NULL) {
*p = '\0';
p++;
port = strtol(p, &r, 0);
if (r == p) {
goto out;
}
}
sock = tcp_socket_outgoing(hostname, port);
}
if (sock == -1) {
err = -errno;
goto out;
}
ret = nbd_receive_negotiate(sock, name, &nbdflags, &size, &blocksize);
if (ret == -1) {
err = -errno;
goto out;
}
s->sock = sock;
s->size = size;
s->blocksize = blocksize;
err = 0;
out:
qemu_free(file);
return err;
}
static int nbd_read(BlockDriverState *bs, int64_t sector_num,
@@ -240,10 +184,15 @@ static int nbd_write(BlockDriverState *bs, int64_t sector_num,
static void nbd_close(BlockDriverState *bs)
{
BDRVNBDState *s = bs->opaque;
qemu_free(s->export_name);
qemu_free(s->host_spec);
struct nbd_request request;
nbd_teardown_connection(bs);
request.type = NBD_CMD_DISC;
request.handle = (uint64_t)(intptr_t)bs;
request.from = 0;
request.len = 0;
nbd_send_request(s->sock, &request);
close(s->sock);
}
static int64_t nbd_getlength(BlockDriverState *bs)

View File

@@ -496,8 +496,6 @@ typedef struct QCowAIOCB {
uint64_t cluster_offset;
uint8_t *cluster_data;
struct iovec hd_iov;
bool is_write;
QEMUBH *bh;
QEMUIOVector hd_qiov;
BlockDriverAIOCB *hd_aiocb;
} QCowAIOCB;
@@ -527,8 +525,6 @@ static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
acb->hd_aiocb = NULL;
acb->sector_num = sector_num;
acb->qiov = qiov;
acb->is_write = is_write;
if (qiov->niov > 1) {
acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size);
if (is_write)
@@ -542,38 +538,6 @@ static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
return acb;
}
static void qcow_aio_read_cb(void *opaque, int ret);
static void qcow_aio_write_cb(void *opaque, int ret);
static void qcow_aio_rw_bh(void *opaque)
{
QCowAIOCB *acb = opaque;
qemu_bh_delete(acb->bh);
acb->bh = NULL;
if (acb->is_write) {
qcow_aio_write_cb(opaque, 0);
} else {
qcow_aio_read_cb(opaque, 0);
}
}
static int qcow_schedule_bh(QEMUBHFunc *cb, QCowAIOCB *acb)
{
if (acb->bh) {
return -EIO;
}
acb->bh = qemu_bh_new(cb, acb);
if (!acb->bh) {
return -EIO;
}
qemu_bh_schedule(acb->bh);
return 0;
}
static void qcow_aio_read_cb(void *opaque, int ret)
{
QCowAIOCB *acb = opaque;
@@ -625,10 +589,8 @@ static void qcow_aio_read_cb(void *opaque, int ret)
qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
acb->hd_aiocb = bdrv_aio_readv(bs->backing_hd, acb->sector_num,
&acb->hd_qiov, acb->n, qcow_aio_read_cb, acb);
if (acb->hd_aiocb == NULL) {
ret = -EIO;
if (acb->hd_aiocb == NULL)
goto done;
}
} else {
/* Note: in this case, no need to wait */
memset(acb->buf, 0, 512 * acb->n);
@@ -636,10 +598,8 @@ static void qcow_aio_read_cb(void *opaque, int ret)
}
} else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
/* add AIO support for compressed blocks ? */
if (decompress_cluster(bs, acb->cluster_offset) < 0) {
ret = -EIO;
if (decompress_cluster(bs, acb->cluster_offset) < 0)
goto done;
}
memcpy(acb->buf,
s->cluster_cache + index_in_cluster * 512, 512 * acb->n);
goto redo;
@@ -654,10 +614,8 @@ static void qcow_aio_read_cb(void *opaque, int ret)
acb->hd_aiocb = bdrv_aio_readv(bs->file,
(acb->cluster_offset >> 9) + index_in_cluster,
&acb->hd_qiov, acb->n, qcow_aio_read_cb, acb);
if (acb->hd_aiocb == NULL) {
ret = -EIO;
if (acb->hd_aiocb == NULL)
goto done;
}
}
return;
@@ -676,21 +634,12 @@ static BlockDriverAIOCB *qcow_aio_readv(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque)
{
QCowAIOCB *acb;
int ret;
acb = qcow_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
if (!acb)
return NULL;
ret = qcow_schedule_bh(qcow_aio_rw_bh, acb);
if (ret < 0) {
if (acb->qiov->niov > 1) {
qemu_vfree(acb->orig_buf);
}
qemu_aio_release(acb);
return NULL;
}
qcow_aio_read_cb(acb, 0);
return &acb->common;
}
@@ -751,10 +700,8 @@ static void qcow_aio_write_cb(void *opaque, int ret)
(cluster_offset >> 9) + index_in_cluster,
&acb->hd_qiov, acb->n,
qcow_aio_write_cb, acb);
if (acb->hd_aiocb == NULL) {
ret = -EIO;
if (acb->hd_aiocb == NULL)
goto done;
}
return;
done:
@@ -770,7 +717,6 @@ static BlockDriverAIOCB *qcow_aio_writev(BlockDriverState *bs,
{
BDRVQcowState *s = bs->opaque;
QCowAIOCB *acb;
int ret;
s->cluster_cache_offset = -1; /* disable compressed cache */
@@ -779,15 +725,7 @@ static BlockDriverAIOCB *qcow_aio_writev(BlockDriverState *bs,
return NULL;
ret = qcow_schedule_bh(qcow_aio_rw_bh, acb);
if (ret < 0) {
if (acb->qiov->niov > 1) {
qemu_vfree(acb->orig_buf);
}
qemu_aio_release(acb);
return NULL;
}
qcow_aio_write_cb(acb, 0);
return &acb->common;
}

View File

@@ -312,15 +312,3 @@ found:
c->entries[i].dirty = true;
}
bool qcow2_cache_set_writethrough(BlockDriverState *bs, Qcow2Cache *c,
bool enable)
{
bool old = c->writethrough;
if (!old && enable) {
qcow2_cache_flush(bs, c);
}
c->writethrough = enable;
return old;
}

View File

@@ -70,7 +70,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)
ret = qcow2_cache_flush(bs, s->refcount_block_cache);
if (ret < 0) {
goto fail;
return ret;
}
BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
@@ -796,8 +796,8 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
m->depends_on = old_alloc;
m->nb_clusters = 0;
*num = 0;
goto out_wait_dependency;
ret = 0;
goto fail;
}
}
}
@@ -812,6 +812,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
cluster_offset = qcow2_alloc_clusters(bs, nb_clusters * s->cluster_size);
if (cluster_offset < 0) {
QLIST_REMOVE(m, next_in_flight);
ret = cluster_offset;
goto fail;
}
@@ -824,7 +825,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
out:
ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
if (ret < 0) {
goto fail_put;
return ret;
}
m->nb_available = MIN(nb_clusters << (s->cluster_bits - 9), n_end);
@@ -834,13 +835,8 @@ out:
return 0;
out_wait_dependency:
return qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
fail:
qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
fail_put:
QLIST_REMOVE(m, next_in_flight);
return ret;
}

View File

@@ -705,15 +705,8 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
BDRVQcowState *s = bs->opaque;
uint64_t *l1_table, *l2_table, l2_offset, offset, l1_size2, l1_allocated;
int64_t old_offset, old_l2_offset;
int i, j, l1_modified = 0, nb_csectors, refcount;
int i, j, l1_modified, nb_csectors, refcount;
int ret;
bool old_l2_writethrough, old_refcount_writethrough;
/* Switch caches to writeback mode during update */
old_l2_writethrough =
qcow2_cache_set_writethrough(bs, s->l2_table_cache, false);
old_refcount_writethrough =
qcow2_cache_set_writethrough(bs, s->refcount_block_cache, false);
l2_table = NULL;
l1_table = NULL;
@@ -727,11 +720,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
l1_allocated = 1;
if (bdrv_pread(bs->file, l1_table_offset,
l1_table, l1_size2) != l1_size2)
{
ret = -EIO;
goto fail;
}
for(i = 0;i < l1_size; i++)
be64_to_cpus(&l1_table[i]);
} else {
@@ -740,6 +729,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
l1_allocated = 0;
}
l1_modified = 0;
for(i = 0; i < l1_size; i++) {
l2_offset = l1_table[i];
if (l2_offset) {
@@ -783,7 +773,6 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
}
if (refcount < 0) {
ret = -EIO;
goto fail;
}
}
@@ -814,7 +803,6 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
refcount = get_refcount(bs, l2_offset >> s->cluster_bits);
}
if (refcount < 0) {
ret = -EIO;
goto fail;
} else if (refcount == 1) {
l2_offset |= QCOW_OFLAG_COPIED;
@@ -825,18 +813,6 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
}
}
}
ret = 0;
fail:
if (l2_table) {
qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
}
/* Enable writethrough cache mode again */
qcow2_cache_set_writethrough(bs, s->l2_table_cache, old_l2_writethrough);
qcow2_cache_set_writethrough(bs, s->refcount_block_cache,
old_refcount_writethrough);
if (l1_modified) {
for(i = 0; i < l1_size; i++)
cpu_to_be64s(&l1_table[i]);
@@ -848,7 +824,15 @@ fail:
}
if (l1_allocated)
qemu_free(l1_table);
return ret;
return 0;
fail:
if (l2_table) {
qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
}
if (l1_allocated)
qemu_free(l1_table);
return -EIO;
}
@@ -1079,7 +1063,7 @@ fail:
* Checks an image for refcount consistency.
*
* Returns 0 if no errors are found, the number of errors in case the image is
* detected as corrupted, and -errno when an internal error occurred.
* detected as corrupted, and -errno when an internal error occured.
*/
int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
{
@@ -1102,7 +1086,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
s->l1_table_offset, s->l1_size, 1);
if (ret < 0) {
goto fail;
return ret;
}
/* snapshots */
@@ -1111,7 +1095,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
sn->l1_table_offset, sn->l1_size, 0);
if (ret < 0) {
goto fail;
return ret;
}
}
inc_refcounts(bs, res, refcount_table, nb_clusters,
@@ -1175,11 +1159,8 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
}
}
ret = 0;
fail:
qemu_free(refcount_table);
return ret;
return 0;
}

View File

@@ -317,8 +317,7 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
{
BDRVQcowState *s = bs->opaque;
QCowSnapshot *sn;
int i, snapshot_index;
int cur_l1_bytes, sn_l1_bytes;
int i, snapshot_index, l1_size2;
snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
if (snapshot_index < 0)
@@ -331,19 +330,14 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
if (qcow2_grow_l1_table(bs, sn->l1_size, true) < 0)
goto fail;
cur_l1_bytes = s->l1_size * sizeof(uint64_t);
sn_l1_bytes = sn->l1_size * sizeof(uint64_t);
if (cur_l1_bytes > sn_l1_bytes) {
memset(s->l1_table + sn->l1_size, 0, cur_l1_bytes - sn_l1_bytes);
}
s->l1_size = sn->l1_size;
l1_size2 = s->l1_size * sizeof(uint64_t);
/* copy the snapshot l1 table to the current l1 table */
if (bdrv_pread(bs->file, sn->l1_table_offset,
s->l1_table, sn_l1_bytes) < 0)
s->l1_table, l1_size2) != l1_size2)
goto fail;
if (bdrv_pwrite_sync(bs->file, s->l1_table_offset,
s->l1_table, cur_l1_bytes) < 0)
s->l1_table, l1_size2) < 0)
goto fail;
for(i = 0;i < s->l1_size; i++) {
be64_to_cpus(&s->l1_table[i]);

View File

@@ -229,7 +229,7 @@ static int qcow2_open(BlockDriverState *bs, int flags)
}
/* alloc L2 table/refcount block cache */
writethrough = ((flags & BDRV_O_CACHE_WB) == 0);
writethrough = ((flags & BDRV_O_CACHE_MASK) == 0);
s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE, writethrough);
s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE,
writethrough);
@@ -378,7 +378,6 @@ typedef struct QCowAIOCB {
uint64_t bytes_done;
uint64_t cluster_offset;
uint8_t *cluster_data;
bool is_write;
BlockDriverAIOCB *hd_aiocb;
QEMUIOVector hd_qiov;
QEMUBH *bh;
@@ -400,19 +399,12 @@ static AIOPool qcow2_aio_pool = {
};
static void qcow2_aio_read_cb(void *opaque, int ret);
static void qcow2_aio_write_cb(void *opaque, int ret);
static void qcow2_aio_rw_bh(void *opaque)
static void qcow2_aio_read_bh(void *opaque)
{
QCowAIOCB *acb = opaque;
qemu_bh_delete(acb->bh);
acb->bh = NULL;
if (acb->is_write) {
qcow2_aio_write_cb(opaque, 0);
} else {
qcow2_aio_read_cb(opaque, 0);
}
qcow2_aio_read_cb(opaque, 0);
}
static int qcow2_schedule_bh(QEMUBHFunc *cb, QCowAIOCB *acb)
@@ -501,14 +493,14 @@ static void qcow2_aio_read_cb(void *opaque, int ret)
goto done;
}
} else {
ret = qcow2_schedule_bh(qcow2_aio_rw_bh, acb);
ret = qcow2_schedule_bh(qcow2_aio_read_bh, acb);
if (ret < 0)
goto done;
}
} else {
/* Note: in this case, no need to wait */
qemu_iovec_memset(&acb->hd_qiov, 0, 512 * acb->cur_nr_sectors);
ret = qcow2_schedule_bh(qcow2_aio_rw_bh, acb);
ret = qcow2_schedule_bh(qcow2_aio_read_bh, acb);
if (ret < 0)
goto done;
}
@@ -523,7 +515,7 @@ static void qcow2_aio_read_cb(void *opaque, int ret)
s->cluster_cache + index_in_cluster * 512,
512 * acb->cur_nr_sectors);
ret = qcow2_schedule_bh(qcow2_aio_rw_bh, acb);
ret = qcow2_schedule_bh(qcow2_aio_read_bh, acb);
if (ret < 0)
goto done;
} else {
@@ -580,7 +572,6 @@ static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num,
acb->hd_aiocb = NULL;
acb->sector_num = sector_num;
acb->qiov = qiov;
acb->is_write = is_write;
qemu_iovec_init(&acb->hd_qiov, qiov->niov);
@@ -600,22 +591,17 @@ static BlockDriverAIOCB *qcow2_aio_readv(BlockDriverState *bs,
void *opaque)
{
QCowAIOCB *acb;
int ret;
acb = qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
if (!acb)
return NULL;
ret = qcow2_schedule_bh(qcow2_aio_rw_bh, acb);
if (ret < 0) {
qemu_iovec_destroy(&acb->hd_qiov);
qemu_aio_release(acb);
return NULL;
}
qcow2_aio_read_cb(acb, 0);
return &acb->common;
}
static void qcow2_aio_write_cb(void *opaque, int ret);
static void run_dependent_requests(QCowL2Meta *m)
{
QCowAIOCB *req;
@@ -738,7 +724,6 @@ static BlockDriverAIOCB *qcow2_aio_writev(BlockDriverState *bs,
{
BDRVQcowState *s = bs->opaque;
QCowAIOCB *acb;
int ret;
s->cluster_cache_offset = -1; /* disable compressed cache */
@@ -746,13 +731,7 @@ static BlockDriverAIOCB *qcow2_aio_writev(BlockDriverState *bs,
if (!acb)
return NULL;
ret = qcow2_schedule_bh(qcow2_aio_rw_bh, acb);
if (ret < 0) {
qemu_iovec_destroy(&acb->hd_qiov);
qemu_aio_release(acb);
return NULL;
}
qcow2_aio_write_cb(acb, 0);
return &acb->common;
}
@@ -936,7 +915,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
(1 << cluster_bits) != cluster_size)
{
error_report(
"Cluster size must be a power of two between %d and %dk",
"Cluster size must be a power of two between %d and %dk\n",
1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10));
return -EINVAL;
}
@@ -1057,7 +1036,7 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options)
const char *backing_fmt = NULL;
uint64_t sectors = 0;
int flags = 0;
size_t cluster_size = DEFAULT_CLUSTER_SIZE;
size_t cluster_size = 65536;
int prealloc = 0;
/* Read out options */
@@ -1364,8 +1343,7 @@ static QEMUOptionParameter qcow2_create_options[] = {
{
.name = BLOCK_OPT_CLUSTER_SIZE,
.type = OPT_SIZE,
.help = "qcow2 cluster size",
.value = { .n = DEFAULT_CLUSTER_SIZE },
.help = "qcow2 cluster size"
},
{
.name = BLOCK_OPT_PREALLOC,

View File

@@ -54,8 +54,6 @@
/* Must be at least 4 to cover all cases of refcount table growth */
#define REFCOUNT_CACHE_SIZE 4
#define DEFAULT_CLUSTER_SIZE 65536
typedef struct QCowHeader {
uint32_t magic;
uint32_t version;
@@ -228,8 +226,6 @@ int qcow2_read_snapshots(BlockDriverState *bs);
Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables,
bool writethrough);
int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c);
bool qcow2_cache_set_writethrough(BlockDriverState *bs, Qcow2Cache *c,
bool enable);
void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table);
int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c);

View File

@@ -72,8 +72,7 @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table)
for (i = 0; i < s->table_nelems; i++) {
uint64_t offset = table->offsets[i];
if (qed_offset_is_unalloc_cluster(offset) ||
qed_offset_is_zero_cluster(offset)) {
if (!offset) {
continue;
}
@@ -112,7 +111,7 @@ static int qed_check_l1_table(QEDCheck *check, QEDTable *table)
unsigned int num_invalid_l2;
uint64_t offset = table->offsets[i];
if (qed_offset_is_unalloc_cluster(offset)) {
if (!offset) {
continue;
}

View File

@@ -23,8 +23,7 @@
* @n: Maximum number of clusters
* @offset: Set to first cluster offset
*
* This function scans tables for contiguous clusters. A contiguous run of
* clusters may be allocated, unallocated, or zero.
* This function scans tables for contiguous allocated or free clusters.
*/
static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s,
QEDTable *table,
@@ -39,14 +38,9 @@ static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s,
*offset = last;
for (i = index + 1; i < end; i++) {
if (qed_offset_is_unalloc_cluster(last)) {
/* Counting unallocated clusters */
if (!qed_offset_is_unalloc_cluster(table->offsets[i])) {
break;
}
} else if (qed_offset_is_zero_cluster(last)) {
/* Counting zero clusters */
if (!qed_offset_is_zero_cluster(table->offsets[i])) {
if (last == 0) {
/* Counting free clusters */
if (table->offsets[i] != 0) {
break;
}
} else {
@@ -93,19 +87,14 @@ static void qed_find_cluster_cb(void *opaque, int ret)
n = qed_count_contiguous_clusters(s, request->l2_table->table,
index, n, &offset);
if (qed_offset_is_unalloc_cluster(offset)) {
ret = QED_CLUSTER_L2;
} else if (qed_offset_is_zero_cluster(offset)) {
ret = QED_CLUSTER_ZERO;
} else if (qed_check_cluster_offset(s, offset)) {
ret = QED_CLUSTER_FOUND;
} else {
ret = -EINVAL;
}
ret = offset ? QED_CLUSTER_FOUND : QED_CLUSTER_L2;
len = MIN(find_cluster_cb->len, n * s->header.cluster_size -
qed_offset_into_cluster(s, find_cluster_cb->pos));
if (offset && !qed_check_cluster_offset(s, offset)) {
ret = -EINVAL;
}
out:
find_cluster_cb->cb(find_cluster_cb->opaque, ret, offset, len);
qemu_free(find_cluster_cb);
@@ -143,7 +132,7 @@ void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
len = MIN(len, (((pos >> s->l1_shift) + 1) << s->l1_shift) - pos);
l2_offset = s->l1_table->offsets[qed_l1_index(s, pos)];
if (qed_offset_is_unalloc_cluster(l2_offset)) {
if (!l2_offset) {
cb(opaque, QED_CLUSTER_L1, 0, len);
return;
}

View File

@@ -230,21 +230,21 @@ static void qed_read_l2_table_cb(void *opaque, int ret)
QEDRequest *request = read_l2_table_cb->request;
BDRVQEDState *s = read_l2_table_cb->s;
CachedL2Table *l2_table = request->l2_table;
uint64_t l2_offset = read_l2_table_cb->l2_offset;
if (ret) {
/* can't trust loaded L2 table anymore */
qed_unref_l2_cache_entry(l2_table);
request->l2_table = NULL;
} else {
l2_table->offset = l2_offset;
l2_table->offset = read_l2_table_cb->l2_offset;
qed_commit_l2_cache_entry(&s->l2_cache, l2_table);
/* This is guaranteed to succeed because we just committed the entry
* to the cache.
*/
request->l2_table = qed_find_l2_cache_entry(&s->l2_cache, l2_offset);
request->l2_table = qed_find_l2_cache_entry(&s->l2_cache,
l2_table->offset);
assert(request->l2_table != NULL);
}

View File

@@ -12,7 +12,6 @@
*
*/
#include "qemu-timer.h"
#include "trace.h"
#include "qed.h"
#include "qerror.h"
@@ -292,88 +291,6 @@ static CachedL2Table *qed_new_l2_table(BDRVQEDState *s)
static void qed_aio_next_io(void *opaque, int ret);
static void qed_plug_allocating_write_reqs(BDRVQEDState *s)
{
assert(!s->allocating_write_reqs_plugged);
s->allocating_write_reqs_plugged = true;
}
static void qed_unplug_allocating_write_reqs(BDRVQEDState *s)
{
QEDAIOCB *acb;
assert(s->allocating_write_reqs_plugged);
s->allocating_write_reqs_plugged = false;
acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs);
if (acb) {
qed_aio_next_io(acb, 0);
}
}
static void qed_finish_clear_need_check(void *opaque, int ret)
{
/* Do nothing */
}
static void qed_flush_after_clear_need_check(void *opaque, int ret)
{
BDRVQEDState *s = opaque;
bdrv_aio_flush(s->bs, qed_finish_clear_need_check, s);
/* No need to wait until flush completes */
qed_unplug_allocating_write_reqs(s);
}
static void qed_clear_need_check(void *opaque, int ret)
{
BDRVQEDState *s = opaque;
if (ret) {
qed_unplug_allocating_write_reqs(s);
return;
}
s->header.features &= ~QED_F_NEED_CHECK;
qed_write_header(s, qed_flush_after_clear_need_check, s);
}
static void qed_need_check_timer_cb(void *opaque)
{
BDRVQEDState *s = opaque;
/* The timer should only fire when allocating writes have drained */
assert(!QSIMPLEQ_FIRST(&s->allocating_write_reqs));
trace_qed_need_check_timer_cb(s);
qed_plug_allocating_write_reqs(s);
/* Ensure writes are on disk before clearing flag */
bdrv_aio_flush(s->bs, qed_clear_need_check, s);
}
static void qed_start_need_check_timer(BDRVQEDState *s)
{
trace_qed_start_need_check_timer(s);
/* Use vm_clock so we don't alter the image file while suspended for
* migration.
*/
qemu_mod_timer(s->need_check_timer, qemu_get_clock_ns(vm_clock) +
get_ticks_per_sec() * QED_NEED_CHECK_TIMEOUT);
}
/* It's okay to call this multiple times or when no timer is started */
static void qed_cancel_need_check_timer(BDRVQEDState *s)
{
trace_qed_cancel_need_check_timer(s);
qemu_del_timer(s->need_check_timer);
}
static int bdrv_qed_open(BlockDriverState *bs, int flags)
{
BDRVQEDState *s = bs->opaque;
@@ -489,10 +406,7 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags)
BdrvCheckResult result = {0};
ret = qed_check(s, &result, true);
if (ret) {
goto out;
}
if (!result.corruptions && !result.check_errors) {
if (!ret && !result.corruptions && !result.check_errors) {
/* Ensure fixes reach storage before clearing check bit */
bdrv_flush(s->bs);
@@ -502,9 +416,6 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags)
}
}
s->need_check_timer = qemu_new_timer_ns(vm_clock,
qed_need_check_timer_cb, s);
out:
if (ret) {
qed_free_l2_cache(&s->l2_cache);
@@ -517,9 +428,6 @@ static void bdrv_qed_close(BlockDriverState *bs)
{
BDRVQEDState *s = bs->opaque;
qed_cancel_need_check_timer(s);
qemu_free_timer(s->need_check_timer);
/* Ensure writes reach stable storage */
bdrv_flush(bs->file);
@@ -665,7 +573,7 @@ static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t l
{
QEDIsAllocatedCB *cb = opaque;
*cb->pnum = len / BDRV_SECTOR_SIZE;
cb->is_allocated = (ret == QED_CLUSTER_FOUND || ret == QED_CLUSTER_ZERO);
cb->is_allocated = ret == QED_CLUSTER_FOUND;
}
static int bdrv_qed_is_allocated(BlockDriverState *bs, int64_t sector_num,
@@ -837,10 +745,7 @@ static void qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos,
* @table: L2 table
* @index: First cluster index
* @n: Number of contiguous clusters
* @cluster: First cluster offset
*
* The cluster offset may be an allocated byte offset in the image file, the
* zero cluster marker, or the unallocated cluster marker.
* @cluster: First cluster byte offset in image file
*/
static void qed_update_l2_table(BDRVQEDState *s, QEDTable *table, int index,
unsigned int n, uint64_t cluster)
@@ -848,10 +753,7 @@ static void qed_update_l2_table(BDRVQEDState *s, QEDTable *table, int index,
int i;
for (i = index; i < index + n; i++) {
table->offsets[i] = cluster;
if (!qed_offset_is_unalloc_cluster(cluster) &&
!qed_offset_is_zero_cluster(cluster)) {
cluster += s->header.cluster_size;
}
cluster += s->header.cluster_size;
}
}
@@ -901,8 +803,6 @@ static void qed_aio_complete(QEDAIOCB *acb, int ret)
acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs);
if (acb) {
qed_aio_next_io(acb, 0);
} else if (s->header.features & QED_F_NEED_CHECK) {
qed_start_need_check_timer(s);
}
}
}
@@ -915,14 +815,14 @@ static void qed_commit_l2_update(void *opaque, int ret)
QEDAIOCB *acb = opaque;
BDRVQEDState *s = acb_to_s(acb);
CachedL2Table *l2_table = acb->request.l2_table;
uint64_t l2_offset = l2_table->offset;
qed_commit_l2_cache_entry(&s->l2_cache, l2_table);
/* This is guaranteed to succeed because we just committed the entry to the
* cache.
*/
acb->request.l2_table = qed_find_l2_cache_entry(&s->l2_cache, l2_offset);
acb->request.l2_table = qed_find_l2_cache_entry(&s->l2_cache,
l2_table->offset);
assert(acb->request.l2_table != NULL);
qed_aio_next_io(opaque, ret);
@@ -1108,17 +1008,11 @@ static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
{
BDRVQEDState *s = acb_to_s(acb);
/* Cancel timer when the first allocating request comes in */
if (QSIMPLEQ_EMPTY(&s->allocating_write_reqs)) {
qed_cancel_need_check_timer(s);
}
/* Freeze this request if another allocating write is in progress */
if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs)) {
QSIMPLEQ_INSERT_TAIL(&s->allocating_write_reqs, acb, next);
}
if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs) ||
s->allocating_write_reqs_plugged) {
if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs)) {
return; /* wait for existing request to finish */
}
@@ -1181,7 +1075,6 @@ static void qed_aio_write_data(void *opaque, int ret,
case QED_CLUSTER_L2:
case QED_CLUSTER_L1:
case QED_CLUSTER_ZERO:
qed_aio_write_alloc(acb, len);
break;
@@ -1221,12 +1114,8 @@ static void qed_aio_read_data(void *opaque, int ret,
qemu_iovec_copy(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
/* Handle zero cluster and backing file reads */
if (ret == QED_CLUSTER_ZERO) {
qemu_iovec_memset(&acb->cur_qiov, 0, acb->cur_qiov.size);
qed_aio_next_io(acb, 0);
return;
} else if (ret != QED_CLUSTER_FOUND) {
/* Handle backing file and unallocated sparse hole reads */
if (ret != QED_CLUSTER_FOUND) {
qed_read_backing_file(s, acb->cur_pos, &acb->cur_qiov,
qed_aio_next_io, acb);
return;
@@ -1333,27 +1222,7 @@ static BlockDriverAIOCB *bdrv_qed_aio_flush(BlockDriverState *bs,
static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset)
{
BDRVQEDState *s = bs->opaque;
uint64_t old_image_size;
int ret;
if (!qed_is_image_size_valid(offset, s->header.cluster_size,
s->header.table_size)) {
return -EINVAL;
}
/* Shrinking is currently not supported */
if ((uint64_t)offset < s->header.image_size) {
return -ENOTSUP;
}
old_image_size = s->header.image_size;
s->header.image_size = offset;
ret = qed_write_header_sync(s);
if (ret < 0) {
s->header.image_size = old_image_size;
}
return ret;
return -ENOTSUP;
}
static int64_t bdrv_qed_getlength(BlockDriverState *bs)
@@ -1464,8 +1333,7 @@ static QEMUOptionParameter qed_create_options[] = {
}, {
.name = BLOCK_OPT_CLUSTER_SIZE,
.type = OPT_SIZE,
.help = "Cluster size (in bytes)",
.value = { .n = QED_DEFAULT_CLUSTER_SIZE },
.help = "Cluster size (in bytes)"
}, {
.name = BLOCK_OPT_TABLE_SIZE,
.type = OPT_SIZE,

View File

@@ -78,9 +78,6 @@ enum {
QED_MIN_TABLE_SIZE = 1, /* in clusters */
QED_MAX_TABLE_SIZE = 16,
QED_DEFAULT_TABLE_SIZE = 4,
/* Delay to flush and clean image after last allocating write completes */
QED_NEED_CHECK_TIMEOUT = 5, /* in seconds */
};
typedef struct {
@@ -160,15 +157,10 @@ typedef struct {
/* Allocating write request queue */
QSIMPLEQ_HEAD(, QEDAIOCB) allocating_write_reqs;
bool allocating_write_reqs_plugged;
/* Periodic flush and clear need check flag */
QEMUTimer *need_check_timer;
} BDRVQEDState;
enum {
QED_CLUSTER_FOUND, /* cluster found */
QED_CLUSTER_ZERO, /* zero cluster found */
QED_CLUSTER_L2, /* cluster missing in L2 */
QED_CLUSTER_L1, /* cluster missing in L1 */
};
@@ -306,29 +298,4 @@ static inline bool qed_check_table_offset(BDRVQEDState *s, uint64_t offset)
qed_check_cluster_offset(s, end_offset);
}
static inline bool qed_offset_is_cluster_aligned(BDRVQEDState *s,
uint64_t offset)
{
if (qed_offset_into_cluster(s, offset)) {
return false;
}
return true;
}
static inline bool qed_offset_is_unalloc_cluster(uint64_t offset)
{
if (offset == 0) {
return true;
}
return false;
}
static inline bool qed_offset_is_zero_cluster(uint64_t offset)
{
if (offset == 1) {
return true;
}
return false;
}
#endif /* BLOCK_QED_H */

View File

@@ -43,17 +43,17 @@
#ifdef __sun__
#define _POSIX_PTHREAD_SEMANTICS 1
#include <signal.h>
#include <sys/dkio.h>
#endif
#ifdef __linux__
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <linux/cdrom.h>
#include <linux/fd.h>
#endif
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <signal.h>
#include <sys/disk.h>
#include <sys/cdio.h>
#endif
@@ -64,13 +64,6 @@
#include <sys/dkio.h>
#endif
#ifdef __NetBSD__
#include <sys/ioctl.h>
#include <sys/disklabel.h>
#include <sys/dkio.h>
#include <sys/disk.h>
#endif
#ifdef __DragonFly__
#include <sys/ioctl.h>
#include <sys/diskslice.h>
@@ -143,55 +136,12 @@ static int64_t raw_getlength(BlockDriverState *bs);
static int cdrom_reopen(BlockDriverState *bs);
#endif
#if defined(__NetBSD__)
static int raw_normalize_devicepath(const char **filename)
{
static char namebuf[PATH_MAX];
const char *dp, *fname;
struct stat sb;
fname = *filename;
dp = strrchr(fname, '/');
if (lstat(fname, &sb) < 0) {
fprintf(stderr, "%s: stat failed: %s\n",
fname, strerror(errno));
return -errno;
}
if (!S_ISBLK(sb.st_mode)) {
return 0;
}
if (dp == NULL) {
snprintf(namebuf, PATH_MAX, "r%s", fname);
} else {
snprintf(namebuf, PATH_MAX, "%.*s/r%s",
(int)(dp - fname), fname, dp + 1);
}
fprintf(stderr, "%s is a block device", fname);
*filename = namebuf;
fprintf(stderr, ", using %s\n", *filename);
return 0;
}
#else
static int raw_normalize_devicepath(const char **filename)
{
return 0;
}
#endif
static int raw_open_common(BlockDriverState *bs, const char *filename,
int bdrv_flags, int open_flags)
{
BDRVRawState *s = bs->opaque;
int fd, ret;
ret = raw_normalize_devicepath(&filename);
if (ret != 0) {
return ret;
}
s->open_flags = open_flags | O_BINARY;
s->open_flags &= ~O_ACCMODE;
if (bdrv_flags & BDRV_O_RDWR) {
@@ -204,7 +154,7 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
* and O_DIRECT for no caching. */
if ((bdrv_flags & BDRV_O_NOCACHE))
s->open_flags |= O_DIRECT;
if (!(bdrv_flags & BDRV_O_CACHE_WB))
else if (!(bdrv_flags & BDRV_O_CACHE_WB))
s->open_flags |= O_DSYNC;
s->fd = -1;
@@ -672,31 +622,6 @@ static int64_t raw_getlength(BlockDriverState *bs)
} else
return st.st_size;
}
#elif defined(__NetBSD__)
static int64_t raw_getlength(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
int fd = s->fd;
struct stat st;
if (fstat(fd, &st))
return -1;
if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
struct dkwedge_info dkw;
if (ioctl(fd, DIOCGWEDGEINFO, &dkw) != -1) {
return dkw.dkw_size * 512;
} else {
struct disklabel dl;
if (ioctl(fd, DIOCGDINFO, &dl))
return -1;
return (uint64_t)dl.d_secsize *
dl.d_partitions[DISKPART(st.st_rdev)].p_size;
}
} else
return st.st_size;
}
#elif defined(__sun__)
static int64_t raw_getlength(BlockDriverState *bs)
{
@@ -793,17 +718,6 @@ static int64_t raw_getlength(BlockDriverState *bs)
}
#endif
static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
{
struct stat st;
BDRVRawState *s = bs->opaque;
if (fstat(s->fd, &st) < 0) {
return -errno;
}
return (int64_t)st.st_blocks * 512;
}
static int raw_create(const char *filename, QEMUOptionParameter *options)
{
int fd;
@@ -899,8 +813,6 @@ static BlockDriver bdrv_file = {
.bdrv_truncate = raw_truncate,
.bdrv_getlength = raw_getlength,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
.create_options = raw_create_options,
};
@@ -1169,8 +1081,6 @@ static BlockDriver bdrv_host_device = {
.bdrv_read = raw_read,
.bdrv_write = raw_write,
.bdrv_getlength = raw_getlength,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
/* generic scsi device */
#ifdef __linux__
@@ -1205,7 +1115,6 @@ static int floppy_probe_device(const char *filename)
int fd, ret;
int prio = 0;
struct floppy_struct fdparam;
struct stat st;
if (strstart(filename, "/dev/fd", NULL))
prio = 50;
@@ -1214,17 +1123,12 @@ static int floppy_probe_device(const char *filename)
if (fd < 0) {
goto out;
}
ret = fstat(fd, &st);
if (ret == -1 || !S_ISBLK(st.st_mode)) {
goto outc;
}
/* Attempt to detect via a floppy specific ioctl */
ret = ioctl(fd, FDGETPRM, &fdparam);
if (ret >= 0)
prio = 100;
outc:
close(fd);
out:
return prio;
@@ -1292,8 +1196,6 @@ static BlockDriver bdrv_host_floppy = {
.bdrv_read = raw_read,
.bdrv_write = raw_write,
.bdrv_getlength = raw_getlength,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
/* removable device support */
.bdrv_is_inserted = floppy_is_inserted,
@@ -1315,23 +1217,17 @@ static int cdrom_probe_device(const char *filename)
{
int fd, ret;
int prio = 0;
struct stat st;
fd = open(filename, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
goto out;
}
ret = fstat(fd, &st);
if (ret == -1 || !S_ISBLK(st.st_mode)) {
goto outc;
}
/* Attempt to detect via a CDROM specific ioctl */
ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
if (ret >= 0)
prio = 100;
outc:
close(fd);
out:
return prio;
@@ -1397,8 +1293,6 @@ static BlockDriver bdrv_host_cdrom = {
.bdrv_read = raw_read,
.bdrv_write = raw_write,
.bdrv_getlength = raw_getlength,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
/* removable device support */
.bdrv_is_inserted = cdrom_is_inserted,
@@ -1522,8 +1416,6 @@ static BlockDriver bdrv_host_cdrom = {
.bdrv_read = raw_read,
.bdrv_write = raw_write,
.bdrv_getlength = raw_getlength,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
/* removable device support */
.bdrv_is_inserted = cdrom_is_inserted,

View File

@@ -88,9 +88,9 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
}
overlapped = FILE_ATTRIBUTE_NORMAL;
if (flags & BDRV_O_NOCACHE)
overlapped |= FILE_FLAG_NO_BUFFERING;
if (!(flags & BDRV_O_CACHE_WB))
if ((flags & BDRV_O_NOCACHE))
overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
else if (!(flags & BDRV_O_CACHE_WB))
overlapped |= FILE_FLAG_WRITE_THROUGH;
s->hfile = CreateFile(filename, access_flags,
FILE_SHARE_READ, NULL,
@@ -213,31 +213,6 @@ static int64_t raw_getlength(BlockDriverState *bs)
return l.QuadPart;
}
static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
{
typedef DWORD (WINAPI * get_compressed_t)(const char *filename,
DWORD * high);
get_compressed_t get_compressed;
struct _stati64 st;
const char *filename = bs->filename;
/* WinNT support GetCompressedFileSize to determine allocate size */
get_compressed =
(get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"),
"GetCompressedFileSizeA");
if (get_compressed) {
DWORD high, low;
low = get_compressed(filename, &high);
if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR) {
return (((int64_t) high) << 32) + low;
}
}
if (_stati64(filename, &st) < 0) {
return -1;
}
return st.st_size;
}
static int raw_create(const char *filename, QEMUOptionParameter *options)
{
int fd;
@@ -282,8 +257,6 @@ static BlockDriver bdrv_file = {
.bdrv_write = raw_write,
.bdrv_truncate = raw_truncate,
.bdrv_getlength = raw_getlength,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
.create_options = raw_create_options,
};
@@ -376,9 +349,9 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
create_flags = OPEN_EXISTING;
overlapped = FILE_ATTRIBUTE_NORMAL;
if (flags & BDRV_O_NOCACHE)
overlapped |= FILE_FLAG_NO_BUFFERING;
if (!(flags & BDRV_O_CACHE_WB))
if ((flags & BDRV_O_NOCACHE))
overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
else if (!(flags & BDRV_O_CACHE_WB))
overlapped |= FILE_FLAG_WRITE_THROUGH;
s->hfile = CreateFile(filename, access_flags,
FILE_SHARE_READ, NULL,
@@ -446,8 +419,6 @@ static BlockDriver bdrv_host_device = {
.bdrv_read = raw_read,
.bdrv_write = raw_write,
.bdrv_getlength = raw_getlength,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
};
static void bdrv_file_init(void)

File diff suppressed because it is too large Load Diff

71
block/rbd_types.h Normal file
View File

@@ -0,0 +1,71 @@
/*
* Ceph - scalable distributed file system
*
* Copyright (C) 2004-2010 Sage Weil <sage@newdream.net>
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software
* Foundation. See file COPYING.LIB.
*
*/
#ifndef CEPH_RBD_TYPES_H
#define CEPH_RBD_TYPES_H
/*
* rbd image 'foo' consists of objects
* foo.rbd - image metadata
* foo.00000000
* foo.00000001
* ... - data
*/
#define RBD_SUFFIX ".rbd"
#define RBD_DIRECTORY "rbd_directory"
#define RBD_INFO "rbd_info"
#define RBD_DEFAULT_OBJ_ORDER 22 /* 4MB */
#define RBD_MAX_OBJ_NAME_SIZE 96
#define RBD_MAX_BLOCK_NAME_SIZE 24
#define RBD_MAX_SEG_NAME_SIZE 128
#define RBD_COMP_NONE 0
#define RBD_CRYPT_NONE 0
#define RBD_HEADER_TEXT "<<< Rados Block Device Image >>>\n"
#define RBD_HEADER_SIGNATURE "RBD"
#define RBD_HEADER_VERSION "001.005"
struct rbd_info {
uint64_t max_id;
} __attribute__ ((packed));
struct rbd_obj_snap_ondisk {
uint64_t id;
uint64_t image_size;
} __attribute__((packed));
struct rbd_obj_header_ondisk {
char text[40];
char block_name[RBD_MAX_BLOCK_NAME_SIZE];
char signature[4];
char version[8];
struct {
uint8_t order;
uint8_t crypt_type;
uint8_t comp_type;
uint8_t unused;
} __attribute__((packed)) options;
uint64_t image_size;
uint64_t snap_seq;
uint32_t snap_count;
uint32_t reserved;
uint64_t snap_names_len;
struct rbd_obj_snap_ondisk snaps[0];
} __attribute__((packed));
#endif

View File

@@ -13,7 +13,6 @@
#include "qemu-error.h"
#include "qemu_socket.h"
#include "block_int.h"
#include "bitops.h"
#define SD_PROTO_VER 0x01
@@ -196,7 +195,7 @@ static inline uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval)
return hval;
}
static inline int is_data_obj_writable(SheepdogInode *inode, unsigned int idx)
static inline int is_data_obj_writeable(SheepdogInode *inode, unsigned int idx)
{
return inode->vdi_id == inode->data_vdi_id[idx];
}
@@ -444,12 +443,18 @@ static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov,
static int sd_schedule_bh(QEMUBHFunc *cb, SheepdogAIOCB *acb)
{
if (acb->bh) {
error_report("bug: %d %d", acb->aiocb_type, acb->aiocb_type);
error_report("bug: %d %d\n", acb->aiocb_type, acb->aiocb_type);
return -EIO;
}
acb->bh = qemu_bh_new(cb, acb);
if (!acb->bh) {
error_report("oom: %d %d\n", acb->aiocb_type, acb->aiocb_type);
return -EIO;
}
qemu_bh_schedule(acb->bh);
return 0;
}
@@ -496,7 +501,7 @@ static ssize_t recvmsg(int s, struct msghdr *msg, int flags)
}
buf = qemu_malloc(size);
ret = qemu_recv(s, buf, size, flags);
ret = recv(s, buf, size, flags);
if (ret < 0) {
goto out;
}
@@ -592,7 +597,7 @@ static int connect_to_sdog(const char *addr, const char *port)
ret = getaddrinfo(addr, port, &hints, &res0);
if (ret) {
error_report("unable to get address info %s, %s",
error_report("unable to get address info %s, %s\n",
addr, strerror(errno));
return -1;
}
@@ -622,7 +627,7 @@ static int connect_to_sdog(const char *addr, const char *port)
goto success;
}
fd = -1;
error_report("failed connect to %s:%s", addr, port);
error_report("failed connect to %s:%s\n", addr, port);
success:
freeaddrinfo(res0);
return fd;
@@ -638,7 +643,7 @@ again:
if (errno == EINTR || errno == EAGAIN) {
goto again;
}
error_report("failed to recv a rsp, %s", strerror(errno));
error_report("failed to recv a rsp, %s\n", strerror(errno));
return 1;
}
@@ -697,7 +702,7 @@ static int send_req(int sockfd, SheepdogReq *hdr, void *data,
ret = do_writev(sockfd, iov, sizeof(*hdr) + *wlen, 0);
if (ret) {
error_report("failed to send a req, %s", strerror(errno));
error_report("failed to send a req, %s\n", strerror(errno));
ret = -1;
}
@@ -717,7 +722,7 @@ static int do_req(int sockfd, SheepdogReq *hdr, void *data,
ret = do_read(sockfd, hdr, sizeof(*hdr));
if (ret) {
error_report("failed to get a rsp, %s", strerror(errno));
error_report("failed to get a rsp, %s\n", strerror(errno));
ret = -1;
goto out;
}
@@ -729,7 +734,7 @@ static int do_req(int sockfd, SheepdogReq *hdr, void *data,
if (*rlen) {
ret = do_read(sockfd, data, *rlen);
if (ret) {
error_report("failed to get the data, %s", strerror(errno));
error_report("failed to get the data, %s\n", strerror(errno));
ret = -1;
goto out;
}
@@ -766,7 +771,7 @@ static void send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id)
ret = add_aio_request(s, aio_req, acb->qiov->iov,
acb->qiov->niov, 0, acb->aiocb_type);
if (ret < 0) {
error_report("add_aio_request is failed");
error_report("add_aio_request is failed\n");
free_aio_req(s, aio_req);
if (QLIST_EMPTY(&acb->aioreq_head)) {
sd_finish_aiocb(acb);
@@ -799,7 +804,7 @@ static void aio_read_response(void *opaque)
/* read a header */
ret = do_read(fd, &rsp, sizeof(rsp));
if (ret) {
error_report("failed to get the header, %s", strerror(errno));
error_report("failed to get the header, %s\n", strerror(errno));
return;
}
@@ -810,7 +815,7 @@ static void aio_read_response(void *opaque)
}
}
if (!aio_req) {
error_report("cannot find aio_req %x", rsp.id);
error_report("cannot find aio_req %x\n", rsp.id);
return;
}
@@ -846,7 +851,7 @@ static void aio_read_response(void *opaque)
ret = do_readv(fd, acb->qiov->iov, rsp.data_length,
aio_req->iov_offset);
if (ret) {
error_report("failed to get the data, %s", strerror(errno));
error_report("failed to get the data, %s\n", strerror(errno));
return;
}
break;
@@ -854,7 +859,7 @@ static void aio_read_response(void *opaque)
if (rsp.result != SD_RES_SUCCESS) {
acb->ret = -EIO;
error_report("%s", sd_strerror(rsp.result));
error_report("%s\n", sd_strerror(rsp.result));
}
rest = free_aio_req(s, aio_req);
@@ -911,7 +916,7 @@ static int get_sheep_fd(BDRVSheepdogState *s)
fd = connect_to_sdog(s->addr, s->port);
if (fd < 0) {
error_report("%s", strerror(errno));
error_report("%s\n", strerror(errno));
return -1;
}
@@ -919,7 +924,7 @@ static int get_sheep_fd(BDRVSheepdogState *s)
ret = set_nodelay(fd);
if (ret) {
error_report("%s", strerror(errno));
error_report("%s\n", strerror(errno));
closesocket(fd);
return -1;
}
@@ -1035,7 +1040,7 @@ static int find_vdi_name(BDRVSheepdogState *s, char *filename, uint32_t snapid,
}
if (rsp->result != SD_RES_SUCCESS) {
error_report("cannot get vdi info, %s, %s %d %s",
error_report("cannot get vdi info, %s, %s %d %s\n",
sd_strerror(rsp->result), filename, snapid, tag);
ret = -1;
goto out;
@@ -1063,7 +1068,7 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
uint64_t old_oid = aio_req->base_oid;
if (!nr_copies) {
error_report("bug");
error_report("bug\n");
}
memset(&hdr, 0, sizeof(hdr));
@@ -1096,14 +1101,14 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
/* send a header */
ret = do_write(s->fd, &hdr, sizeof(hdr));
if (ret) {
error_report("failed to send a req, %s", strerror(errno));
error_report("failed to send a req, %s\n", strerror(errno));
return -EIO;
}
if (wlen) {
ret = do_writev(s->fd, iov, wlen, aio_req->iov_offset);
if (ret) {
error_report("failed to send a data, %s", strerror(errno));
error_report("failed to send a data, %s\n", strerror(errno));
return -EIO;
}
}
@@ -1145,7 +1150,7 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies,
ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
if (ret) {
error_report("failed to send a request to the sheep");
error_report("failed to send a request to the sheep\n");
return -1;
}
@@ -1153,7 +1158,7 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies,
case SD_RES_SUCCESS:
return 0;
default:
error_report("%s", sd_strerror(rsp->result));
error_report("%s\n", sd_strerror(rsp->result));
return -1;
}
}
@@ -1206,7 +1211,7 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
fd = connect_to_sdog(s->addr, s->port);
if (fd < 0) {
error_report("failed to connect");
error_report("failed to connect\n");
goto out;
}
@@ -1275,7 +1280,7 @@ static int do_sd_create(char *filename, int64_t vdi_size,
}
if (rsp->result != SD_RES_SUCCESS) {
error_report("%s, %s", sd_strerror(rsp->result), filename);
error_report("%s, %s\n", sd_strerror(rsp->result), filename);
return -EIO;
}
@@ -1286,49 +1291,6 @@ static int do_sd_create(char *filename, int64_t vdi_size,
return 0;
}
static int sd_prealloc(const char *filename)
{
BlockDriverState *bs = NULL;
uint32_t idx, max_idx;
int64_t vdi_size;
void *buf = qemu_mallocz(SD_DATA_OBJ_SIZE);
int ret;
ret = bdrv_file_open(&bs, filename, BDRV_O_RDWR);
if (ret < 0) {
goto out;
}
vdi_size = bdrv_getlength(bs);
if (vdi_size < 0) {
ret = vdi_size;
goto out;
}
max_idx = DIV_ROUND_UP(vdi_size, SD_DATA_OBJ_SIZE);
for (idx = 0; idx < max_idx; idx++) {
/*
* The created image can be a cloned image, so we need to read
* a data from the source image.
*/
ret = bdrv_pread(bs, idx * SD_DATA_OBJ_SIZE, buf, SD_DATA_OBJ_SIZE);
if (ret < 0) {
goto out;
}
ret = bdrv_pwrite(bs, idx * SD_DATA_OBJ_SIZE, buf, SD_DATA_OBJ_SIZE);
if (ret < 0) {
goto out;
}
}
out:
if (bs) {
bdrv_delete(bs);
}
qemu_free(buf);
return ret;
}
static int sd_create(const char *filename, QEMUOptionParameter *options)
{
int ret;
@@ -1338,16 +1300,14 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
BDRVSheepdogState s;
char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
uint32_t snapid;
int prealloc = 0;
const char *vdiname;
strstart(filename, "sheepdog:", &vdiname);
strstart(filename, "sheepdog:", (const char **)&filename);
memset(&s, 0, sizeof(s));
memset(vdi, 0, sizeof(vdi));
memset(tag, 0, sizeof(tag));
if (parse_vdiname(&s, vdiname, vdi, &snapid, tag) < 0) {
error_report("invalid filename");
if (parse_vdiname(&s, filename, vdi, &snapid, tag) < 0) {
error_report("invalid filename\n");
return -EINVAL;
}
@@ -1356,22 +1316,12 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
vdi_size = options->value.n;
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
backing_file = options->value.s;
} else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
if (!options->value.s || !strcmp(options->value.s, "off")) {
prealloc = 0;
} else if (!strcmp(options->value.s, "full")) {
prealloc = 1;
} else {
error_report("Invalid preallocation mode: '%s'",
options->value.s);
return -EINVAL;
}
}
options++;
}
if (vdi_size > SD_MAX_VDI_SIZE) {
error_report("too big image size");
error_report("too big image size\n");
return -EINVAL;
}
@@ -1383,7 +1333,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
/* Currently, only Sheepdog backing image is supported. */
drv = bdrv_find_protocol(backing_file);
if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {
error_report("backing_file must be a sheepdog image");
error_report("backing_file must be a sheepdog image\n");
return -EINVAL;
}
@@ -1394,7 +1344,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
s = bs->opaque;
if (!is_snapshot(&s->inode)) {
error_report("cannot clone from a non snapshot vdi");
error_report("cannot clone from a non snapshot vdi\n");
bdrv_delete(bs);
return -EINVAL;
}
@@ -1403,12 +1353,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
bdrv_delete(bs);
}
ret = do_sd_create(vdi, vdi_size, base_vid, &vid, 0, s.addr, s.port);
if (!prealloc || ret) {
return ret;
}
return sd_prealloc(filename);
return do_sd_create((char *)vdi, vdi_size, base_vid, &vid, 0, s.addr, s.port);
}
static void sd_close(BlockDriverState *bs)
@@ -1439,7 +1384,7 @@ static void sd_close(BlockDriverState *bs)
if (!ret && rsp->result != SD_RES_SUCCESS &&
rsp->result != SD_RES_VDI_NOT_LOCKED) {
error_report("%s, %s", sd_strerror(rsp->result), s->name);
error_report("%s, %s\n", sd_strerror(rsp->result), s->name);
}
qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL, NULL);
@@ -1461,10 +1406,10 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
unsigned int datalen;
if (offset < s->inode.vdi_size) {
error_report("shrinking is not supported");
error_report("shrinking is not supported\n");
return -EINVAL;
} else if (offset > SD_MAX_VDI_SIZE) {
error_report("too big image size");
error_report("too big image size\n");
return -EINVAL;
}
@@ -1481,7 +1426,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
close(fd);
if (ret < 0) {
error_report("failed to update an inode.");
error_report("failed to update an inode.\n");
return -EIO;
}
@@ -1554,7 +1499,7 @@ static int sd_create_branch(BDRVSheepdogState *s)
fd = connect_to_sdog(s->addr, s->port);
if (fd < 0) {
error_report("failed to connect");
error_report("failed to connect\n");
goto out;
}
@@ -1631,7 +1576,7 @@ static void sd_readv_writev_bh_cb(void *p)
create = 1;
} else if (acb->aiocb_type == AIOCB_WRITE_UDATA
&& !is_data_obj_writable(inode, idx)) {
&& !is_data_obj_writeable(inode, idx)) {
/* Copy-On-Write */
create = 1;
old_oid = oid;
@@ -1672,7 +1617,7 @@ static void sd_readv_writev_bh_cb(void *p)
ret = add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
create, acb->aiocb_type);
if (ret < 0) {
error_report("add_aio_request is failed");
error_report("add_aio_request is failed\n");
free_aio_req(s, aio_req);
acb->ret = -EIO;
goto out;
@@ -1749,7 +1694,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
if (s->is_snapshot) {
error_report("You can't create a snapshot of a snapshot VDI, "
"%s (%" PRIu32 ").", s->name, s->inode.vdi_id);
"%s (%" PRIu32 ").\n", s->name, s->inode.vdi_id);
return -EINVAL;
}
@@ -1772,7 +1717,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),
s->inode.nr_copies, datalen, 0, 0);
if (ret < 0) {
error_report("failed to write snapshot's inode.");
error_report("failed to write snapshot's inode.\n");
ret = -EIO;
goto cleanup;
}
@@ -1780,7 +1725,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
ret = do_sd_create(s->name, s->inode.vdi_size, s->inode.vdi_id, &new_vid, 1,
s->addr, s->port);
if (ret < 0) {
error_report("failed to create inode for snapshot. %s",
error_report("failed to create inode for snapshot. %s\n",
strerror(errno));
ret = -EIO;
goto cleanup;
@@ -1792,7 +1737,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
s->inode.nr_copies, datalen, 0);
if (ret < 0) {
error_report("failed to read new inode info. %s", strerror(errno));
error_report("failed to read new inode info. %s\n", strerror(errno));
ret = -EIO;
goto cleanup;
}
@@ -1831,14 +1776,14 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
ret = find_vdi_name(s, vdi, snapid, tag, &vid, 1);
if (ret) {
error_report("Failed to find_vdi_name");
error_report("Failed to find_vdi_name\n");
ret = -ENOENT;
goto out;
}
fd = connect_to_sdog(s->addr, s->port);
if (fd < 0) {
error_report("failed to connect");
error_report("failed to connect\n");
goto out;
}
@@ -1856,7 +1801,7 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
memcpy(&s->inode, buf, sizeof(s->inode));
if (!s->inode.vm_state_size) {
error_report("Invalid snapshot");
error_report("Invalid snapshot\n");
ret = -ENOENT;
goto out;
}
@@ -1873,7 +1818,7 @@ out:
qemu_free(buf);
qemu_free(old_s);
error_report("failed to open. recover old bdrv_sd_state.");
error_report("failed to open. recover old bdrv_sd_state.\n");
return ret;
}
@@ -1884,6 +1829,20 @@ static int sd_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
return 0;
}
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
#define BITS_PER_BYTE 8
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long))
static inline int test_bit(unsigned int nr, const unsigned long *addr)
{
return ((1UL << (nr % BITS_PER_LONG)) &
(((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
}
static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
{
BDRVSheepdogState *s = bs->opaque;
@@ -1928,7 +1887,7 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
fd = connect_to_sdog(s->addr, s->port);
if (fd < 0) {
error_report("failed to connect");
error_report("failed to connect\n");
goto out;
}
@@ -2002,7 +1961,7 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
}
if (ret < 0) {
error_report("failed to save vmstate %s", strerror(errno));
error_report("failed to save vmstate %s\n", strerror(errno));
ret = -EIO;
goto cleanup;
}
@@ -2044,11 +2003,6 @@ static QEMUOptionParameter sd_create_options[] = {
.type = OPT_STRING,
.help = "File name of a base image"
},
{
.name = BLOCK_OPT_PREALLOC,
.type = OPT_STRING,
.help = "Preallocation mode (allowed values: off, full)"
},
{ NULL }
};

View File

@@ -87,7 +87,6 @@ void uuid_unparse(const uuid_t uu, char *out);
#define MiB (KiB * KiB)
#define SECTOR_SIZE 512
#define DEFAULT_CLUSTER_SIZE (1 * MiB)
#if defined(CONFIG_VDI_DEBUG)
#define logout(fmt, ...) \
@@ -114,7 +113,7 @@ void uuid_unparse(const uuid_t uu, char *out);
*/
#define VDI_TEXT "<<< QEMU VM Virtual Disk Image >>>\n"
/* Unallocated blocks use this index (no need to convert endianness). */
/* Unallocated blocks use this index (no need to convert endianess). */
#define VDI_UNALLOCATED UINT32_MAX
#if !defined(CONFIG_UUID)
@@ -152,7 +151,6 @@ typedef struct {
/* Buffer for new allocated block. */
void *block_buffer;
void *orig_buf;
bool is_write;
int header_modified;
BlockDriverAIOCB *hd_aiocb;
struct iovec hd_iov;
@@ -196,7 +194,7 @@ typedef struct {
uint32_t block_sectors;
/* First sector of block map. */
uint32_t bmap_sector;
/* VDI header (converted to host endianness). */
/* VDI header (converted to host endianess). */
VdiHeader header;
} BDRVVdiState;
@@ -505,8 +503,6 @@ static VdiAIOCB *vdi_aio_setup(BlockDriverState *bs, int64_t sector_num,
acb->hd_aiocb = NULL;
acb->sector_num = sector_num;
acb->qiov = qiov;
acb->is_write = is_write;
if (qiov->niov > 1) {
acb->buf = qemu_blockalign(bs, qiov->size);
acb->orig_buf = acb->buf;
@@ -545,20 +541,14 @@ static int vdi_schedule_bh(QEMUBHFunc *cb, VdiAIOCB *acb)
}
static void vdi_aio_read_cb(void *opaque, int ret);
static void vdi_aio_write_cb(void *opaque, int ret);
static void vdi_aio_rw_bh(void *opaque)
static void vdi_aio_read_bh(void *opaque)
{
VdiAIOCB *acb = opaque;
logout("\n");
qemu_bh_delete(acb->bh);
acb->bh = NULL;
if (acb->is_write) {
vdi_aio_write_cb(opaque, 0);
} else {
vdi_aio_read_cb(opaque, 0);
}
vdi_aio_read_cb(opaque, 0);
}
static void vdi_aio_read_cb(void *opaque, int ret)
@@ -606,7 +596,7 @@ static void vdi_aio_read_cb(void *opaque, int ret)
if (bmap_entry == VDI_UNALLOCATED) {
/* Block not allocated, return zeros, no need to wait. */
memset(acb->buf, 0, n_sectors * SECTOR_SIZE);
ret = vdi_schedule_bh(vdi_aio_rw_bh, acb);
ret = vdi_schedule_bh(vdi_aio_read_bh, acb);
if (ret < 0) {
goto done;
}
@@ -620,7 +610,6 @@ static void vdi_aio_read_cb(void *opaque, int ret)
acb->hd_aiocb = bdrv_aio_readv(bs->file, offset, &acb->hd_qiov,
n_sectors, vdi_aio_read_cb, acb);
if (acb->hd_aiocb == NULL) {
ret = -EIO;
goto done;
}
}
@@ -639,23 +628,12 @@ static BlockDriverAIOCB *vdi_aio_readv(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque)
{
VdiAIOCB *acb;
int ret;
logout("\n");
acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
if (!acb) {
return NULL;
}
ret = vdi_schedule_bh(vdi_aio_rw_bh, acb);
if (ret < 0) {
if (acb->qiov->niov > 1) {
qemu_vfree(acb->orig_buf);
}
qemu_aio_release(acb);
return NULL;
}
vdi_aio_read_cb(acb, 0);
return &acb->common;
}
@@ -695,7 +673,6 @@ static void vdi_aio_write_cb(void *opaque, int ret)
acb->hd_aiocb = bdrv_aio_writev(bs->file, 0, &acb->hd_qiov, 1,
vdi_aio_write_cb, acb);
if (acb->hd_aiocb == NULL) {
ret = -EIO;
goto done;
}
return;
@@ -725,7 +702,6 @@ static void vdi_aio_write_cb(void *opaque, int ret)
acb->hd_aiocb = bdrv_aio_writev(bs->file, offset, &acb->hd_qiov,
n_sectors, vdi_aio_write_cb, acb);
if (acb->hd_aiocb == NULL) {
ret = -EIO;
goto done;
}
return;
@@ -776,7 +752,6 @@ static void vdi_aio_write_cb(void *opaque, int ret)
&acb->hd_qiov, s->block_sectors,
vdi_aio_write_cb, acb);
if (acb->hd_aiocb == NULL) {
ret = -EIO;
goto done;
}
} else {
@@ -789,7 +764,6 @@ static void vdi_aio_write_cb(void *opaque, int ret)
acb->hd_aiocb = bdrv_aio_writev(bs->file, offset, &acb->hd_qiov,
n_sectors, vdi_aio_write_cb, acb);
if (acb->hd_aiocb == NULL) {
ret = -EIO;
goto done;
}
}
@@ -809,23 +783,12 @@ static BlockDriverAIOCB *vdi_aio_writev(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque)
{
VdiAIOCB *acb;
int ret;
logout("\n");
acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
if (!acb) {
return NULL;
}
ret = vdi_schedule_bh(vdi_aio_rw_bh, acb);
if (ret < 0) {
if (acb->qiov->niov > 1) {
qemu_vfree(acb->orig_buf);
}
qemu_aio_release(acb);
return NULL;
}
vdi_aio_write_cb(acb, 0);
return &acb->common;
}
@@ -835,7 +798,7 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
int result = 0;
uint64_t bytes = 0;
uint32_t blocks;
size_t block_size = DEFAULT_CLUSTER_SIZE;
size_t block_size = 1 * MiB;
uint32_t image_type = VDI_TYPE_DYNAMIC;
VdiHeader header;
size_t i;
@@ -953,8 +916,7 @@ static QEMUOptionParameter vdi_create_options[] = {
{
.name = BLOCK_OPT_CLUSTER_SIZE,
.type = OPT_SIZE,
.help = "VDI cluster (block) size",
.value = { .n = DEFAULT_CLUSTER_SIZE },
.help = "VDI cluster (block) size"
},
#endif
#if defined(CONFIG_VDI_STATIC_IMAGE)

File diff suppressed because it is too large Load Diff

View File

@@ -505,8 +505,12 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options)
int ret = -EIO;
// Read out options
total_sectors = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n /
BDRV_SECTOR_SIZE;
while (options && options->name) {
if (!strcmp(options->name, "size")) {
total_sectors = options->value.n / 512;
}
options++;
}
// Create the file
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);

View File

@@ -39,7 +39,6 @@
#define BLOCK_OPT_CLUSTER_SIZE "cluster_size"
#define BLOCK_OPT_TABLE_SIZE "table_size"
#define BLOCK_OPT_PREALLOC "preallocation"
#define BLOCK_OPT_SUBFMT "subformat"
typedef struct AIOPool {
void (*cancel)(BlockDriverAIOCB *acb);
@@ -86,7 +85,6 @@ struct BlockDriver {
const char *protocol_name;
int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset);
int64_t (*bdrv_getlength)(BlockDriverState *bs);
int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs);
int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
@@ -196,6 +194,7 @@ struct BlockDriverState {
/* NOTE: the following infos are only hints for real hardware
drivers. They are not used by the block driver */
int cyls, heads, secs, translation;
int type;
BlockErrorAction on_read_error, on_write_error;
char device_name[32];
unsigned long *dirty_bitmap;
@@ -205,8 +204,8 @@ struct BlockDriverState {
void *private;
};
#define CHANGE_MEDIA 0x01
#define CHANGE_SIZE 0x02
#define CHANGE_MEDIA 0x01
#define CHANGE_SIZE 0x02
struct BlockDriverAIOCB {
AIOPool *pool;

View File

@@ -17,8 +17,6 @@
#include "hw/qdev.h"
#include "block_int.h"
DriveInfo *extboot_drive = NULL;
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
static const char *const if_name[IF_COUNT] = {
@@ -238,11 +236,18 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
int on_read_error, on_write_error;
const char *devaddr;
DriveInfo *dinfo;
int is_extboot = 0;
int snapshot = 0;
int ret;
translation = BIOS_ATA_TRANSLATION_AUTO;
if (default_to_scsi) {
type = IF_SCSI;
pstrcpy(devname, sizeof(devname), "scsi");
} else {
type = IF_IDE;
pstrcpy(devname, sizeof(devname), "ide");
}
media = MEDIA_DISK;
/* extract parameters */
@@ -268,11 +273,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
error_report("unsupported bus type '%s'", buf);
return NULL;
}
} else {
type = default_to_scsi ? IF_SCSI : IF_IDE;
pstrcpy(devname, sizeof(devname), if_name[type]);
}
max_devs = if_max_devs[type];
if (cyls || heads || secs) {
@@ -292,7 +293,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
if ((buf = qemu_opt_get(opts, "trans")) != NULL) {
if (!cyls) {
error_report("'%s' trans must be used with cyls, heads and secs",
error_report("'%s' trans must be used with cyls,heads and secs",
buf);
return NULL;
}
@@ -313,7 +314,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
media = MEDIA_DISK;
} else if (!strcmp(buf, "cdrom")) {
if (cyls || secs || heads) {
error_report("CHS can't be set with media=%s", buf);
error_report("'%s' invalid physical CHS format", buf);
return NULL;
}
media = MEDIA_CDROM;
@@ -325,7 +326,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
if (!strcmp(buf, "off") || !strcmp(buf, "none")) {
bdrv_flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
bdrv_flags |= BDRV_O_NOCACHE;
} else if (!strcmp(buf, "writeback")) {
bdrv_flags |= BDRV_O_CACHE_WB;
} else if (!strcmp(buf, "unsafe")) {
@@ -366,12 +367,6 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
}
}
is_extboot = qemu_opt_get_bool(opts, "boot", 0);
if (is_extboot && extboot_drive) {
fprintf(stderr, "qemu: two bootable drives specified\n");
return NULL;
}
on_write_error = BLOCK_ERR_STOP_ENOSPC;
if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO && type != IF_NONE) {
@@ -477,10 +472,6 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
strncpy(dinfo->serial, serial, sizeof(dinfo->serial) - 1);
QTAILQ_INSERT_TAIL(&drives, dinfo, next);
if (is_extboot) {
extboot_drive = dinfo;
}
bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);
switch(type) {
@@ -496,8 +487,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
}
break;
case MEDIA_CDROM:
bdrv_set_removable(dinfo->bdrv, 1);
dinfo->media_cd = 1;
bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);
break;
}
break;
@@ -505,7 +495,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
/* FIXME: This isn't really a floppy, but it's a reasonable
approximation. */
case IF_FLOPPY:
bdrv_set_removable(dinfo->bdrv, 1);
bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_FLOPPY);
break;
case IF_PFLASH:
case IF_MTD:
@@ -513,7 +503,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
case IF_VIRTIO:
/* add virtio block device */
opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0);
qemu_opt_set(opts, "driver", "virtio-blk");
qemu_opt_set(opts, "driver", "virtio-blk-pci");
qemu_opt_set(opts, "drive", dinfo->id);
if (devaddr)
qemu_opt_set(opts, "addr", devaddr);
@@ -581,16 +571,15 @@ void do_commit(Monitor *mon, const QDict *qdict)
int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
const char *device = qdict_get_str(qdict, "device");
const char *filename = qdict_get_try_str(qdict, "snapshot-file");
const char *filename = qdict_get_try_str(qdict, "snapshot_file");
const char *format = qdict_get_try_str(qdict, "format");
BlockDriverState *bs;
BlockDriver *drv, *old_drv, *proto_drv;
BlockDriver *drv, *proto_drv;
int ret = 0;
int flags;
char old_filename[1024];
if (!filename) {
qerror_report(QERR_MISSING_PARAMETER, "snapshot-file");
qerror_report(QERR_MISSING_PARAMETER, "snapshot_file");
ret = -1;
goto out;
}
@@ -602,11 +591,6 @@ int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data)
goto out;
}
pstrcpy(old_filename, sizeof(old_filename), bs->filename);
old_drv = bs->drv;
flags = bs->open_flags;
if (!format) {
format = "qcow2";
}
@@ -626,7 +610,7 @@ int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data)
}
ret = bdrv_img_create(filename, format, bs->filename,
bs->drv->format_name, NULL, -1, flags);
bs->drv->format_name, NULL, -1, bs->open_flags);
if (ret) {
goto out;
}
@@ -634,20 +618,15 @@ int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data)
qemu_aio_flush();
bdrv_flush(bs);
flags = bs->open_flags;
bdrv_close(bs);
ret = bdrv_open(bs, filename, flags, drv);
/*
* If reopening the image file we just created fails, fall back
* and try to re-open the original image. If that fails too, we
* are in serious trouble.
* If reopening the image file we just created fails, we really
* are in trouble :(
*/
if (ret != 0) {
ret = bdrv_open(bs, old_filename, flags, old_drv);
if (ret != 0) {
qerror_report(QERR_OPEN_FILE_FAILED, old_filename);
} else {
qerror_report(QERR_OPEN_FILE_FAILED, filename);
}
abort();
}
out:
if (ret) {

View File

@@ -33,7 +33,6 @@ struct DriveInfo {
int bus;
int unit;
int auto_del; /* see blockdev_mark_auto_del() */
int media_cd;
QemuOpts *opts;
char serial[BLOCK_SERIAL_STRLEN + 1];
QTAILQ_ENTRY(DriveInfo) next;
@@ -66,6 +65,4 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data);
int do_block_resize(Monitor *mon, const QDict *qdict, QObject **ret_data);
extern DriveInfo *extboot_drive;
#endif

View File

@@ -29,7 +29,7 @@
#include "qemu.h"
#include "qemu-common.h"
/* For tb_lock */
#include "cpu.h"
#include "exec-all.h"
#include "tcg.h"
#include "qemu-timer.h"
#include "envlist.h"
@@ -237,7 +237,7 @@ void cpu_loop(CPUX86State *env)
break;
#ifndef TARGET_ABI32
case EXCP_SYSCALL:
/* syscall from syscall instruction */
/* syscall from syscall intruction */
if (bsd_type == target_freebsd)
env->regs[R_EAX] = do_freebsd_syscall(env,
env->regs[R_EAX],
@@ -690,8 +690,7 @@ static void usage(void)
"-bsd type select emulated BSD type FreeBSD/NetBSD/OpenBSD (default)\n"
"\n"
"Debug options:\n"
"-d options activate log (default logfile=%s)\n"
"-D logfile override default logfile location\n"
"-d options activate log (logfile=%s)\n"
"-p pagesize set the host page size to 'pagesize'\n"
"-singlestep always run in singlestep mode\n"
"-strace log system calls\n"
@@ -732,8 +731,6 @@ int main(int argc, char **argv)
{
const char *filename;
const char *cpu_model;
const char *log_file = DEBUG_LOGFILE;
const char *log_mask = NULL;
struct target_pt_regs regs1, *regs = &regs1;
struct image_info info1, *info = &info1;
TaskState ts1, *ts = &ts1;
@@ -748,6 +745,9 @@ int main(int argc, char **argv)
if (argc <= 1)
usage();
/* init debug */
cpu_set_log_filename(DEBUG_LOGFILE);
if ((envlist = envlist_create()) == NULL) {
(void) fprintf(stderr, "Unable to allocate envlist\n");
exit(1);
@@ -775,15 +775,22 @@ int main(int argc, char **argv)
if (!strcmp(r, "-")) {
break;
} else if (!strcmp(r, "d")) {
if (optind >= argc) {
int mask;
const CPULogItem *item;
if (optind >= argc)
break;
r = argv[optind++];
mask = cpu_str_to_log_mask(r);
if (!mask) {
printf("Log items (comma separated):\n");
for(item = cpu_log_items; item->mask != 0; item++) {
printf("%-10s %s\n", item->name, item->help);
}
exit(1);
}
log_mask = argv[optind++];
} else if (!strcmp(r, "D")) {
if (optind >= argc) {
break;
}
log_file = argv[optind++];
cpu_set_log(mask);
} else if (!strcmp(r, "E")) {
r = argv[optind++];
if (envlist_setenv(envlist, r) != 0)
@@ -856,27 +863,8 @@ int main(int argc, char **argv)
usage();
}
}
/* init debug */
cpu_set_log_filename(log_file);
if (log_mask) {
int mask;
const CPULogItem *item;
mask = cpu_str_to_log_mask(log_mask);
if (!mask) {
printf("Log items (comma separated):\n");
for (item = cpu_log_items; item->mask != 0; item++) {
printf("%-10s %s\n", item->name, item->help);
}
exit(1);
}
cpu_set_log(mask);
}
if (optind >= argc) {
if (optind >= argc)
usage();
}
filename = argv[optind];
/* Zero out regs */

View File

@@ -323,7 +323,7 @@ abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
/* Functions for accessing guest memory. The tget and tput functions
read/write single values, byteswapping as necessary. The lock_user
read/write single values, byteswapping as neccessary. The lock_user
gets a pointer to a contiguous area of guest memory, but does not perform
and byteswapping. lock_user may return either a pointer to the guest
memory, or a temporary buffer. */

View File

@@ -31,6 +31,7 @@
#include <sys/syscall.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <signal.h>
#include <utime.h>
#include "qemu.h"

View File

@@ -19,6 +19,7 @@
#include "qemu-common.h"
#include "qemu-char.h"
#include "sysemu.h"
#include "net.h"
#include "bt-host.h"

View File

@@ -19,6 +19,7 @@
#include "qemu-common.h"
#include "qemu-char.h"
#include "sysemu.h"
#include "net.h"
#include "hw/bt.h"

View File

@@ -14,6 +14,7 @@
#include "qemu-common.h"
#include "hw/hw.h"
#include "qemu-timer.h"
#include "sysemu.h"
#include "qemu-char.h"
#include "buffered_file.h"
@@ -237,7 +238,7 @@ static void buffered_rate_tick(void *opaque)
return;
}
qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 100);
qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 100);
if (s->freeze_output)
return;
@@ -273,9 +274,9 @@ QEMUFile *qemu_fopen_ops_buffered(void *opaque,
buffered_set_rate_limit,
buffered_get_rate_limit);
s->timer = qemu_new_timer_ms(rt_clock, buffered_rate_tick, s);
s->timer = qemu_new_timer(rt_clock, buffered_rate_tick, s);
qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 100);
qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 100);
return s->file;
}

View File

@@ -34,28 +34,7 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop)
asm volatile ("isync" : : : "memory");
}
/*
* Is this correct for PPC?
*/
static inline void dma_flush_range(unsigned long start, unsigned long stop)
{
}
#elif defined(__ia64__)
static inline void flush_icache_range(unsigned long start, unsigned long stop)
{
while (start < stop) {
asm volatile ("fc %0" :: "r"(start));
start += 32;
}
asm volatile (";;sync.i;;srlz.i;;");
}
#define dma_flush_range(start, end) flush_icache_range(start, end)
#define qemu_cache_utils_init(envp) do { (void) (envp); } while (0)
#else
static inline void dma_flush_range(unsigned long start, unsigned long stop)
{
}
#define qemu_cache_utils_init(envp) do { (void) (envp); } while (0)
#endif

View File

@@ -267,9 +267,8 @@ static QString *read_line(FILE *file, char *key)
{
char value[128];
if (fscanf(file, "%127s%127s", key, value) == EOF) {
if (fscanf(file, "%s%s", key, value) == EOF)
return NULL;
}
remove_dots(key);
return qstring_from_str(value);
}

View File

@@ -33,8 +33,7 @@ START_TEST(escaped_string)
{ "\"\\n\"", "\n" },
{ "\"\\r\"", "\r" },
{ "\"\\t\"", "\t" },
{ "\"/\"", "/" },
{ "\"\\/\"", "/", .skip = 1 },
{ "\"\\/\"", "\\/" },
{ "\"\\\\\"", "\\" },
{ "\"\\\"\"", "\"" },
{ "\"hello world \\\"embedded string\\\"\"",

6
cmd.c
View File

@@ -486,7 +486,7 @@ timestr(
snprintf(ts, size, "%u:%02u.%02u",
(unsigned int) MINUTES(tv->tv_sec),
(unsigned int) SECONDS(tv->tv_sec),
(unsigned int) (usec * 100));
(unsigned int) usec * 100);
return;
}
format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */
@@ -497,9 +497,9 @@ timestr(
(unsigned int) HOURS(tv->tv_sec),
(unsigned int) MINUTES(tv->tv_sec),
(unsigned int) SECONDS(tv->tv_sec),
(unsigned int) (usec * 100));
(unsigned int) usec * 100);
} else {
snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
snprintf(ts, size, "0.%04u sec", (unsigned int) usec * 10000);
}
}

View File

@@ -26,45 +26,45 @@ struct sigfd_compat_info
static void *sigwait_compat(void *opaque)
{
struct sigfd_compat_info *info = opaque;
int err;
sigset_t all;
sigfillset(&all);
pthread_sigmask(SIG_BLOCK, &all, NULL);
sigprocmask(SIG_BLOCK, &all, NULL);
while (1) {
int sig;
int err;
do {
siginfo_t siginfo;
err = sigwait(&info->mask, &sig);
if (err != 0) {
if (errno == EINTR) {
continue;
} else {
return NULL;
}
} else {
struct qemu_signalfd_siginfo buffer;
err = sigwaitinfo(&info->mask, &siginfo);
if (err == -1 && errno == EINTR) {
err = 0;
continue;
}
if (err > 0) {
char buffer[128];
size_t offset = 0;
memset(&buffer, 0, sizeof(buffer));
buffer.ssi_signo = sig;
memcpy(buffer, &err, sizeof(err));
while (offset < sizeof(buffer)) {
ssize_t len;
len = write(info->fd, (char *)&buffer + offset,
len = write(info->fd, buffer + offset,
sizeof(buffer) - offset);
if (len == -1 && errno == EINTR)
continue;
if (len <= 0) {
return NULL;
err = -1;
break;
}
offset += len;
}
}
}
} while (err >= 0);
return NULL;
}
static int qemu_signalfd_compat(const sigset_t *mask)
@@ -115,14 +115,3 @@ int qemu_signalfd(const sigset_t *mask)
return qemu_signalfd_compat(mask);
}
bool qemu_signalfd_available(void)
{
#ifdef CONFIG_SIGNALFD
errno = 0;
syscall(SYS_signalfd, -1, NULL, _NSIG / 8);
return errno != ENOSYS;
#else
return false;
#endif
}

View File

@@ -39,6 +39,5 @@ struct qemu_signalfd_siginfo {
};
int qemu_signalfd(const sigset_t *mask);
bool qemu_signalfd_available(void);
#endif

View File

@@ -1,34 +0,0 @@
/* public domain */
#ifndef COMPILER_H
#define COMPILER_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))
#else
#define QEMU_WARN_UNUSED_RESULT
#endif
#define QEMU_BUILD_BUG_ON(x) \
typedef char qemu_build_bug_on__##__LINE__[(x)?-1:1];
#if defined __GNUC__
# if (__GNUC__ < 4) || \
defined(__GNUC_MINOR__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 4)
/* gcc versions before 4.4.x don't support gnu_printf, so use printf. */
# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2)))
# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m)))
# else
/* Use gnu_printf when supported (qemu uses standard format strings). */
# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2)))
# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
# endif
#else
#define GCC_ATTR /**/
#define GCC_FMT_ATTR(n, m)
#endif
#endif /* COMPILER_H */

902
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -180,7 +180,7 @@ void vga_hw_screen_dump(const char *filename)
active_console = consoles[0];
/* There is currently no way of specifying which screen we want to dump,
so always dump the first one. */
if (consoles[0] && consoles[0]->hw_screen_dump)
if (consoles[0]->hw_screen_dump)
consoles[0]->hw_screen_dump(consoles[0]->hw, filename);
active_console = previous_active_console;
}
@@ -1135,7 +1135,7 @@ static void kbd_send_chars(void *opaque)
/* characters are pending: we send them a bit later (XXX:
horrible, should change char device API) */
if (s->out_fifo.count > 0) {
qemu_mod_timer(s->kbd_timer, qemu_get_clock_ms(rt_clock) + 1);
qemu_mod_timer(s->kbd_timer, qemu_get_clock(rt_clock) + 1);
}
}
@@ -1278,40 +1278,38 @@ static DisplaySurface* defaultallocator_create_displaysurface(int width, int hei
{
DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
int linesize = width * 4;
qemu_alloc_display(surface, width, height, linesize,
qemu_default_pixelformat(32), 0);
surface->width = width;
surface->height = height;
surface->linesize = width * 4;
surface->pf = qemu_default_pixelformat(32);
#ifdef HOST_WORDS_BIGENDIAN
surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
#else
surface->flags = QEMU_ALLOCATED_FLAG;
#endif
surface->data = (uint8_t*) qemu_mallocz(surface->linesize * surface->height);
return surface;
}
static DisplaySurface* defaultallocator_resize_displaysurface(DisplaySurface *surface,
int width, int height)
{
int linesize = width * 4;
qemu_alloc_display(surface, width, height, linesize,
qemu_default_pixelformat(32), 0);
return surface;
}
void qemu_alloc_display(DisplaySurface *surface, int width, int height,
int linesize, PixelFormat pf, int newflags)
{
void *data;
surface->width = width;
surface->height = height;
surface->linesize = linesize;
surface->pf = pf;
if (surface->flags & QEMU_ALLOCATED_FLAG) {
data = qemu_realloc(surface->data,
surface->linesize * surface->height);
} else {
data = qemu_malloc(surface->linesize * surface->height);
}
surface->data = (uint8_t *)data;
surface->flags = newflags | QEMU_ALLOCATED_FLAG;
surface->linesize = width * 4;
surface->pf = qemu_default_pixelformat(32);
if (surface->flags & QEMU_ALLOCATED_FLAG)
surface->data = (uint8_t*) qemu_realloc(surface->data, surface->linesize * surface->height);
else
surface->data = (uint8_t*) qemu_malloc(surface->linesize * surface->height);
#ifdef HOST_WORDS_BIGENDIAN
surface->flags |= QEMU_BIG_ENDIAN_FLAG;
surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
#else
surface->flags = QEMU_ALLOCATED_FLAG;
#endif
return surface;
}
DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
@@ -1349,15 +1347,8 @@ static struct DisplayAllocator default_allocator = {
static void dumb_display_init(void)
{
DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
int width = 640;
int height = 480;
ds->allocator = &default_allocator;
if (is_fixedsize_console()) {
width = active_console->g_width;
height = active_console->g_height;
}
ds->surface = qemu_create_displaysurface(ds, width, height);
ds->surface = qemu_create_displaysurface(ds, 640, 480);
register_displaystate(ds);
}
@@ -1466,7 +1457,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
s->out_fifo.buf = s->out_fifo_buf;
s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
s->kbd_timer = qemu_new_timer_ms(rt_clock, kbd_send_chars, s);
s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);
s->ds = ds;
if (!color_inited) {
@@ -1514,7 +1505,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
chr->init(chr);
}
int text_console_init(QemuOpts *opts, CharDriverState **_chr)
CharDriverState *text_console_init(QemuOpts *opts)
{
CharDriverState *chr;
TextConsole *s;
@@ -1546,7 +1537,7 @@ int text_console_init(QemuOpts *opts, CharDriverState **_chr)
if (!s) {
free(chr);
return -EBUSY;
return NULL;
}
s->chr = chr;
@@ -1554,9 +1545,7 @@ int text_console_init(QemuOpts *opts, CharDriverState **_chr)
s->g_height = height;
chr->opaque = s;
chr->chr_set_echo = text_console_set_echo;
*_chr = chr;
return 0;
return chr;
}
void text_consoles_set_display(DisplayState *ds)

View File

@@ -4,8 +4,6 @@
#include "qemu-char.h"
#include "qdict.h"
#include "notify.h"
#include "qerror.h"
#include "monitor.h"
/* keyboard/mouse support */
@@ -191,8 +189,6 @@ void register_displaystate(DisplayState *ds);
DisplayState *get_displaystate(void);
DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
int linesize, uint8_t *data);
void qemu_alloc_display(DisplaySurface *surface, int width, int height,
int linesize, PixelFormat pf, int newflags);
PixelFormat qemu_different_endianness_pixelformat(int bpp);
PixelFormat qemu_default_pixelformat(int bpp);
@@ -354,7 +350,7 @@ void vga_hw_text_update(console_ch_t *chardata);
int is_graphic_console(void);
int is_fixedsize_console(void);
int text_console_init(QemuOpts *opts, CharDriverState **_chr);
CharDriverState *text_console_init(QemuOpts *opts);
void text_consoles_set_display(DisplayState *ds);
void console_select(unsigned int index);
void console_color_init(DisplayState *ds);
@@ -372,33 +368,12 @@ void cocoa_display_init(DisplayState *ds, int full_screen);
void vnc_display_init(DisplayState *ds);
void vnc_display_close(DisplayState *ds);
int vnc_display_open(DisplayState *ds, const char *display);
void vnc_display_add_client(DisplayState *ds, int csock, int skipauth);
int vnc_display_disable_login(DisplayState *ds);
char *vnc_display_local_addr(DisplayState *ds);
#ifdef CONFIG_VNC
int vnc_display_password(DisplayState *ds, const char *password);
int vnc_display_disable_login(DisplayState *ds);
int vnc_display_pw_expire(DisplayState *ds, time_t expires);
void do_info_vnc_print(Monitor *mon, const QObject *data);
void do_info_vnc(Monitor *mon, QObject **ret_data);
#else
static inline int vnc_display_password(DisplayState *ds, const char *password)
{
qerror_report(QERR_FEATURE_DISABLED, "vnc");
return -ENODEV;
}
static inline int vnc_display_pw_expire(DisplayState *ds, time_t expires)
{
qerror_report(QERR_FEATURE_DISABLED, "vnc");
return -ENODEV;
};
static inline void do_info_vnc(Monitor *mon, QObject **ret_data)
{
};
static inline void do_info_vnc_print(Monitor *mon, const QObject *data)
{
monitor_printf(mon, "VNC support disabled\n");
};
#endif
char *vnc_display_local_addr(DisplayState *ds);
/* curses.c */
void curses_display_init(DisplayState *ds, int full_screen);

106
cpu-all.h
View File

@@ -123,7 +123,8 @@ typedef union {
endian ! */
typedef union {
float64 d;
#if defined(HOST_WORDS_BIGENDIAN)
#if defined(HOST_WORDS_BIGENDIAN) \
|| (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
struct {
uint32_t upper;
uint32_t lower;
@@ -137,17 +138,11 @@ typedef union {
uint64_t ll;
} CPU_DoubleU;
typedef union {
floatx80 d;
struct {
uint64_t lower;
uint16_t upper;
} l;
} CPU_LDoubleU;
#ifdef TARGET_SPARC
typedef union {
float128 q;
#if defined(HOST_WORDS_BIGENDIAN)
#if defined(HOST_WORDS_BIGENDIAN) \
|| (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
struct {
uint32_t upmost;
uint32_t upper;
@@ -171,6 +166,7 @@ typedef union {
} ll;
#endif
} CPU_QuadU;
#endif
/* CPU memory access without any memory or io remapping */
@@ -781,73 +777,25 @@ void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
extern CPUState *first_cpu;
extern CPUState *cpu_single_env;
/* Flags for use in ENV->INTERRUPT_PENDING.
The numbers assigned here are non-sequential in order to preserve
binary compatibility with the vmstate dump. Bit 0 (0x0001) was
previously used for CPU_INTERRUPT_EXIT, and is cleared when loading
the vmstate dump. */
/* External hardware interrupt pending. This is typically used for
interrupts from devices. */
#define CPU_INTERRUPT_HARD 0x0002
/* Exit the current TB. This is typically used when some system-level device
makes some change to the memory mapping. E.g. the a20 line change. */
#define CPU_INTERRUPT_EXITTB 0x0004
/* Halt the CPU. */
#define CPU_INTERRUPT_HALT 0x0020
/* Debug event pending. */
#define CPU_INTERRUPT_DEBUG 0x0080
/* Several target-specific external hardware interrupts. Each target/cpu.h
should define proper names based on these defines. */
#define CPU_INTERRUPT_TGT_EXT_0 0x0008
#define CPU_INTERRUPT_TGT_EXT_1 0x0010
#define CPU_INTERRUPT_TGT_EXT_2 0x0040
#define CPU_INTERRUPT_TGT_EXT_3 0x0200
#define CPU_INTERRUPT_TGT_EXT_4 0x1000
/* Several target-specific internal interrupts. These differ from the
preceeding target-specific interrupts in that they are intended to
originate from within the cpu itself, typically in response to some
instruction being executed. These, therefore, are not masked while
single-stepping within the debugger. */
#define CPU_INTERRUPT_TGT_INT_0 0x0100
#define CPU_INTERRUPT_TGT_INT_1 0x0400
#define CPU_INTERRUPT_TGT_INT_2 0x0800
/* First unused bit: 0x2000. */
/* The set of all bits that should be masked when single-stepping. */
#define CPU_INTERRUPT_SSTEP_MASK \
(CPU_INTERRUPT_HARD \
| CPU_INTERRUPT_TGT_EXT_0 \
| CPU_INTERRUPT_TGT_EXT_1 \
| CPU_INTERRUPT_TGT_EXT_2 \
| CPU_INTERRUPT_TGT_EXT_3 \
| CPU_INTERRUPT_TGT_EXT_4)
#ifndef CONFIG_USER_ONLY
typedef void (*CPUInterruptHandler)(CPUState *, int);
extern CPUInterruptHandler cpu_interrupt_handler;
static inline void cpu_interrupt(CPUState *s, int mask)
{
cpu_interrupt_handler(s, mask);
}
#else /* USER_ONLY */
void cpu_interrupt(CPUState *env, int mask);
#endif /* USER_ONLY */
#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
#define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
#define CPU_INTERRUPT_TIMER 0x08 /* internal timer exception pending */
#define CPU_INTERRUPT_FIQ 0x10 /* Fast interrupt pending. */
#define CPU_INTERRUPT_HALT 0x20 /* CPU halt wanted */
#define CPU_INTERRUPT_SMI 0x40 /* (x86 only) SMI interrupt pending */
#define CPU_INTERRUPT_DEBUG 0x80 /* Debug event occured. */
#define CPU_INTERRUPT_VIRQ 0x100 /* virtual interrupt pending. */
#define CPU_INTERRUPT_NMI 0x200 /* NMI pending. */
#define CPU_INTERRUPT_INIT 0x400 /* INIT pending. */
#define CPU_INTERRUPT_SIPI 0x800 /* SIPI pending. */
#define CPU_INTERRUPT_MCE 0x1000 /* (x86 only) MCE pending. */
void cpu_interrupt(CPUState *s, int mask);
void cpu_reset_interrupt(CPUState *env, int mask);
void cpu_exit(CPUState *s);
bool qemu_cpu_has_work(CPUState *env);
int qemu_cpu_has_work(CPUState *env);
/* Breakpoint/watchpoint flags */
#define BP_MEM_READ 0x01
@@ -915,14 +863,10 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
extern int phys_ram_fd;
extern ram_addr_t ram_size;
/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
#define RAM_PREALLOC_MASK (1 << 0)
typedef struct RAMBlock {
uint8_t *host;
ram_addr_t offset;
ram_addr_t length;
uint32_t flags;
char idstr[256];
QLIST_ENTRY(RAMBlock) next;
#if defined(__linux__) && !defined(TARGET_S390X)
@@ -1015,16 +959,14 @@ int cpu_physical_memory_get_dirty_tracking(void);
int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
target_phys_addr_t end_addr);
int cpu_physical_log_start(target_phys_addr_t start_addr,
ram_addr_t size);
int cpu_physical_log_stop(target_phys_addr_t start_addr,
ram_addr_t size);
void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
#endif /* !CONFIG_USER_ONLY */
int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
uint8_t *buf, int len, int is_write);
void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
uint64_t mcg_status, uint64_t addr, uint64_t misc,
int broadcast);
#endif /* CPU_ALL_H */

View File

@@ -34,21 +34,10 @@ typedef unsigned long ram_addr_t;
typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
void cpu_register_physical_memory_log(target_phys_addr_t start_addr,
ram_addr_t size,
ram_addr_t phys_offset,
ram_addr_t region_offset,
bool log_dirty);
static inline void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
ram_addr_t size,
ram_addr_t phys_offset,
ram_addr_t region_offset)
{
cpu_register_physical_memory_log(start_addr, size, phys_offset,
region_offset, false);
}
void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
ram_addr_t size,
ram_addr_t phys_offset,
ram_addr_t region_offset);
static inline void cpu_register_physical_memory(target_phys_addr_t start_addr,
ram_addr_t size,
ram_addr_t phys_offset)
@@ -61,15 +50,11 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
ram_addr_t size, void *host);
ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size);
void qemu_ram_free(ram_addr_t addr);
void qemu_ram_free_from_ptr(ram_addr_t addr);
void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
/* This should only be used for ram local to a device. */
void *qemu_get_ram_ptr(ram_addr_t addr);
void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size);
/* Same but slower, to use for migration, where the order of
* RAMBlocks must not change. */
void *qemu_safe_ram_ptr(ram_addr_t addr);
void qemu_put_ram_ptr(void *addr);
/* This should not be used by devices. */
int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
@@ -82,14 +67,14 @@ void cpu_unregister_io_memory(int table_address);
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
int len, int is_write);
static inline void cpu_physical_memory_read(target_phys_addr_t addr,
void *buf, int len)
uint8_t *buf, int len)
{
cpu_physical_memory_rw(addr, buf, len, 0);
}
static inline void cpu_physical_memory_write(target_phys_addr_t addr,
const void *buf, int len)
const uint8_t *buf, int len)
{
cpu_physical_memory_rw(addr, (void *)buf, len, 1);
cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
}
void *cpu_physical_memory_map(target_phys_addr_t addr,
target_phys_addr_t *plen,
@@ -105,17 +90,12 @@ struct CPUPhysMemoryClient {
void (*set_memory)(struct CPUPhysMemoryClient *client,
target_phys_addr_t start_addr,
ram_addr_t size,
ram_addr_t phys_offset,
bool log_dirty);
ram_addr_t phys_offset);
int (*sync_dirty_bitmap)(struct CPUPhysMemoryClient *client,
target_phys_addr_t start_addr,
target_phys_addr_t end_addr);
int (*migration_log)(struct CPUPhysMemoryClient *client,
int enable);
int (*log_start)(struct CPUPhysMemoryClient *client,
target_phys_addr_t phys_addr, ram_addr_t size);
int (*log_stop)(struct CPUPhysMemoryClient *client,
target_phys_addr_t phys_addr, ram_addr_t size);
QLIST_ENTRY(CPUPhysMemoryClient) list;
};
@@ -134,30 +114,15 @@ void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
void qemu_flush_coalesced_mmio_buffer(void);
uint32_t ldub_phys(target_phys_addr_t addr);
uint32_t lduw_le_phys(target_phys_addr_t addr);
uint32_t lduw_be_phys(target_phys_addr_t addr);
uint32_t ldl_le_phys(target_phys_addr_t addr);
uint32_t ldl_be_phys(target_phys_addr_t addr);
uint64_t ldq_le_phys(target_phys_addr_t addr);
uint64_t ldq_be_phys(target_phys_addr_t addr);
void stb_phys(target_phys_addr_t addr, uint32_t val);
void stw_le_phys(target_phys_addr_t addr, uint32_t val);
void stw_be_phys(target_phys_addr_t addr, uint32_t val);
void stl_le_phys(target_phys_addr_t addr, uint32_t val);
void stl_be_phys(target_phys_addr_t addr, uint32_t val);
void stq_le_phys(target_phys_addr_t addr, uint64_t val);
void stq_be_phys(target_phys_addr_t addr, uint64_t val);
#ifdef NEED_CPU_H
uint32_t lduw_phys(target_phys_addr_t addr);
uint32_t ldl_phys(target_phys_addr_t addr);
uint64_t ldq_phys(target_phys_addr_t addr);
void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val);
void stb_phys(target_phys_addr_t addr, uint32_t val);
void stw_phys(target_phys_addr_t addr, uint32_t val);
void stl_phys(target_phys_addr_t addr, uint32_t val);
void stq_phys(target_phys_addr_t addr, uint64_t val);
#endif
void cpu_physical_memory_write_rom(target_phys_addr_t addr,
const uint8_t *buf, int len);

View File

@@ -37,22 +37,16 @@
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
typedef int16_t target_short __attribute__ ((aligned(TARGET_SHORT_ALIGNMENT)));
typedef uint16_t target_ushort __attribute__((aligned(TARGET_SHORT_ALIGNMENT)));
typedef int32_t target_int __attribute__((aligned(TARGET_INT_ALIGNMENT)));
typedef uint32_t target_uint __attribute__((aligned(TARGET_INT_ALIGNMENT)));
typedef int64_t target_llong __attribute__((aligned(TARGET_LLONG_ALIGNMENT)));
typedef uint64_t target_ullong __attribute__((aligned(TARGET_LLONG_ALIGNMENT)));
/* target_ulong is the type of a virtual address */
#if TARGET_LONG_SIZE == 4
typedef int32_t target_long __attribute__((aligned(TARGET_LONG_ALIGNMENT)));
typedef uint32_t target_ulong __attribute__((aligned(TARGET_LONG_ALIGNMENT)));
typedef int32_t target_long;
typedef uint32_t target_ulong;
#define TARGET_FMT_lx "%08x"
#define TARGET_FMT_ld "%d"
#define TARGET_FMT_lu "%u"
#elif TARGET_LONG_SIZE == 8
typedef int64_t target_long __attribute__((aligned(TARGET_LONG_ALIGNMENT)));
typedef uint64_t target_ulong __attribute__((aligned(TARGET_LONG_ALIGNMENT)));
typedef int64_t target_long;
typedef uint64_t target_ulong;
#define TARGET_FMT_lx "%016" PRIx64
#define TARGET_FMT_ld "%" PRId64
#define TARGET_FMT_lu "%" PRIu64
@@ -203,7 +197,6 @@ typedef struct CPUWatchpoint {
int nr_cores; /* number of cores within this CPU package */ \
int nr_threads;/* number of threads within this CPU */ \
int running; /* Nonzero if cpu is currently running(usermode). */ \
int thread_id; \
/* user data */ \
void *opaque; \
\
@@ -212,7 +205,6 @@ typedef struct CPUWatchpoint {
uint32_t stopped; /* Artificially stopped */ \
struct QemuThread *thread; \
struct QemuCond *halt_cond; \
int thread_kicked; \
struct qemu_work_item *queued_work_first, *queued_work_last; \
const char *cpu_model_str; \
struct KVMState *kvm_state; \

File diff suppressed because it is too large Load Diff

968
cpus.c

File diff suppressed because it is too large Load Diff

9
cpus.h
View File

@@ -6,21 +6,16 @@ int qemu_init_main_loop(void);
void qemu_main_loop_start(void);
void resume_all_vcpus(void);
void pause_all_vcpus(void);
void cpu_stop_current(void);
bool qemu_system_is_ready(void);
void cpu_synchronize_all_states(void);
void cpu_synchronize_all_post_reset(void);
void cpu_synchronize_all_post_init(void);
/* vl.c */
extern int smp_cores;
extern int smp_threads;
extern int debug_requested;
extern int vmstop_requested;
void vm_state_notify(int running, int reason);
bool cpu_exec_all(void);
void set_numa_modes(void);
void set_cpu_log(const char *optarg);
void set_cpu_log_filename(const char *optarg);
void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg);
#endif

View File

@@ -211,7 +211,7 @@ void do_compare_and_swap32(void *cpu_env, int num)
uint32_t *value = (uint32_t*)((CPUX86State*)cpu_env)->regs[R_ECX];
DPRINTF("commpage: compare_and_swap32(%x,new,%p)\n", old, value);
if(old == tswap32(*value))
if(value && old == tswap32(*value))
{
uint32_t new = ((CPUX86State*)cpu_env)->regs[R_EDX];
*value = tswap32(new);

View File

@@ -738,8 +738,6 @@ TaskState *first_task_state;
int main(int argc, char **argv)
{
const char *filename;
const char *log_file = DEBUG_LOGFILE;
const char *log_mask = NULL;
struct target_pt_regs regs1, *regs = &regs1;
TaskState ts1, *ts = &ts1;
CPUState *env;
@@ -751,6 +749,9 @@ int main(int argc, char **argv)
if (argc <= 1)
usage();
/* init debug */
cpu_set_log_filename(DEBUG_LOGFILE);
optind = 1;
for(;;) {
if (optind >= argc)
@@ -763,15 +764,22 @@ int main(int argc, char **argv)
if (!strcmp(r, "-")) {
break;
} else if (!strcmp(r, "d")) {
if (optind >= argc) {
break;
int mask;
CPULogItem *item;
if (optind >= argc)
break;
r = argv[optind++];
mask = cpu_str_to_log_mask(r);
if (!mask) {
printf("Log items (comma separated):\n");
for(item = cpu_log_items; item->mask != 0; item++) {
printf("%-10s %s\n", item->name, item->help);
}
exit(1);
}
log_mask = argv[optind++];
} else if (!strcmp(r, "D")) {
if (optind >= argc) {
break;
}
log_file = argv[optind++];
cpu_set_log(mask);
} else if (!strcmp(r, "s")) {
r = argv[optind++];
stack_size = strtol(r, (char **)&r, 0);
@@ -809,27 +817,8 @@ int main(int argc, char **argv)
usage();
}
}
/* init debug */
cpu_set_log_filename(log_file);
if (log_mask) {
int mask;
CPULogItem *item;
mask = cpu_str_to_log_mask(log_mask);
if (!mask) {
printf("Log items (comma separated):\n");
for (item = cpu_log_items; item->mask != 0; item++) {
printf("%-10s %s\n", item->name, item->help);
}
exit(1);
}
cpu_set_log(mask);
}
if (optind >= argc) {
if (optind >= argc)
usage();
}
filename = argv[optind];
/* Zero out regs */

View File

@@ -21,6 +21,7 @@
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/ucontext.h>
@@ -31,6 +32,8 @@
#undef uc_link
#endif
#include <signal.h>
#include "qemu.h"
#include "qemu-common.h"

View File

@@ -977,7 +977,7 @@ long do_unix_syscall_indirect(void *cpu_env, int num)
#elif TARGET_PPC
{
int i;
/* XXX: not really needed those regs are volatile across calls */
/* XXX: not really needed those regs are volatile accross calls */
uint32_t **regs = ((CPUPPCState*)cpu_env)->gpr;
for(i = 11; i > 3; i--)
*regs[i] = *regs[i-1];

View File

@@ -1,9 +0,0 @@
# Default configuration for alpha-softmmu
include pci.mak
CONFIG_SERIAL=y
CONFIG_I8254=y
CONFIG_VGA_PCI=y
CONFIG_IDE_CORE=y
CONFIG_IDE_QDEV=y
CONFIG_VMWARE_VGA=y

View File

@@ -4,7 +4,6 @@ include pci.mak
CONFIG_VGA_PCI=y
CONFIG_VGA_ISA=y
CONFIG_VMWARE_VGA=y
CONFIG_VMMOUSE=y
CONFIG_SERIAL=y
CONFIG_PARALLEL=y
CONFIG_I8254=y
@@ -19,5 +18,3 @@ CONFIG_IDE_PIIX=y
CONFIG_NE2000_ISA=y
CONFIG_PIIX_PCI=y
CONFIG_SOUND=y
CONFIG_HPET=y
CONFIG_APPLESMC=y

View File

@@ -1,6 +0,0 @@
# Default configuration for lm32-softmmu
CONFIG_PTIMER=y
CONFIG_PFLASH_CFI01=y
CONFIG_PFLASH_CFI02=y
CONFIG_SD=y

View File

@@ -2,4 +2,3 @@
CONFIG_PTIMER=y
CONFIG_PFLASH_CFI01=y
CONFIG_SERIAL=y

View File

@@ -1 +0,0 @@
# Default configuration for microblazeel-linux-user

View File

@@ -1,5 +0,0 @@
# Default configuration for microblazeel-softmmu
CONFIG_PTIMER=y
CONFIG_PFLASH_CFI01=y
CONFIG_SERIAL=y

View File

@@ -3,7 +3,6 @@ CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO=y
CONFIG_USB_UHCI=y
CONFIG_USB_OHCI=y
CONFIG_USB_EHCI=y
CONFIG_NE2000_PCI=y
CONFIG_EEPRO100_PCI=y
CONFIG_PCNET_PCI=y

View File

@@ -1 +0,0 @@
# Default configuration for s390x-linux-user

View File

@@ -1 +0,0 @@
# Default configuration for unicore32-linux-user

View File

@@ -4,7 +4,6 @@ include pci.mak
CONFIG_VGA_PCI=y
CONFIG_VGA_ISA=y
CONFIG_VMWARE_VGA=y
CONFIG_VMMOUSE=y
CONFIG_SERIAL=y
CONFIG_PARALLEL=y
CONFIG_I8254=y
@@ -19,5 +18,3 @@ CONFIG_IDE_PIIX=y
CONFIG_NE2000_ISA=y
CONFIG_PIIX_PCI=y
CONFIG_SOUND=y
CONFIG_HPET=y
CONFIG_APPLESMC=y

View File

@@ -20,6 +20,7 @@
#include "config.h"
#include "qemu-common.h"
#include "sysemu.h"
#include "device_tree.h"
#include "hw/loader.h"
@@ -73,7 +74,7 @@ fail:
}
int qemu_devtree_setprop(void *fdt, const char *node_path,
const char *property, void *val_array, int size)
const char *property, uint32_t *val_array, int size)
{
int offset;

View File

@@ -17,7 +17,7 @@
void *load_device_tree(const char *filename_path, int *sizep);
int qemu_devtree_setprop(void *fdt, const char *node_path,
const char *property, void *val_array, int size);
const char *property, uint32_t *val_array, int size);
int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
const char *property, uint32_t val);
int qemu_devtree_setprop_string(void *fdt, const char *node_path,

View File

@@ -184,9 +184,6 @@ enum bfd_architecture
#define bfd_mach_sh5 0x50
bfd_arch_alpha, /* Dec Alpha */
#define bfd_mach_alpha 1
#define bfd_mach_alpha_ev4 0x10
#define bfd_mach_alpha_ev5 0x20
#define bfd_mach_alpha_ev6 0x30
bfd_arch_arm, /* Advanced Risc Machines ARM */
#define bfd_mach_arm_unknown 0
#define bfd_mach_arm_2 1

11
disas.c
View File

@@ -5,6 +5,7 @@
#include <errno.h>
#include "cpu.h"
#include "exec-all.h"
#include "disas.h"
/* Filled in by elfload.c. Simplistic, but will do for now. */
@@ -204,7 +205,7 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
disasm_info.mach = bfd_mach_sh4;
print_insn = print_insn_sh;
#elif defined(TARGET_ALPHA)
disasm_info.mach = bfd_mach_alpha_ev6;
disasm_info.mach = bfd_mach_alpha;
print_insn = print_insn_alpha;
#elif defined(TARGET_CRIS)
if (flags != 32) {
@@ -214,9 +215,6 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
disasm_info.mach = bfd_mach_cris_v32;
print_insn = print_insn_crisv32;
}
#elif defined(TARGET_S390X)
disasm_info.mach = bfd_mach_s390_64;
print_insn = print_insn_s390;
#elif defined(TARGET_MICROBLAZE)
disasm_info.mach = bfd_arch_microblaze;
print_insn = print_insn_microblaze;
@@ -344,7 +342,7 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
struct disassemble_info *info)
{
if (monitor_disas_is_physical) {
cpu_physical_memory_read(memaddr, myaddr, length);
cpu_physical_memory_rw(memaddr, myaddr, length, 0);
} else {
cpu_memory_rw_debug(monitor_disas_env, memaddr,myaddr, length, 0);
}
@@ -416,9 +414,6 @@ void monitor_disas(Monitor *mon, CPUState *env,
#elif defined(TARGET_SH4)
disasm_info.mach = bfd_mach_sh4;
print_insn = print_insn_sh;
#elif defined(TARGET_S390X)
disasm_info.mach = bfd_mach_s390_64;
print_insn = print_insn_s390;
#else
monitor_printf(mon, "0x" TARGET_FMT_lx
": Asm output not supported on this arch\n", pc);

View File

@@ -47,7 +47,6 @@ typedef struct {
target_phys_addr_t sg_cur_byte;
QEMUIOVector iov;
QEMUBH *bh;
DMAIOFunc *io_func;
} DMAAIOCB;
static void dma_bdrv_cb(void *opaque, int ret);
@@ -117,8 +116,13 @@ static void dma_bdrv_cb(void *opaque, int ret)
return;
}
dbs->acb = dbs->io_func(dbs->bs, dbs->sector_num, &dbs->iov,
dbs->iov.size / 512, dma_bdrv_cb, dbs);
if (dbs->is_write) {
dbs->acb = bdrv_aio_writev(dbs->bs, dbs->sector_num, &dbs->iov,
dbs->iov.size / 512, dma_bdrv_cb, dbs);
} else {
dbs->acb = bdrv_aio_readv(dbs->bs, dbs->sector_num, &dbs->iov,
dbs->iov.size / 512, dma_bdrv_cb, dbs);
}
if (!dbs->acb) {
dma_bdrv_unmap(dbs);
qemu_iovec_destroy(&dbs->iov);
@@ -140,12 +144,12 @@ static AIOPool dma_aio_pool = {
.cancel = dma_aio_cancel,
};
BlockDriverAIOCB *dma_bdrv_io(
static BlockDriverAIOCB *dma_bdrv_io(
BlockDriverState *bs, QEMUSGList *sg, uint64_t sector_num,
DMAIOFunc *io_func, BlockDriverCompletionFunc *cb,
void *opaque, int is_write)
BlockDriverCompletionFunc *cb, void *opaque,
int is_write)
{
DMAAIOCB *dbs = qemu_aio_get(&dma_aio_pool, bs, cb, opaque);
DMAAIOCB *dbs = qemu_aio_get(&dma_aio_pool, bs, cb, opaque);
dbs->acb = NULL;
dbs->bs = bs;
@@ -154,7 +158,6 @@ BlockDriverAIOCB *dma_bdrv_io(
dbs->sg_cur_index = 0;
dbs->sg_cur_byte = 0;
dbs->is_write = is_write;
dbs->io_func = io_func;
dbs->bh = NULL;
qemu_iovec_init(&dbs->iov, sg->nsg);
dma_bdrv_cb(dbs, 0);
@@ -170,12 +173,12 @@ BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs,
QEMUSGList *sg, uint64_t sector,
void (*cb)(void *opaque, int ret), void *opaque)
{
return dma_bdrv_io(bs, sg, sector, bdrv_aio_readv, cb, opaque, 0);
return dma_bdrv_io(bs, sg, sector, cb, opaque, 0);
}
BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
QEMUSGList *sg, uint64_t sector,
void (*cb)(void *opaque, int ret), void *opaque)
{
return dma_bdrv_io(bs, sg, sector, bdrv_aio_writev, cb, opaque, 1);
return dma_bdrv_io(bs, sg, sector, cb, opaque, 1);
}

8
dma.h
View File

@@ -32,14 +32,6 @@ void qemu_sglist_add(QEMUSGList *qsg, target_phys_addr_t base,
target_phys_addr_t len);
void qemu_sglist_destroy(QEMUSGList *qsg);
typedef BlockDriverAIOCB *DMAIOFunc(BlockDriverState *bs, int64_t sector_num,
QEMUIOVector *iov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque);
BlockDriverAIOCB *dma_bdrv_io(BlockDriverState *bs,
QEMUSGList *sg, uint64_t sector_num,
DMAIOFunc *io_func, BlockDriverCompletionFunc *cb,
void *opaque, int is_write);
BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs,
QEMUSGList *sg, uint64_t sector,
BlockDriverCompletionFunc *cb, void *opaque);

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