Compare commits

...

51 Commits

Author SHA1 Message Date
aliguori
5558e88318 Add a tag for the 0.10.2 release
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/tags/release_0_10_2@7013 c046a42c-6fe2-441c-8c8c-71466251a162
2009-04-07 02:03:31 +00:00
aliguori
06b393452f Update version for release
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@7012 c046a42c-6fe2-441c-8c8c-71466251a162
2009-04-07 01:57:17 +00:00
aliguori
b7d11af2e0 Fix find_device_type() to correctly identify floppy disk devices; (Luca Tettamanti)
they are reported as DRIVE_REMOVABLE by win32.

Signed-off-by: Luca Tettamanti <kronos.it@gmail.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@7011 c046a42c-6fe2-441c-8c8c-71466251a162
2009-04-07 01:46:18 +00:00
aliguori
8d47bb6162 Fix savevm after BDRV_FILE size enforcement
We now enforce that you cannot write beyond the end of a non-growable file.
 qcow2 files are not growable but we rely on them being growable to do
 savevm/loadvm.  Temporarily allow them to be growable by introducing a new
 API specifically for savevm read/write operations.
 
 Reported-by: malc
 Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
 


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@7005 c046a42c-6fe2-441c-8c8c-71466251a162
2009-04-05 21:07:26 +00:00
aliguori
80acab6c50 stop dirty tracking just at the end of migration (Glauber Costa)
If there is still work to do, it is not safe to assume we
can end the dirty tracking. Specifically, kvm can update the dirty
tracking log inside ram_save_block(), leaving pages still out of sync
if we go with the current code.

Based on a patch by Yaniv Kamay

Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@7002 c046a42c-6fe2-441c-8c8c-71466251a162
2009-04-05 19:33:41 +00:00
aliguori
da0ac2bc13 create qemu_file_set_error (Glauber Costa)
This is mainly for consistency, since we don't want
anything outside of savevm setting it explicitly. There
are current no users of that in qemu tree, but there
are potential candidates on kvm-userspace. And avi
is a nice guy, let's be nice with him.

Based on a patch by Yaniv Kamay

Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@7001 c046a42c-6fe2-441c-8c8c-71466251a162
2009-04-05 19:33:37 +00:00
aliguori
d3c2632047 propagate error on failed completion (Glauber Costa)
migrate_fd_put_ready() calls qemu_savevm_state_complete(),
but the later can fail.

If it happens, re-start the vm and propagate the error up

Based on a patch by Yaniv Kamay

Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@7000 c046a42c-6fe2-441c-8c8c-71466251a162
2009-04-05 19:33:33 +00:00
aliguori
7cc73776e7 qcow2: fix image creation for large, > ~2TB, images (Chris Wright)
When creating large disk images w/ qcow2 format, qcow2_create is hard
coded to creating a single refcount block.  This is insufficient for
large images, and will cause qemu-img to segfault as it walks off the
end of the refcount block.  Keep track of the space needed during image
create and create proper number of refcount blocks accordingly.

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

Signed-off-by: Chris Wright <chrisw@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@6988 c046a42c-6fe2-441c-8c8c-71466251a162
2009-04-05 18:16:10 +00:00
aliguori
937e9a1c83 pci_add storage: fix error handling for 'if' parameter (Eduardo Habkost)
This fixes:

 - The error message to show the actual if= argument value. It was showing
   the filename instead, because 'buf' is reaused on the filename parsing.
 - A bug that makes a block device to be created even when an unsupported if= arg
   is passed to pci_add.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@6987 c046a42c-6fe2-441c-8c8c-71466251a162
2009-04-05 18:16:04 +00:00
aliguori
4498819404 Fix (at least one cause of) qcow2 corruption. (Nolan Leake)
qcow2's get_cluster_offset() scans forward in the l2 table to find other
clusters that have the same allocation status as the first cluster.
This is used by (among others) qcow_is_allocated().

Unfortunately, it was not checking to be sure that it didn't fall off
the end of the l2 table.  This patch adds that check.

The symptom that motivated me to look into this was that
bdrv_is_allocated() was returning false when there was in fact data
there.  This is one of many ways this bug could lead to data corruption.

I checked the other place that scans for consecutive unallocated blocks
(alloc_cluster_offset()) and it appears to be OK:
    nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);
appears to prevent the same problem from occurring.

Signed-off-by: Nolan Leake <nolan <at> sigbus.net>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@6986 c046a42c-6fe2-441c-8c8c-71466251a162
2009-04-05 18:15:59 +00:00
aliguori
c61ad61830 Fix oops on 2.6.25 guest (Rusty Russell)
I believe this is behind the following:
https://bugs.edge.launchpad.net/ubuntu/jaunty/+source/linux/+bug/331128

virtio_pci in 2.6.25 didn't do feature negotiation correctly: it acked every
bit.  Fortunately, we can detect this.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@6985 c046a42c-6fe2-441c-8c8c-71466251a162
2009-04-05 18:15:54 +00:00
aurel32
65297bc408 SH4: Add support for kernel cmdline
Backport of revisions 6792, 6916, 6919 from trunk.



git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@6960 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-31 05:55:16 +00:00
aliguori
02d400ead7 char: Fix closing of various char devices (Jan Kiszka)
This patch fixes several issues around closing char devices. Affected
were pty (timer was left behind, even running), udp (no close handling
at all) and tcp (missing async IO handler cleanup). The bugs either
caused segfaults or stalled the qemu process. So far, hot-unplugging USB
serial adapters suffered from this.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@6912 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-28 18:01:29 +00:00
aliguori
20a9c6ac7f host_device_remove: remove incorrect check for device name (Eduardo Habkost)
There is no need to check for valid prefixes on the the device name
when removing it. If the device name is found on the vlan client list,
it can be removed, regardless of the prefix used on its name.

To reproduce the bug, just run this on the monitor:

 (qemu) host_net_add user name=foobar
 (qemu) host_net_remove 0 foobar
 invalid host network device foobar
 (qemu)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@6890 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-28 15:51:46 +00:00
aliguori
bd0b264c21 Enable -k option on Win32 (Herve Poussineau)
Attached patch enables -k option on Win32. There is no reason to disable it.

Signed-off-by: Herve Poussineau <hpoussin@reactos.org>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@6889 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-28 15:46:15 +00:00
aliguori
0f31aac44f configure sensitive to user locale (Andreas Faerber)
On German Fedora 9, no KVM errors are displayed.
This is because configure greps for "error:", which is locale-sensitive.

Use LANG=C for configure to find and display errors as expected.

Signed-off-by: Andreas Faerber <andreas.faerber@web.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@6883 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-22 03:01:39 +00:00
aliguori
30b15843b2 Fix VGA issue introduced by r6349 (malc)
Thanks to Robert Riebisch for bisection

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@6882 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-22 02:59:21 +00:00
aliguori
04ffdd7f94 Update version for release
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@6880 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-21 23:02:41 +00:00
aliguori
7648bb760d Rename stable branch
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@6879 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-21 23:00:32 +00:00
aliguori
ebb7184720 Restore old stable branch
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6878 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-21 22:59:47 +00:00
aliguori
3f546bd0b1 Add release_0_10_1 tag
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10@6876 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-21 22:34:21 +00:00
aliguori
00614a4cb4 Update Changelog
git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6869 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-20 16:22:31 +00:00
aliguori
7c14db42cb virtio: Allow guest to defer VIRTIO_F_NOTIFY_ON_EMPTY (Alex Williamson)
There may be cases where the guest does not want the avail queue
interrupt, even when it's empty.  For the virtio-net case, the
guest may use a different buffering scheme or decide polling for
used buffers is more efficient.  This can be accomplished by simply
checking for whether the guest has acknowledged the existing notify
on empty flag.

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6868 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-20 16:18:45 +00:00
aliguori
e58843d0f1 e1000: Fix RX descriptor low threshold interrupt logic (Alex Williamson)
The RXDMT0 interrupt is supposed to fire when the number of free
RX descriptors drops to some fraction of the total descriptors.
However in practice, it seems like we're adding this interrupt
cause on every RX.  Fix the logic to treat (tail - head) as the
number of free entries rather than the number of used entries.

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6867 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-20 16:18:39 +00:00
aliguori
0e39d3f89b x86: Add NULL check to lsl (Jan Kiszka)
According to the Intel specs, lsl performs a check against NULL for the
provided selector, just like lar does. helper_lar() includes the
corresponding code, helper_lsl() was lacking it so far.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6866 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-20 16:18:35 +00:00
aliguori
5389a9df53 temporarily disable logging around pci config writes (Avi Kivity)
A pci config write may remap the vga linear frame buffer, confusing the
memory slot dirty logging logic.

Fixed Windows with -vga std.

Signed-off-by: Avi Kivity <avi@redhat.com>
Sigend-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6854 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-13 18:11:21 +00:00
aliguori
21fd832512 stop dirty logging while updating cirrus bank memory (Glauber Costa)
Otherwise, slot tracking gets confused.

This fixes a screen corruption bug with Ubuntu guest installation.

Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6853 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-13 18:11:17 +00:00
aliguori
15d4afd55b Update changelog
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6848 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-13 16:22:40 +00:00
aliguori
3df962a30d qemu:virtio-net: Check return size on the correct sg list (Alex Williamson)
When checking that the size of the control virtqueue return field
is sufficient, use the correct sg list.

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6847 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-13 16:19:04 +00:00
aliguori
4827c90cef make qemu_announce_self handle non contiguous net tables (Marcelo Tosatti)
With hotplug nd_table might contain holes.

Noticed by Eduardo Habkost.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6846 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-13 16:18:57 +00:00
aliguori
0f56231dce Revert r6404
This series is broken by design as it requires expensive IO operations at
open time causing very long delays when starting a virtual machine for the
first time.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6821 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-11 20:16:16 +00:00
aliguori
523faf1b92 Revert r6405
This series is broken by design as it requires expensive IO operations at
open time causing very long delays when starting a virtual machine for the
first time.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6820 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-11 20:16:12 +00:00
aliguori
414c078104 Revert r6406
This series is broken by design as it requires expensive IO operations at
open time causing very long delays when starting a virtual machine for the
first time.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6819 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-11 20:16:05 +00:00
aliguori
9cecf0f570 Revert r6407
This series is broken by design as it requires expensive IO operations at
open time causing very long delays when starting a virtual machine for the
first time.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6818 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-11 20:16:01 +00:00
aliguori
4ca9f3dd71 Revert r6408
This series is broken by design as it requires expensive IO operations at
open time causing very long delays when starting a virtual machine for the
first time.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6817 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-11 20:15:55 +00:00
aurel32
f902c4192e qemu-img: fix help message
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6788 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-08 19:52:43 +00:00
aliguori
b96a313d3d Remove unnecessary prefix on SDL_syswm.h. This fixes the build for certain
installs of SDL.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6781 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-08 15:04:13 +00:00
aurel32
d9aa1fce5a Clear CPU_INTERRUPT_EXIT on VM load
CPU_INTERRUPT_EXIT is not set anymore in env->interrupt_request since
revision 6729. Make sure the bit is cleared on VM load.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6760 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-07 21:08:39 +00:00
aurel32
8a11f5ff08 Fix race condition on access to env->interrupt_request
env->interrupt_request is accessed as the bit level from both main code
and signal handler, making a race condition possible even on CISC CPU.
This causes freeze of QEMU under high load when running the dyntick
clock.

The patch below move the bit corresponding to CPU_INTERRUPT_EXIT in a
separate variable, declared as volatile sig_atomic_t, so it should be
work even on RISC CPU.

We may want to move the cpu_interrupt(env, CPU_INTERRUPT_EXIT) case in
its own function and get rid of CPU_INTERRUPT_EXIT. That can be done
later, I wanted to keep the patch short for easier review.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6729 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-06 21:49:37 +00:00
aliguori
b786b7ccbd monitor: Rework early disk password inquiry (Jan Kiszka)
Reading the passwords for encrypted hard disks during early startup is
broken (I guess for quiet a while now):
 - No monitor terminal is ready for input at this point
 - Forcing all mux'ed terminals into monitor mode can confuse other
   users of that channels

To overcome these issues and to lay the ground for a clean decoupling of
monitor terminals, this patch changes the initial password inquiry as
follows:
 - Prevent autostart if there is some encrypted disk
 - Once the user tries to resume the VM, prompt for all missing
   passwords
 - Only resume if all passwords were accepted

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6699 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-05 19:42:40 +00:00
aliguori
d3be2b2f71 monitor: Report encrypted disks in snapshot mode (Jan Kiszka)
If the backing file is encrypted, 'info block' currently does not report
the disk as encrypted. Fix this by using the standard API to check disk
encryption mode. Moreover, switch to a canonical output format.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6698 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-05 19:42:36 +00:00
aliguori
e36fb2a3a2 monitor: Use reasonable default virtual console size (Jan Kiszka)
If a target uses a tiny display (like the MusicPal), the default monitor
is currently set to the same size. Fix this by applying the same
defaults like already used serial and virtio consoles.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6697 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-05 19:42:30 +00:00
aliguori
4978045781 block: Introduce bdrv_get_encrypted_filename (Jan Kiszka)
Introduce bdrv_get_encrypted_filename service to allow more informative
password prompting.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6696 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-05 19:42:19 +00:00
aliguori
cb5745c529 block: Improve bdrv_iterate (Jan Kiszka)
Make bdrv_iterate more useful by passing the BlockDriverState to the
iterator instead of the device name.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6695 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-05 19:42:15 +00:00
aliguori
295b492cfa block: Polish error handling of brdv_open2 (Jan Kiszka)
Make sure that we always delete temporary disk images on error, remove
obsolete malloc error checks and return proper error codes.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6694 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-05 19:42:11 +00:00
aliguori
af8222c0f8 char-mux: Use separate input buffers (Jan Kiszka)
Currently, the intermediate input buffer of mux'ed character devices
records data across all sub-devices. This has the side effect that we
easily leak data recorded over one sub-devices to another once we switch
the focus. Avoid data loss and confusion by defining exclusive buffers.

Note: In contrast to the original author's claim, the buffering concept
still breaks down when the fifo of the currently active sub-device is
full. As we cannot accept futher data from this point on without risking
to loose it, we will also miss escape sequences, just like without all
that buffering. In short: There is no reliable escape sequence handling
without infinite buffers or the risk of loosing some data.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6693 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-05 19:42:07 +00:00
aliguori
249139f4e6 char: Fix initial reset (Jan Kiszka)
Recent changes to the graphical console initialization broke the initial
CHR_EVENT_RESET distribution. The reset BHs generated on char device
initialization are now already consumed during machine init (ide init
... -> qemu_aio_wait -> qemu_bh_poll). Therefore, this patch moves the
initial qemu_chr_reset calls into a separate funtion which is called
after machine init.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6692 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-05 19:42:04 +00:00
aliguori
8ae0978ed5 Fix cpuid KVM crash on i386 (Lubomir Rintel)
Cpuid should return into vec, not overwrite past address in count.
Changeset 6565 broke this.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6691 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-05 19:01:53 +00:00
aliguori
c0024a8257 lsi: add ISTAT1 register read (Ryan Harper)
SLES10 SP2 installer complains when probing a scsi disk and exits qemu
when failing to read one of the registers.

lsi_scsi: error: readb 0x15


-- 
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
ryanh@us.ibm.com



diffstat output:
 lsi53c895a.c |    2 ++
 1 files changed, 2 insertions(+)

Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
---
Subject: [PATCH] lsi: add ISTAT1 register read
From: Ryan Harper <ryanh@us.ibm.com>
Cc: kvm@vger.kernel.org

SLES10 SP2 installer complains when probing a scsi disk and exits qemu when
failing to read one of the registers.

lsi_scsi: error: readb 0x15

Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6690 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-05 19:01:46 +00:00
aliguori
e9af78a859 Add stable branch
git-svn-id: svn://svn.savannah.nongnu.org/qemu/branches/stable_0_10_0@6687 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-05 18:52:51 +00:00
aliguori
25c4fde177 Add property to tag
git-svn-id: svn://svn.savannah.nongnu.org/qemu/tags/release_0_10_0@6686 c046a42c-6fe2-441c-8c8c-71466251a162
2009-03-05 18:51:35 +00:00
37 changed files with 443 additions and 251 deletions

View File

@@ -1,3 +1,46 @@
version 0.10.2:
- fix savevm/loadvm (Anthony Liguori)
- live migration: fix dirty tracking windows (Glauber Costa)
- live migration: improve error propogation (Glauber Costa)
- qcow2: fix image creation for > ~2TB images (Chris Wright)
- hotplug: fix error handling for if= parameter (Eduardo Habkost)
- qcow2: fix data corruption (Nolan Leake)
- virtio: fix guest oops with 2.6.25 kernels (Rusty Russell)
- SH4: add support for -kernel (Takashi Yoshii, Aurelien Jarno)
- hotplug: fix closing of char devices (Jan Kiszka)
- hotplug: remove incorrect check for device name (Eduardo Habkost)
- enable -k on win32 (Herve Poussineau)
- configure: use LANG=C for grep (Andreas Faerber)
- fix VGA regression (malc)
version 0.10.1:
- virtio-net: allow masking of notifications on empty queue (Alex Williamson)
- e1000: fix rx descriptor low threshold logic (Alex Willaimson)
- x86 tcg: add NULL checks to lsl instruction (Jan Kiszka)
- kvm vga: fix screen corruption with -std-vga and Windows (Avi Kivity)
- kvm vga: fix screen corruption with Ubuntu installations (Glauber Costa)
- virtio-net: check right return size on sg list (Alex Williamson)
- Make qemu_announce_self handle holes (live migration after hotplug)
(Marcelo Tosatti)
- Revert r6804-r6808 (qcow2 allocation info). This series of changes added
a high cost to startup for large qcow2 images (Anthony Liguori)
- qemu-img: fix help message (Aurelien Jarno)
- Fix build for non-default installs of SDL (Anthony Liguori)
- Fix race condition in env->interrupt_request. When using TCG and a dynticks
host timer, this condition could cause TCG to get stuck in an infinite
loop (Aurelien Jarno)
- Fix reading encrypted hard disk passwords during early startup (Jan Kiszka)
- Fix encrypted disk reporting in 'info block' (Jan Kiszka)
- Fix console size with tiny displays (MusicPal) (Jan Kiszka)
- Improve error handling in bdrv_open2 (Jan Kiszka)
- Avoid leaking data in mux'ed character devices (Jan Kiszka)
- Fix initial character device reset (no banner in monitor) (Jan Kiszka)
- Fix cpuid KVM crash on i386 host (Lubomir Rintel)
- Fix SLES10sp2 installation by adding ISTAT1 register to LSI SCSI emulation
(Ryan Harper)
version 0.10.0:
- TCG support (No longer requires GCC 3.x)

View File

@@ -1 +1 @@
0.10.0
0.10.2

View File

@@ -143,10 +143,6 @@ typedef struct BDRVQcowState {
uint32_t crypt_method_header;
AES_KEY aes_encrypt_key;
AES_KEY aes_decrypt_key;
int64_t highest_alloc; /* highest cluester allocated (in clusters) */
int64_t nc_free; /* num of free clusters below highest_alloc */
uint64_t snapshots_offset;
int snapshots_size;
int nb_snapshots;
@@ -174,8 +170,6 @@ static void free_clusters(BlockDriverState *bs,
#ifdef DEBUG_ALLOC
static void check_refcounts(BlockDriverState *bs);
#endif
static void scan_refcount(BlockDriverState *bs, int64_t *high, int64_t *free);
static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
{
@@ -276,8 +270,6 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
if (refcount_init(bs) < 0)
goto fail;
scan_refcount(bs, &s->highest_alloc, &s->nc_free);
/* read the backing file name */
if (header.backing_file_offset != 0) {
len = header.backing_file_size;
@@ -678,6 +670,10 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
nb_available = (nb_available >> 9) + index_in_cluster;
if (nb_needed > nb_available) {
nb_needed = nb_available;
}
cluster_offset = 0;
/* seek the the l2 offset in the l1 table */
@@ -1466,6 +1462,7 @@ static int qcow_create(const char *filename, int64_t total_size,
const char *backing_file, int flags)
{
int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits;
int ref_clusters;
QCowHeader header;
uint64_t tmp, offset;
QCowCreateState s1, *s = &s1;
@@ -1506,22 +1503,28 @@ static int qcow_create(const char *filename, int64_t total_size,
offset += align_offset(l1_size * sizeof(uint64_t), s->cluster_size);
s->refcount_table = qemu_mallocz(s->cluster_size);
s->refcount_block = qemu_mallocz(s->cluster_size);
s->refcount_table_offset = offset;
header.refcount_table_offset = cpu_to_be64(offset);
header.refcount_table_clusters = cpu_to_be32(1);
offset += s->cluster_size;
s->refcount_table[0] = cpu_to_be64(offset);
s->refcount_block_offset = offset;
offset += s->cluster_size;
/* count how many refcount blocks needed */
tmp = offset >> s->cluster_bits;
ref_clusters = (tmp >> (s->cluster_bits - REFCOUNT_SHIFT)) + 1;
for (i=0; i < ref_clusters; i++) {
s->refcount_table[i] = cpu_to_be64(offset);
offset += s->cluster_size;
}
s->refcount_block = qemu_mallocz(ref_clusters * s->cluster_size);
/* update refcounts */
create_refcount_update(s, 0, header_size);
create_refcount_update(s, s->l1_table_offset, l1_size * sizeof(uint64_t));
create_refcount_update(s, s->refcount_table_offset, s->cluster_size);
create_refcount_update(s, s->refcount_block_offset, s->cluster_size);
create_refcount_update(s, s->refcount_block_offset, ref_clusters * s->cluster_size);
/* write all the data */
write(fd, &header, sizeof(header));
@@ -1537,7 +1540,7 @@ static int qcow_create(const char *filename, int64_t total_size,
write(fd, s->refcount_table, s->cluster_size);
lseek(fd, s->refcount_block_offset, SEEK_SET);
write(fd, s->refcount_block, s->cluster_size);
write(fd, s->refcount_block, ref_clusters * s->cluster_size);
qemu_free(s->refcount_table);
qemu_free(s->refcount_block);
@@ -1646,8 +1649,6 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
bdi->cluster_size = s->cluster_size;
bdi->vm_state_offset = (int64_t)s->l1_vm_state_index <<
(s->cluster_bits + s->l2_bits);
bdi->highest_alloc = s->highest_alloc << s->cluster_bits;
bdi->num_free_bytes = s->nc_free << s->cluster_bits;
return 0;
}
@@ -2166,39 +2167,6 @@ static int load_refcount_block(BlockDriverState *bs,
return 0;
}
static void scan_refcount(BlockDriverState *bs, int64_t *high, int64_t *free)
{
BDRVQcowState *s = bs->opaque;
int64_t refcnt_index, cluster_index, cluster_end, h = 0, f = 0;
int64_t tail = 0; /* do not count last consecutive free entries */
for (refcnt_index=0; refcnt_index < s->refcount_table_size; refcnt_index++){
if (s->refcount_table[refcnt_index] == 0) {
f += 1 << (s->cluster_bits - REFCOUNT_SHIFT);
tail += 1 << (s->cluster_bits - REFCOUNT_SHIFT);
continue;
}
cluster_index = refcnt_index << (s->cluster_bits - REFCOUNT_SHIFT);
cluster_end = (refcnt_index + 1) << (s->cluster_bits - REFCOUNT_SHIFT);
for ( ; cluster_index < cluster_end; cluster_index++) {
if (get_refcount(bs, cluster_index) == 0) {
f++;
tail++;
}
else {
h = cluster_index;
tail = 0;
}
}
}
f -= tail;
if (free)
*free = f;
if (high)
*high = (h+1);
}
static int get_refcount(BlockDriverState *bs, int64_t cluster_index)
{
BDRVQcowState *s = bs->opaque;
@@ -2239,12 +2207,6 @@ retry:
size,
(s->free_cluster_index - nb_clusters) << s->cluster_bits);
#endif
if (s->highest_alloc < s->free_cluster_index) {
s->nc_free += (s->free_cluster_index - s->highest_alloc);
s->highest_alloc = s->free_cluster_index;
}
return (s->free_cluster_index - nb_clusters) << s->cluster_bits;
}
@@ -2418,12 +2380,6 @@ static int update_cluster_refcount(BlockDriverState *bs,
block_index = cluster_index &
((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
refcount = be16_to_cpu(s->refcount_block_cache[block_index]);
if (refcount == 1 && addend == -1)
s->nc_free += 1;
else if (refcount == 0 && addend == 1)
s->nc_free -= 1;
refcount += addend;
if (refcount < 0 || refcount > 0xffff)
return -EINVAL;
@@ -2645,6 +2601,31 @@ static void dump_refcounts(BlockDriverState *bs)
#endif
#endif
static int qcow_put_buffer(BlockDriverState *bs, const uint8_t *buf,
int64_t pos, int size)
{
int growable = bs->growable;
bs->growable = 1;
bdrv_pwrite(bs, pos, buf, size);
bs->growable = growable;
return size;
}
static int qcow_get_buffer(BlockDriverState *bs, uint8_t *buf,
int64_t pos, int size)
{
int growable = bs->growable;
int ret;
bs->growable = 1;
ret = bdrv_pread(bs, pos, buf, size);
bs->growable = growable;
return ret;
}
BlockDriver bdrv_qcow2 = {
"qcow2",
sizeof(BDRVQcowState),
@@ -2670,4 +2651,7 @@ BlockDriver bdrv_qcow2 = {
.bdrv_snapshot_delete = qcow_snapshot_delete,
.bdrv_snapshot_list = qcow_snapshot_list,
.bdrv_get_info = qcow_get_info,
.bdrv_put_buffer = qcow_put_buffer,
.bdrv_get_buffer = qcow_get_buffer,
};

View File

@@ -399,10 +399,15 @@ static int find_device_type(BlockDriverState *bs, const char *filename)
return FTYPE_HARDDISK;
snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", p[0]);
type = GetDriveType(s->drive_path);
if (type == DRIVE_CDROM)
switch (type) {
case DRIVE_REMOVABLE:
case DRIVE_FIXED:
return FTYPE_HARDDISK;
case DRIVE_CDROM:
return FTYPE_CD;
else
default:
return FTYPE_FILE;
}
} else {
return FTYPE_FILE;
}

105
block.c
View File

@@ -311,8 +311,6 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
int ret;
bs = bdrv_new("");
if (!bs)
return -ENOMEM;
ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
if (ret < 0) {
bdrv_delete(bs);
@@ -338,6 +336,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
bs->read_only = 0;
bs->is_temporary = 0;
bs->encrypted = 0;
bs->valid_key = 0;
if (flags & BDRV_O_SNAPSHOT) {
BlockDriverState *bs1;
@@ -349,12 +348,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
/* if there is a backing file, use it */
bs1 = bdrv_new("");
if (!bs1) {
return -ENOMEM;
}
if (bdrv_open(bs1, filename, 0) < 0) {
ret = bdrv_open(bs1, filename, 0);
if (ret < 0) {
bdrv_delete(bs1);
return -1;
return ret;
}
total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
@@ -372,9 +369,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
else
realpath(filename, backing_filename);
if (bdrv_create(&bdrv_qcow2, tmp_filename,
total_size, backing_filename, 0) < 0) {
return -1;
ret = bdrv_create(&bdrv_qcow2, tmp_filename,
total_size, backing_filename, 0);
if (ret < 0) {
return ret;
}
filename = tmp_filename;
bs->is_temporary = 1;
@@ -383,14 +381,12 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
pstrcpy(bs->filename, sizeof(bs->filename), filename);
if (flags & BDRV_O_FILE) {
drv = find_protocol(filename);
if (!drv)
return -ENOENT;
} else {
if (!drv) {
drv = find_image_format(filename);
if (!drv)
return -1;
}
} else if (!drv) {
drv = find_image_format(filename);
}
if (!drv) {
ret = -ENOENT;
goto unlink_and_fail;
}
bs->drv = drv;
bs->opaque = qemu_mallocz(drv->instance_size);
@@ -409,6 +405,9 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
qemu_free(bs->opaque);
bs->opaque = NULL;
bs->drv = NULL;
unlink_and_fail:
if (bs->is_temporary)
unlink(filename);
return ret;
}
if (drv->bdrv_getlength) {
@@ -422,15 +421,13 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
if (bs->backing_file[0] != '\0') {
/* if there is a backing file, use it */
bs->backing_hd = bdrv_new("");
if (!bs->backing_hd) {
fail:
bdrv_close(bs);
return -ENOMEM;
}
path_combine(backing_filename, sizeof(backing_filename),
filename, bs->backing_file);
if (bdrv_open(bs->backing_hd, backing_filename, open_flags) < 0)
goto fail;
ret = bdrv_open(bs->backing_hd, backing_filename, open_flags);
if (ret < 0) {
bdrv_close(bs);
return ret;
}
}
/* call the change callback */
@@ -970,6 +967,15 @@ int bdrv_is_encrypted(BlockDriverState *bs)
return bs->encrypted;
}
int bdrv_key_required(BlockDriverState *bs)
{
BlockDriverState *backing_hd = bs->backing_hd;
if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
return 1;
return (bs->encrypted && !bs->valid_key);
}
int bdrv_set_key(BlockDriverState *bs, const char *key)
{
int ret;
@@ -982,7 +988,9 @@ int bdrv_set_key(BlockDriverState *bs, const char *key)
}
if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
return -1;
return bs->drv->bdrv_set_key(bs, key);
ret = bs->drv->bdrv_set_key(bs, key);
bs->valid_key = (ret == 0);
return ret;
}
void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
@@ -1015,12 +1023,12 @@ BlockDriverState *bdrv_find(const char *name)
return NULL;
}
void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
{
BlockDriverState *bs;
for (bs = bdrv_first; bs != NULL; bs = bs->next) {
it(opaque, bs->device_name);
it(opaque, bs);
}
}
@@ -1105,8 +1113,7 @@ void bdrv_info(void)
}
term_printf(" ro=%d", bs->read_only);
term_printf(" drv=%s", bs->drv->format_name);
if (bs->encrypted)
term_printf(" encrypted");
term_printf(" encrypted=%d", bdrv_is_encrypted(bs));
} else {
term_printf(" [not inserted]");
}
@@ -1118,7 +1125,6 @@ void bdrv_info(void)
void bdrv_info_stats (void)
{
BlockDriverState *bs;
BlockDriverInfo bdi;
for (bs = bdrv_first; bs != NULL; bs = bs->next) {
term_printf ("%s:"
@@ -1126,18 +1132,23 @@ void bdrv_info_stats (void)
" wr_bytes=%" PRIu64
" rd_operations=%" PRIu64
" wr_operations=%" PRIu64
,
"\n",
bs->device_name,
bs->rd_bytes, bs->wr_bytes,
bs->rd_ops, bs->wr_ops);
if (bdrv_get_info(bs, &bdi) == 0)
term_printf(" high=%" PRId64
" bytes_free=%" PRId64,
bdi.highest_alloc, bdi.num_free_bytes);
term_printf("\n");
}
}
const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
{
if (bs->backing_hd && bs->backing_hd->encrypted)
return bs->backing_file;
else if (bs->encrypted)
return bs->filename;
else
return NULL;
}
void bdrv_get_backing_filename(BlockDriverState *bs,
char *filename, int filename_size)
{
@@ -1170,6 +1181,26 @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
return drv->bdrv_get_info(bs, bdi);
}
int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf, int64_t pos, int size)
{
BlockDriver *drv = bs->drv;
if (!drv)
return -ENOMEDIUM;
if (!drv->bdrv_put_buffer)
return -ENOTSUP;
return drv->bdrv_put_buffer(bs, buf, pos, size);
}
int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size)
{
BlockDriver *drv = bs->drv;
if (!drv)
return -ENOMEDIUM;
if (!drv->bdrv_get_buffer)
return -ENOTSUP;
return drv->bdrv_get_buffer(bs, buf, pos, size);
}
/**************************************************************/
/* handling of snapshots */

15
block.h
View File

@@ -26,8 +26,6 @@ typedef struct BlockDriverInfo {
int cluster_size;
/* offset at which the VM state can be saved (0 if not possible) */
int64_t vm_state_offset;
int64_t highest_alloc; /* highest allocated block offset (in bytes) */
int64_t num_free_bytes; /* below highest_alloc */
} BlockDriverInfo;
typedef struct QEMUSnapshotInfo {
@@ -103,8 +101,6 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
BlockDriverCompletionFunc *cb, void *opaque);
void bdrv_aio_cancel(BlockDriverAIOCB *acb);
int qemu_key_check(BlockDriverState *bs, const char *name);
/* Ensure contents are flushed to disk. */
void bdrv_flush(BlockDriverState *bs);
void bdrv_flush_all(void);
@@ -141,9 +137,12 @@ void bdrv_set_change_cb(BlockDriverState *bs,
void (*change_cb)(void *opaque), void *opaque);
void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
BlockDriverState *bdrv_find(const char *name);
void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque);
void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs),
void *opaque);
int bdrv_is_encrypted(BlockDriverState *bs);
int bdrv_key_required(BlockDriverState *bs);
int bdrv_set_key(BlockDriverState *bs, const char *key);
int bdrv_query_missing_keys(void);
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
void *opaque);
const char *bdrv_get_device_name(BlockDriverState *bs);
@@ -151,6 +150,7 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
const char *bdrv_get_encrypted_filename(BlockDriverState *bs);
void bdrv_get_backing_filename(BlockDriverState *bs,
char *filename, int filename_size);
int bdrv_snapshot_create(BlockDriverState *bs,
@@ -169,4 +169,9 @@ void path_combine(char *dest, int dest_size,
const char *base_path,
const char *filename);
int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf,
int64_t pos, int size);
int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size);
#endif

View File

@@ -76,6 +76,11 @@ struct BlockDriver {
QEMUSnapshotInfo **psn_info);
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
int (*bdrv_put_buffer)(BlockDriverState *bs, const uint8_t *buf,
int64_t pos, int size);
int (*bdrv_get_buffer)(BlockDriverState *bs, uint8_t *buf,
int64_t pos, int size);
/* removable device specific */
int (*bdrv_is_inserted)(BlockDriverState *bs);
int (*bdrv_media_changed)(BlockDriverState *bs);
@@ -96,6 +101,7 @@ struct BlockDriverState {
int removable; /* if true, the media can be removed */
int locked; /* if true, the media cannot temporarily be ejected */
int encrypted; /* if true, the media is encrypted */
int valid_key; /* if true, a valid encryption key has been set */
int sg; /* if true, the device is a /dev/sg* */
/* event callback when inserting/removing */
void (*change_cb)(void *opaque);

2
configure vendored
View File

@@ -1013,7 +1013,7 @@ EOF
kvm="no";
if [ -x "`which awk 2>/dev/null`" ] && \
[ -x "`which grep 2>/dev/null`" ]; then
kvmerr=`$cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $kvm_cflags $TMPC 2>&1 \
kvmerr=`LANG=C $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $kvm_cflags $TMPC 2>&1 \
| grep "error: " \
| awk -F "error: " '{if (NR>1) printf(", "); printf("%s",$2);}'`
if test "$kvmerr" != "" ; then

View File

@@ -302,10 +302,9 @@ void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1
void term_print_filename(const char *filename);
void term_flush(void);
void term_print_help(void);
void monitor_readline(const char *prompt, int is_password,
char *buf, int buf_size);
void monitor_suspend(void);
void monitor_resume(void);
int monitor_read_bdrv_key(BlockDriverState *bs);
/* readline.c */
typedef void ReadLineFunc(void *opaque, const char *str);

View File

@@ -27,6 +27,7 @@
#include "config.h"
#include <setjmp.h>
#include <inttypes.h>
#include <signal.h>
#include "osdep.h"
#include "sys-queue.h"
@@ -170,6 +171,7 @@ typedef struct CPUWatchpoint {
memory was accessed */ \
uint32_t halted; /* Nonzero if the CPU is in suspend state */ \
uint32_t interrupt_request; \
volatile sig_atomic_t exit_request; \
/* The meaning of the MMU modes is defined in the target code. */ \
CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; \
target_phys_addr_t iotlb[NB_MMU_MODES][CPU_TLB_SIZE]; \

View File

@@ -311,7 +311,7 @@ int cpu_exec(CPUState *env1)
env->exception_index = -1;
}
#ifdef USE_KQEMU
if (kqemu_is_ok(env) && env->interrupt_request == 0) {
if (kqemu_is_ok(env) && env->interrupt_request == 0 && env->exit_request == 0) {
int ret;
env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
ret = kqemu_cpu_exec(env);
@@ -326,7 +326,7 @@ int cpu_exec(CPUState *env1)
} else if (ret == 2) {
/* softmmu execution needed */
} else {
if (env->interrupt_request != 0) {
if (env->interrupt_request != 0 || env->exit_request != 0) {
/* hardware interrupt will be executed just after */
} else {
/* otherwise, we restart */
@@ -525,11 +525,11 @@ int cpu_exec(CPUState *env1)
the program flow was changed */
next_tb = 0;
}
if (interrupt_request & CPU_INTERRUPT_EXIT) {
env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
env->exception_index = EXCP_INTERRUPT;
cpu_loop_exit();
}
}
if (unlikely(env->exit_request)) {
env->exit_request = 0;
env->exception_index = EXCP_INTERRUPT;
cpu_loop_exit();
}
#ifdef DEBUG_EXEC
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
@@ -599,7 +599,7 @@ int cpu_exec(CPUState *env1)
TB, but before it is linked into a potentially
infinite loop and becomes env->current_tb. Avoid
starting execution if there is a pending interrupt. */
if (unlikely (env->interrupt_request & CPU_INTERRUPT_EXIT))
if (unlikely (env->exit_request))
env->current_tb = NULL;
while (env->current_tb) {

12
exec.c
View File

@@ -523,6 +523,7 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
qemu_get_be32s(f, &env->halted);
qemu_get_be32s(f, &env->interrupt_request);
env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
tlb_flush(env, 1);
return 0;
@@ -1501,9 +1502,12 @@ void cpu_interrupt(CPUState *env, int mask)
#endif
int old_mask;
if (mask & CPU_INTERRUPT_EXIT) {
env->exit_request = 1;
mask &= ~CPU_INTERRUPT_EXIT;
}
old_mask = env->interrupt_request;
/* FIXME: This is probably not threadsafe. A different thread could
be in the middle of a read-modify-write operation. */
env->interrupt_request |= mask;
#if defined(USE_NPTL)
/* FIXME: TB unchaining isn't SMP safe. For now just ignore the
@@ -1514,10 +1518,8 @@ void cpu_interrupt(CPUState *env, int mask)
if (use_icount) {
env->icount_decr.u16.high = 0xffff;
#ifndef CONFIG_USER_ONLY
/* CPU_INTERRUPT_EXIT isn't a real interrupt. It just means
an async event happened and we need to process it. */
if (!can_do_io(env)
&& (mask & ~(old_mask | CPU_INTERRUPT_EXIT)) != 0) {
&& (mask & ~old_mask) != 0) {
cpu_abort(env, "Raised interrupt while not in I/O function");
}
#endif

View File

@@ -2637,11 +2637,16 @@ static void map_linear_vram(CirrusVGAState *s)
s->lfb_vram_mapped = 0;
cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000,
(s->vram_offset + s->cirrus_bank_base[0]) | IO_MEM_UNASSIGNED);
cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000,
(s->vram_offset + s->cirrus_bank_base[1]) | IO_MEM_UNASSIGNED);
if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
&& !((s->sr[0x07] & 0x01) == 0)
&& !((s->gr[0x0B] & 0x14) == 0x14)
&& !(s->gr[0x0B] & 0x02)) {
vga_dirty_log_stop((VGAState *)s);
cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000,
(s->vram_offset + s->cirrus_bank_base[0]) | IO_MEM_RAM);
cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000,

View File

@@ -666,8 +666,8 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
n = E1000_ICS_RXT0;
if ((rdt = s->mac_reg[RDT]) < s->mac_reg[RDH])
rdt += s->mac_reg[RDLEN] / sizeof(desc);
if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) << s->rxbuf_min_shift >=
s->mac_reg[RDLEN])
if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) <= s->mac_reg[RDLEN] >>
s->rxbuf_min_shift)
n |= E1000_ICS_RXDMT0;
set_ics(s, 0, n);

View File

@@ -67,6 +67,7 @@ unsigned int qemu_get_be32(QEMUFile *f);
uint64_t qemu_get_be64(QEMUFile *f);
int qemu_file_rate_limit(QEMUFile *f);
int qemu_file_has_error(QEMUFile *f);
void qemu_file_set_error(QEMUFile *f);
/* Try to send any outstanding data. This function is useful when output is
* halted due to rate limiting or EAGAIN errors occur as it can be used to

View File

@@ -1369,6 +1369,8 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
CASE_GET_REG32(dsa, 0x10)
case 0x14: /* ISTAT0 */
return s->istat0;
case 0x15: /* ISTAT1 */
return s->istat1;
case 0x16: /* MBOX0 */
return s->mbox0;
case 0x17: /* MBOX1 */

View File

@@ -95,19 +95,22 @@ static PCIDevice *qemu_pci_hot_add_storage(PCIBus *pci_bus, const char *opts)
type = IF_SCSI;
else if (!strcmp(buf, "virtio")) {
type = IF_VIRTIO;
} else {
term_printf("type %s not a hotpluggable PCI device.\n", buf);
goto out;
}
} else {
term_printf("no if= specified\n");
return NULL;
goto out;
}
if (get_param_value(buf, sizeof(buf), "file", opts)) {
drive_idx = add_init_drive(opts);
if (drive_idx < 0)
return NULL;
goto out;
} else if (type == IF_VIRTIO) {
term_printf("virtio requires a backing file/device.\n");
return NULL;
goto out;
}
switch (type) {
@@ -120,10 +123,9 @@ static PCIDevice *qemu_pci_hot_add_storage(PCIBus *pci_bus, const char *opts)
case IF_VIRTIO:
opaque = virtio_blk_init (pci_bus, drives_table[drive_idx].bdrv);
break;
default:
term_printf ("type %s not a hotpluggable PCI device.\n", buf);
}
out:
return opaque;
}

View File

@@ -37,6 +37,9 @@
#define SM501_VRAM_SIZE 0x800000
/* CONFIG_BOOT_LINK_OFFSET of Linux kernel */
#define LINUX_LOAD_OFFSET 0x800000
#define PA_IRLMSK 0x00
#define PA_POWOFF 0x30
#define PA_VERREG 0x32
@@ -233,20 +236,27 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
pci_nic_init(pci, &nd_table[i], (i==0)? 2<<3: -1, "rtl8139");
/* Todo: register on board registers */
{
if (kernel_filename) {
int kernel_size;
/* initialization which should be done by firmware */
stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */
stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */
kernel_size = load_image(kernel_filename, phys_ram_base);
if (kernel_cmdline) {
kernel_size = load_image_targphys(kernel_filename,
SDRAM_BASE + LINUX_LOAD_OFFSET,
SDRAM_SIZE - LINUX_LOAD_OFFSET);
env->pc = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000;
pstrcpy_targphys(SDRAM_BASE + 0x10100, 256, kernel_cmdline);
} else {
kernel_size = load_image_targphys(kernel_filename, SDRAM_BASE, SDRAM_SIZE);
env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
}
if (kernel_size < 0) {
fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
exit(1);
}
env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
}
}

View File

@@ -11,6 +11,7 @@
#include "usb.h"
#include "block.h"
#include "scsi-disk.h"
#include "console.h"
//#define DEBUG_MSD
@@ -513,7 +514,7 @@ static void usb_msd_handle_destroy(USBDevice *dev)
qemu_free(s);
}
USBDevice *usb_msd_init(const char *filename)
USBDevice *usb_msd_init(const char *filename, BlockDriverState **pbs)
{
MSDState *s;
BlockDriverState *bdrv;
@@ -552,9 +553,8 @@ USBDevice *usb_msd_init(const char *filename)
bdrv = bdrv_new("usb");
if (bdrv_open2(bdrv, filename, 0, drv) < 0)
goto fail;
if (qemu_key_check(bdrv, filename))
goto fail;
s->bs = bdrv;
*pbs = bdrv;
s->dev.speed = USB_SPEED_FULL;
s->dev.handle_packet = usb_generic_handle_packet;

View File

@@ -21,6 +21,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "block.h"
#define USB_TOKEN_SETUP 0x2d
#define USB_TOKEN_IN 0x69 /* device -> host */
#define USB_TOKEN_OUT 0xe1 /* host -> device */
@@ -250,7 +253,7 @@ USBDevice *usb_keyboard_init(void);
void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *));
/* usb-msd.c */
USBDevice *usb_msd_init(const char *filename);
USBDevice *usb_msd_init(const char *filename, BlockDriverState **pbs);
/* usb-net.c */
USBDevice *usb_net_init(NICInfo *nd);

View File

@@ -1616,6 +1616,16 @@ static void vga_draw_graphic(VGAState *s, int full_update)
s->double_scan = double_scan;
}
if (shift_control == 0) {
if (s->sr[0x01] & 8) {
disp_width <<= 1;
}
} else if (shift_control == 1) {
if (s->sr[0x01] & 8) {
disp_width <<= 1;
}
}
depth = s->get_bpp(s);
if (s->line_offset != s->last_line_offset ||
disp_width != s->last_width ||
@@ -1661,7 +1671,6 @@ static void vga_draw_graphic(VGAState *s, int full_update)
full_update |= update_palette16(s);
if (s->sr[0x01] & 8) {
v = VGA_DRAW_LINE4D2;
disp_width <<= 1;
} else {
v = VGA_DRAW_LINE4;
}
@@ -1670,7 +1679,6 @@ static void vga_draw_graphic(VGAState *s, int full_update)
full_update |= update_palette16(s);
if (s->sr[0x01] & 8) {
v = VGA_DRAW_LINE2D2;
disp_width <<= 1;
} else {
v = VGA_DRAW_LINE2;
}
@@ -2482,6 +2490,17 @@ int isa_vga_mm_init(uint8_t *vga_ram_base,
return 0;
}
static void pci_vga_write_config(PCIDevice *d,
uint32_t address, uint32_t val, int len)
{
PCIVGAState *pvs = container_of(d, PCIVGAState, dev);
VGAState *s = &pvs->vga_state;
vga_dirty_log_stop(s);
pci_default_write_config(d, address, val, len);
vga_dirty_log_start(s);
}
int pci_vga_init(PCIBus *bus, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size,
unsigned long vga_bios_offset, int vga_bios_size)
@@ -2492,7 +2511,7 @@ int pci_vga_init(PCIBus *bus, uint8_t *vga_ram_base,
d = (PCIVGAState *)pci_register_device(bus, "VGA",
sizeof(PCIVGAState),
-1, NULL, NULL);
-1, NULL, pci_vga_write_config);
if (!d)
return -1;
s = &d->vga_state;

View File

@@ -113,6 +113,21 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev)
return features;
}
static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
{
uint32_t features = 0;
/* Linux kernel 2.6.25. It understood MAC (as everyone must),
* but also these: */
features |= (1 << VIRTIO_NET_F_MAC);
features |= (1 << VIRTIO_NET_F_GUEST_CSUM);
features |= (1 << VIRTIO_NET_F_GUEST_TSO4);
features |= (1 << VIRTIO_NET_F_GUEST_TSO6);
features |= (1 << VIRTIO_NET_F_GUEST_ECN);
return features & virtio_net_get_features(vdev);
}
static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
{
VirtIONet *n = to_virtio_net(vdev);
@@ -228,7 +243,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
}
if (elem.out_sg[0].iov_len < sizeof(ctrl) ||
elem.out_sg[elem.in_num - 1].iov_len < sizeof(status)) {
elem.in_sg[elem.in_num - 1].iov_len < sizeof(status)) {
fprintf(stderr, "virtio-net ctrl header not in correct element\n");
exit(1);
}
@@ -580,6 +595,7 @@ PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
n->vdev.set_config = virtio_net_set_config;
n->vdev.get_features = virtio_net_get_features;
n->vdev.set_features = virtio_net_set_features;
n->vdev.bad_features = virtio_net_bad_features;
n->vdev.reset = virtio_net_reset;
n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx);

View File

@@ -516,6 +516,13 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
switch (addr) {
case VIRTIO_PCI_GUEST_FEATURES:
/* Guest does not negotiate properly? We have to assume nothing. */
if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
if (vdev->bad_features)
val = vdev->bad_features(vdev);
else
val = 0;
}
if (vdev->set_features)
vdev->set_features(vdev, val);
vdev->features = val;
@@ -555,7 +562,7 @@ static uint32_t virtio_ioport_read(void *opaque, uint32_t addr)
switch (addr) {
case VIRTIO_PCI_HOST_FEATURES:
ret = vdev->get_features(vdev);
ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY) | (1 << VIRTIO_F_BAD_FEATURE);
break;
case VIRTIO_PCI_GUEST_FEATURES:
ret = vdev->features;
@@ -726,9 +733,10 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
{
/* Always notify when queue is empty */
if ((vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx) &&
(vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT))
/* Always notify when queue is empty (when feature acknowledge) */
if ((vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT) &&
(!(vdev->features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) ||
(vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx)))
return;
vdev->isr |= 0x01;

View File

@@ -32,6 +32,8 @@
/* We notify when the ring is completely used, even if the guest is supressing
* callbacks */
#define VIRTIO_F_NOTIFY_ON_EMPTY 24
/* A guest should never accept this. It implies negotiation is broken. */
#define VIRTIO_F_BAD_FEATURE 30
/* from Linux's linux/virtio_ring.h */
@@ -82,6 +84,7 @@ struct VirtIODevice
size_t config_len;
void *config;
uint32_t (*get_features)(VirtIODevice *vdev);
uint32_t (*bad_features)(VirtIODevice *vdev);
void (*set_features)(VirtIODevice *vdev, uint32_t val);
void (*get_config)(VirtIODevice *vdev, uint8_t *config);
void (*set_config)(VirtIODevice *vdev, const uint8_t *config);

View File

@@ -445,7 +445,7 @@ int kvm_cpu_exec(CPUState *env)
do {
kvm_arch_pre_run(env, run);
if ((env->interrupt_request & CPU_INTERRUPT_EXIT)) {
if (env->exit_request) {
dprintf("interrupt exit requested\n");
ret = 0;
break;
@@ -512,8 +512,8 @@ int kvm_cpu_exec(CPUState *env)
}
} while (ret > 0);
if ((env->interrupt_request & CPU_INTERRUPT_EXIT)) {
env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
if (env->exit_request) {
env->exit_request = 0;
env->exception_index = EXCP_INTERRUPT;
}

View File

@@ -90,11 +90,12 @@ int fread_targphys(target_phys_addr_t dst_addr, size_t nbytes, FILE *f)
while (nbytes) {
want = nbytes > sizeof(buf) ? sizeof(buf) : nbytes;
did = fread(buf, 1, want, f);
if (did != want) break;
cpu_physical_memory_write_rom(dst_addr, buf, did);
dst_addr += did;
nbytes -= did;
if (did != want)
break;
}
return dst_addr - dst_begin;
}

View File

@@ -212,13 +212,19 @@ void migrate_fd_put_ready(void *opaque)
dprintf("iterate\n");
if (qemu_savevm_state_iterate(s->file) == 1) {
int state;
dprintf("done iterating\n");
vm_stop(0);
bdrv_flush_all();
qemu_savevm_state_complete(s->file);
s->state = MIG_STATE_COMPLETED;
if ((qemu_savevm_state_complete(s->file)) < 0) {
vm_start();
state = MIG_STATE_ERROR;
} else {
state = MIG_STATE_COMPLETED;
}
migrate_fd_cleanup(s);
s->state = state;
}
}

View File

@@ -76,6 +76,8 @@ static uint8_t term_outbuf[1024];
static int term_outbuf_index;
static void monitor_start_input(void);
static void monitor_readline(const char *prompt, int is_password,
char *buf, int buf_size);
static CPUState *mon_cpu = NULL;
@@ -433,7 +435,7 @@ static void do_change_block(const char *device, const char *filename, const char
if (eject_device(bs, 0) < 0)
return;
bdrv_open2(bs, filename, 0, drv);
qemu_key_check(bs, filename);
monitor_read_bdrv_key(bs);
}
static void do_change_vnc(const char *target, const char *arg)
@@ -494,9 +496,24 @@ static void do_stop(void)
vm_stop(EXCP_INTERRUPT);
}
static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs)
{
int *err = opaque;
if (bdrv_key_required(bs))
*err = monitor_read_bdrv_key(bs);
else
*err = 0;
}
static void do_cont(void)
{
vm_start();
int err = 0;
bdrv_iterate(encrypted_bdrv_it, &err);
/* only resume the vm if all keys are set and valid */
if (!err)
vm_start();
}
#ifdef CONFIG_GDBSTUB
@@ -2679,8 +2696,9 @@ static void file_completion(const char *input)
closedir(ffs);
}
static void block_completion_it(void *opaque, const char *name)
static void block_completion_it(void *opaque, BlockDriverState *bs)
{
const char *name = bdrv_get_device_name(bs);
const char *input = opaque;
if (input[0] == '\0' ||
@@ -2891,8 +2909,8 @@ static void monitor_readline_cb(void *opaque, const char *input)
monitor_readline_started = 0;
}
void monitor_readline(const char *prompt, int is_password,
char *buf, int buf_size)
static void monitor_readline(const char *prompt, int is_password,
char *buf, int buf_size)
{
int i;
int old_focus[MAX_MON];
@@ -2922,3 +2940,22 @@ void monitor_readline(const char *prompt, int is_password,
monitor_hd[i]->focus = old_focus[i];
}
}
int monitor_read_bdrv_key(BlockDriverState *bs)
{
char password[256];
int i;
if (!bdrv_is_encrypted(bs))
return 0;
term_printf("%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
bdrv_get_encrypted_filename(bs));
for(i = 0; i < 3; i++) {
monitor_readline("Password: ", 1, password, sizeof(password));
if (bdrv_set_key(bs, password) == 0)
return 0;
term_printf("invalid password\n");
}
return -EPERM;
}

5
net.c
View File

@@ -1818,11 +1818,6 @@ void net_host_device_remove(int vlan_id, const char *device)
VLANState *vlan;
VLANClientState *vc;
if (!net_host_check_device(device)) {
term_printf("invalid host network device %s\n", device);
return;
}
vlan = qemu_find_vlan(vlan_id);
if (!vlan) {
term_printf("can't find vlan %d\n", vlan_id);

View File

@@ -101,6 +101,10 @@
/***********************************************************/
/* character device */
static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
TAILQ_HEAD_INITIALIZER(chardevs);
static int initial_reset_issued;
static void qemu_chr_event(CharDriverState *s, int event)
{
if (!s->chr_event)
@@ -118,12 +122,23 @@ static void qemu_chr_reset_bh(void *opaque)
void qemu_chr_reset(CharDriverState *s)
{
if (s->bh == NULL) {
if (s->bh == NULL && initial_reset_issued) {
s->bh = qemu_bh_new(qemu_chr_reset_bh, s);
qemu_bh_schedule(s->bh);
}
}
void qemu_chr_initial_reset(void)
{
CharDriverState *chr;
initial_reset_issued = 1;
TAILQ_FOREACH(chr, &chardevs, next) {
qemu_chr_reset(chr);
}
}
int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
{
return s->chr_write(s, buf, len);
@@ -210,12 +225,15 @@ typedef struct {
IOEventHandler *chr_event[MAX_MUX];
void *ext_opaque[MAX_MUX];
CharDriverState *drv;
unsigned char buffer[MUX_BUFFER_SIZE];
int prod;
int cons;
int mux_cnt;
int term_got_escape;
int max_size;
/* Intermediate input buffer allows to catch escape sequences even if the
currently active device is not accepting any input - but only until it
is full as well. */
unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE];
int prod[MAX_MUX];
int cons[MAX_MUX];
} MuxDriver;
@@ -345,11 +363,11 @@ static void mux_chr_accept_input(CharDriverState *chr)
int m = chr->focus;
MuxDriver *d = chr->opaque;
while (d->prod != d->cons &&
while (d->prod[m] != d->cons[m] &&
d->chr_can_read[m] &&
d->chr_can_read[m](d->ext_opaque[m])) {
d->chr_read[m](d->ext_opaque[m],
&d->buffer[d->cons++ & MUX_BUFFER_MASK], 1);
&d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
}
}
@@ -357,11 +375,12 @@ static int mux_chr_can_read(void *opaque)
{
CharDriverState *chr = opaque;
MuxDriver *d = chr->opaque;
int m = chr->focus;
if ((d->prod - d->cons) < MUX_BUFFER_SIZE)
if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE)
return 1;
if (d->chr_can_read[chr->focus])
return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
if (d->chr_can_read[m])
return d->chr_can_read[m](d->ext_opaque[m]);
return 0;
}
@@ -376,12 +395,12 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
for(i = 0; i < size; i++)
if (mux_proc_byte(chr, d, buf[i])) {
if (d->prod == d->cons &&
if (d->prod[m] == d->cons[m] &&
d->chr_can_read[m] &&
d->chr_can_read[m](d->ext_opaque[m]))
d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
else
d->buffer[d->prod++ & MUX_BUFFER_MASK] = buf[i];
d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
}
}
@@ -898,6 +917,8 @@ static void pty_chr_close(struct CharDriverState *chr)
qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
close(s->fd);
qemu_del_timer(s->timer);
qemu_free_timer(s->timer);
qemu_free(s);
}
@@ -1727,6 +1748,16 @@ static void udp_chr_update_read_handler(CharDriverState *chr)
}
}
static void udp_chr_close(CharDriverState *chr)
{
NetCharDriver *s = chr->opaque;
if (s->fd >= 0) {
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
closesocket(s->fd);
}
qemu_free(s);
}
static CharDriverState *qemu_chr_open_udp(const char *def)
{
CharDriverState *chr = NULL;
@@ -1760,6 +1791,7 @@ static CharDriverState *qemu_chr_open_udp(const char *def)
chr->opaque = s;
chr->chr_write = udp_chr_write;
chr->chr_update_read_handler = udp_chr_update_read_handler;
chr->chr_close = udp_chr_close;
return chr;
return_err:
@@ -1962,10 +1994,14 @@ static void tcp_chr_accept(void *opaque)
static void tcp_chr_close(CharDriverState *chr)
{
TCPCharDriver *s = chr->opaque;
if (s->fd >= 0)
if (s->fd >= 0) {
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
closesocket(s->fd);
if (s->listen_fd >= 0)
}
if (s->listen_fd >= 0) {
qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
closesocket(s->listen_fd);
}
qemu_free(s);
}
@@ -2076,9 +2112,6 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
return NULL;
}
static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs
= TAILQ_HEAD_INITIALIZER(chardevs);
CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
{
const char *p;

View File

@@ -74,6 +74,7 @@ void qemu_chr_add_handlers(CharDriverState *s,
void *opaque);
int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
void qemu_chr_reset(CharDriverState *s);
void qemu_chr_initial_reset(void);
int qemu_chr_can_read(CharDriverState *s);
void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
void qemu_chr_accept_input(CharDriverState *s);

View File

@@ -74,8 +74,8 @@ static void help(void)
" differ\n"
" 'fmt' is the disk image format. It is guessed automatically in most cases\n"
" 'size' is the disk image size in kilobytes. Optional suffixes\n"
" 'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are"
" supported any @code{k} or @code{K} is ignored\n"
" 'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are\n"
" supported any 'k' or 'K' is ignored\n"
" 'output_filename' is the destination disk image filename\n"
" 'output_fmt' is the destination format\n"
" '-c' indicates that target image must be compressed (qcow format only)\n"
@@ -730,10 +730,6 @@ static int img_info(int argc, char **argv)
if (bdrv_get_info(bs, &bdi) >= 0) {
if (bdi.cluster_size != 0)
printf("cluster_size: %d\n", bdi.cluster_size);
if (bdi.highest_alloc)
printf("highest_alloc: %" PRId64 "\n", bdi.highest_alloc);
if (bdi.num_free_bytes)
printf("num_free_bytes: %" PRId64 "\n", bdi.num_free_bytes);
}
bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
if (backing_filename[0] != '\0') {

View File

@@ -118,7 +118,9 @@ void qemu_announce_self(void)
VLANClientState *vc;
uint8_t buf[256];
for (i = 0; i < nb_nics; i++) {
for (i = 0; i < MAX_NICS; i++) {
if (!nd_table[i].used)
continue;
len = announce_self_create(buf, nd_table[i].macaddr);
vlan = nd_table[i].vlan;
for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
@@ -304,18 +306,18 @@ typedef struct QEMUFileBdrv
int64_t base_offset;
} QEMUFileBdrv;
static int bdrv_put_buffer(void *opaque, const uint8_t *buf,
static int block_put_buffer(void *opaque, const uint8_t *buf,
int64_t pos, int size)
{
QEMUFileBdrv *s = opaque;
bdrv_pwrite(s->bs, s->base_offset + pos, buf, size);
bdrv_put_buffer(s->bs, buf, s->base_offset + pos, size);
return size;
}
static int bdrv_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
{
QEMUFileBdrv *s = opaque;
return bdrv_pread(s->bs, s->base_offset + pos, buf, size);
return bdrv_get_buffer(s->bs, buf, s->base_offset + pos, size);
}
static int bdrv_fclose(void *opaque)
@@ -335,9 +337,9 @@ static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_wr
s->base_offset = offset;
if (is_writable)
return qemu_fopen_ops(s, bdrv_put_buffer, NULL, bdrv_fclose, NULL);
return qemu_fopen_ops(s, block_put_buffer, NULL, bdrv_fclose, NULL);
return qemu_fopen_ops(s, NULL, bdrv_get_buffer, bdrv_fclose, NULL);
return qemu_fopen_ops(s, NULL, block_get_buffer, bdrv_fclose, NULL);
}
QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
@@ -364,6 +366,11 @@ int qemu_file_has_error(QEMUFile *f)
return f->has_error;
}
void qemu_file_set_error(QEMUFile *f)
{
f->has_error = 1;
}
void qemu_fflush(QEMUFile *f)
{
if (!f->put_buffer)

2
sdl.c
View File

@@ -27,7 +27,7 @@
#include "x_keymap.h"
#include <SDL.h>
#include <SDL/SDL_syswm.h>
#include <SDL_syswm.h>
#ifndef _WIN32
#include <signal.h>

View File

@@ -1421,10 +1421,10 @@ static void host_cpuid(uint32_t function, uint32_t count,
#else
asm volatile("pusha \n\t"
"cpuid \n\t"
"mov %%eax, 0(%1) \n\t"
"mov %%ebx, 4(%1) \n\t"
"mov %%ecx, 8(%1) \n\t"
"mov %%edx, 12(%1) \n\t"
"mov %%eax, 0(%2) \n\t"
"mov %%ebx, 4(%2) \n\t"
"mov %%ecx, 8(%2) \n\t"
"mov %%edx, 12(%2) \n\t"
"popa"
: : "a"(function), "c"(count), "S"(vec)
: "memory", "cc");

View File

@@ -3241,6 +3241,8 @@ target_ulong helper_lsl(target_ulong selector1)
selector = selector1 & 0xffff;
eflags = helper_cc_compute_all(CC_OP);
if ((selector & 0xfffc) == 0)
goto fail;
if (load_segment(&e1, &e2, selector) != 0)
goto fail;
rpl = selector & 3;

80
vl.c
View File

@@ -201,6 +201,7 @@ ram_addr_t ram_size;
int nb_nics;
NICInfo nd_table[MAX_NICS];
int vm_running;
static int autostart;
static int rtc_utc = 1;
static int rtc_date_offset = -1; /* -1 means no change */
int cirrus_vga_enabled = 1;
@@ -2607,11 +2608,13 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
bdrv_flags |= BDRV_O_CACHE_WB;
else if (cache == 3) /* not specified */
bdrv_flags |= BDRV_O_CACHE_DEF;
if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) {
if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
fprintf(stderr, "qemu: could not open disk image %s\n",
file);
return -1;
}
if (bdrv_key_required(bdrv))
autostart = 0;
return drives_table_idx;
}
@@ -2658,7 +2661,7 @@ int usb_device_add_dev(USBDevice *dev)
return 0;
}
static int usb_device_add(const char *devname)
static int usb_device_add(const char *devname, int is_hotplug)
{
const char *p;
USBDevice *dev;
@@ -2675,7 +2678,18 @@ static int usb_device_add(const char *devname)
} else if (!strcmp(devname, "keyboard")) {
dev = usb_keyboard_init();
} else if (strstart(devname, "disk:", &p)) {
dev = usb_msd_init(p);
BlockDriverState *bs;
dev = usb_msd_init(p, &bs);
if (!dev)
return -1;
if (bdrv_key_required(bs)) {
autostart = 0;
if (is_hotplug && monitor_read_bdrv_key(bs) < 0) {
dev->handle_destroy(dev);
return -1;
}
}
} else if (!strcmp(devname, "wacom-tablet")) {
dev = usb_wacom_init();
} else if (strstart(devname, "serial:", &p)) {
@@ -2756,7 +2770,7 @@ static int usb_device_del(const char *devname)
void do_usb_add(const char *devname)
{
usb_device_add(devname);
usb_device_add(devname, 1);
}
void do_usb_del(const char *devname)
@@ -3206,10 +3220,10 @@ static int ram_save_live(QEMUFile *f, int stage, void *opaque)
/* try transferring iterative blocks of memory */
if (stage == 3) {
cpu_physical_memory_set_dirty_tracking(0);
/* flush all remaining blocks regardless of rate limiting */
while (ram_save_block(f) != 0);
cpu_physical_memory_set_dirty_tracking(0);
}
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
@@ -4230,9 +4244,7 @@ static const QEMUOption qemu_options[] = {
{ "boot", HAS_ARG, QEMU_OPTION_boot },
{ "snapshot", 0, QEMU_OPTION_snapshot },
{ "m", HAS_ARG, QEMU_OPTION_m },
#ifndef _WIN32
{ "k", HAS_ARG, QEMU_OPTION_k },
#endif
#ifdef HAS_AUDIO
{ "audio-help", 0, QEMU_OPTION_audio_help },
{ "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
@@ -4334,45 +4346,6 @@ static const QEMUOption qemu_options[] = {
{ NULL },
};
/* password input */
int qemu_key_check(BlockDriverState *bs, const char *name)
{
char password[256];
int i;
if (!bdrv_is_encrypted(bs))
return 0;
term_printf("%s is encrypted.\n", name);
for(i = 0; i < 3; i++) {
monitor_readline("Password: ", 1, password, sizeof(password));
if (bdrv_set_key(bs, password) == 0)
return 0;
term_printf("invalid password\n");
}
return -EPERM;
}
static BlockDriverState *get_bdrv(int index)
{
if (index > nb_drives)
return NULL;
return drives_table[index].bdrv;
}
static void read_passwords(void)
{
BlockDriverState *bs;
int i;
for(i = 0; i < 6; i++) {
bs = get_bdrv(i);
if (bs)
qemu_key_check(bs, bdrv_get_device_name(bs));
}
}
#ifdef HAS_AUDIO
struct soundhw soundhw[] = {
#ifdef HAS_AUDIO_CHOICE
@@ -4639,7 +4612,6 @@ int main(int argc, char **argv, char **envp)
int fds[2];
int tb_size;
const char *pid_file = NULL;
int autostart;
const char *incoming = NULL;
int fd = 0;
struct passwd *pwd = NULL;
@@ -4696,7 +4668,7 @@ int main(int argc, char **argv, char **envp)
kernel_cmdline = "";
cyls = heads = secs = 0;
translation = BIOS_ATA_TRANSLATION_AUTO;
monitor_device = "vc";
monitor_device = "vc:80Cx24C";
serial_devices[0] = "vc:80Cx24C";
for(i = 1; i < MAX_SERIAL_PORTS; i++)
@@ -5637,7 +5609,7 @@ int main(int argc, char **argv, char **envp)
/* init USB devices */
if (usb_enabled) {
for(i = 0; i < usb_devices_index; i++) {
if (usb_device_add(usb_devices[i]) < 0) {
if (usb_device_add(usb_devices[i], 0) < 0) {
fprintf(stderr, "Warning: could not add USB device %s\n",
usb_devices[i]);
}
@@ -5693,6 +5665,7 @@ int main(int argc, char **argv, char **envp)
}
text_consoles_set_display(display_state);
qemu_chr_initial_reset();
if (monitor_device && monitor_hd)
monitor_init(monitor_hd, !nographic);
@@ -5747,13 +5720,8 @@ int main(int argc, char **argv, char **envp)
qemu_start_incoming_migration(incoming);
}
{
/* XXX: simplify init */
read_passwords();
if (autostart) {
vm_start();
}
}
if (autostart)
vm_start();
if (daemonize) {
uint8_t status = 0;