Compare commits

...

35 Commits

Author SHA1 Message Date
Michael Roth
785adb09b9 update VERSION for v1.1.1
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-07-12 13:36:53 -05:00
Michael Roth
f52d0d639e Merge remote-tracking branch 'agraf/s390-for-upstream-1.1' into HEAD 2012-07-10 14:08:37 -05:00
Alexander Graf
4082e889ee s390x: fix s390 virtio aliases
Some of the virtio devices have the same frontend name, but actually
implement different devices behind the scenes through aliases.

The indicator which device type to use is the architecture. On s390, we
want s390 virtio devices. On everything else, we want PCI devices.

Reflect this in the alias selection code. This way we fix commands like
-device virtio-blk on s390x which with this patch applied select the
correct virtio-blk-s390 device rather than virtio-blk-pci.

Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2012-07-10 18:29:29 +02:00
Jason Wang
b7093f294c rtl8139: validate rx ring before receiving packets
Commit ff71f2e8ca prevent the possible
crash during initialization of linux driver by checking the operating
mode.This seems too strict as:

- the real card could still work in mode other than normal
- some buggy driver who does not set correct opmode after eeprom
 access

So, considering rx ring address were reset to zero (which could be
safely trated as an address not intened to DMA to), in order to
both letting old guest work and preventing the unexpected DMA to
guest, we can forbid packet receiving when rx ring address is zero.

Tested-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit fcce6fd25f)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-29 10:22:30 -05:00
Daniel Verkamp
cd63a77e99 ahci: SATA FIS is 20 bytes, not 0x20
As in the SATA and AHCI specifications, a FIS is 5 Dwords of 4 bytes
each, which comes to 20 bytes (decimal), not 0x20.

Signed-off-by: Daniel Verkamp <daniel@drv.nu>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 4bb9c939a5)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 10:58:24 -05:00
Stefan Hajnoczi
8456852657 qemu-img: document qed format on qemu-img man page
The qemu-img.1 man page is missing the qed format from its list of
supported formats.  Document the image creation options for qed.

Suggested-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>
(cherry picked from commit f085800e24)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 09:04:33 -05:00
Stefan Weil
7d440f20bd virtio: Fix compiler warning for non Linux hosts
The local variables ret, i are only used if __linux__ is defined.

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

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 09:04:04 -05:00
MORITA Kazutaka
feba8ae20b sheepdog: fix return value of do_load_save_vm_state
bdrv_save_vmstate and bdrv_load_vmstate should return the vmstate size
on success, and -errno on error.

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

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 09:03:33 -05:00
Jan Beulich
c9c2479289 qemu/xendisk: set maximum number of grants to be used
Legacy (non-pvops) gntdev drivers may require this to be done when the
number of grants intended to be used simultaneously exceeds a certain
driver specific default limit.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
(cherry picked from commit 64c27e5b1f)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 09:00:42 -05:00
Bruce Rogers
4c45bf61d3 build: install qmp-commands.txt
File is targeted for install, but is never installed.

Signed-off-by: Bruce Rogers <brogers@suse.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
(cherry picked from commit 0cd23fcc0a)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:55:50 -05:00
Pavel Hrdina
70d582074f fdc: fix implied seek while there is no media in drive
The Windows uses 'READ' command at the start of an instalation
without checking the 'dir' register. We have to abort the transfer
with an abnormal termination if there is no media in the drive.

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

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:55:44 -05:00
Stefan Hajnoczi
0da4c07322 qcow2: fix autoclear image header update
The autoclear feature bits can be used for qcow2 file format features
that are safe to "drop" by old programs that do not understand the
feature.  Upon opening the image file unknown autoclear feature bits are
cleared and the image file header is rewritten, but this was happening
too early in the code when critical header fields were not yet loaded.

Process autoclear feature bits after all necessary header information
has been loaded.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit af7b708db2)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:55:38 -05:00
Pavel Dovgaluk
ee7735fa63 Prevent disk data loss when closing qemu
Prevent disk data loss when closing qemu console window
under Windows 7.

v3. Comment for Sleep() parameter was updated.

Signed-off-by: Pavel Dovgalyuk<pavel.dovgaluk@gmail.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit b75a02829d)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:55:33 -05:00
Zhi Yong Wu
02fe741375 qcow2: fix endianness conversion
Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 87267753a3)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:55:25 -05:00
Jason Baron
dbe4ac16bb pci_bridge_dev: fix error path in pci_bridge_dev_initfn()
Currently, we do not properly cleanup, if pci_bridge_dev_initfn
fails to initialize properly. Make sure to call pci_bridge_exitfn()
in the error path.

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

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:55:19 -05:00
Jason Baron
f63e60327b qdev: release parent properties on dc->init failure
While looking into hot-plugging bridges, I can create a qemu segfault via:

$ device_add pci-bridge

Bridge chassis not specified. Each bridge is required to be assigned a unique chassis id > 0.
**
ERROR:qom/object.c:389:object_delete: assertion failed: (obj->ref == 0)

I'm proposing to fix this by adding a call to 'object_unparent()', before the
call to qdev_free(). I see there is already a precedent for this usage pattern as
seen in qdev_simple_unplug_cb():

/* can be used as ->unplug() callback for the simple cases */
int qdev_simple_unplug_cb(DeviceState *dev)
{
    /* just zap it */
    object_unparent(OBJECT(dev));
    qdev_free(dev);
    return 0;
}

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

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:55:12 -05:00
Jan Kiszka
0ec3907571 intel-hda: Fix reset of MSI function
Call msi_reset on device reset as still required by the core.

CC: Gerd Hoffmann <kraxel@redhat.com>
CC: qemu-stable@nongnu.org
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 8e729e3b52)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:55:06 -05:00
Jan Kiszka
1658e3cd89 ahci: Fix reset of MSI function
Call msi_reset on device reset as still required by the core.

CC: Alexander Graf <agraf@suse.de>
CC: qemu-stable@nongnu.org
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 868a1a5226)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:55:00 -05:00
Fernando Luis Vazquez Cao
065436479b rtl8139: honor RxOverflow flag in can_receive method
Some drivers (Linux' 8139too among them) rely on the NIC
injecting an interrupt in the event of a receive buffer overflow
and, accordingly, set the RxOverflow bit in the interrupt
mask. Unfortunately rtl8139's can_receive method ignores the
RxOverflow flag, which may lead to a situation where rtl8139
stops receiving packets (can_receive returns 0) when the receive
buffer becomes full.

If the driver eventually read from the receive buffer or reset
the card the emulator could recover from this situation. However
some implementations only do this upon receiving an interrupt
with either RxOK or RxOverflow set in the ISR; interrupt that
will never come because QEMU's flow control mechanisms would
prevent rtl8139 from receiving any packet.

Letting packets go through when the overflow interrupt is enabled
makes the QEMU emulator compliant to the spec and solves the
problem.

This patch should fix a relatively common (in our experience)
network stall observed when running enterprise distros with
rtl8139 as the NIC; in some cases the 8139too device driver gets
loaded and when under heavy load the network eventually stops
working.

Reported-by: Hayato Kakuta <kakuta.hayato@oss.ntt.co.jp>
Tested-by: Hayato Kakuta <kakuta.hayato@oss.ntt.co.jp>
Acked-by: Igor Kovalenko <igor.v.kovalenko@gmail.com>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit fee9d348ff)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:54:55 -05:00
Stefan Weil
f6db26e4f8 configure: Fix build for some versions of glibc (9pfs)
Some versions declare open_by_handle_at, but don't define AT_EMPTY_PATH.
Extend the check in configure to test both preconditions.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Serge Hallyn <serge.hallyn@ubuntu.com>
(cherry picked from commit acc55ba8b1)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:54:44 -05:00
Stefan Weil
c49dd1bf64 monitor: Fix memory leak with readline completion
Each string which is shown during readline completion in the QEMU monitor
is allocated dynamically but currently never deallocated.

Add the missing loop which calls g_free for the allocated strings.

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

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:53:25 -05:00
Kevin Wolf
b4fcb4b499 qcow2: Silence false warning
Some gcc versions seem not to be able to figure out that the switch
statement covers all possible values and that c is therefore always
initialised. Add a default branch for them.

Reported-by: malc <av1474@comtv.ru>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: malc <av1474@comtv.ru>
(cherry picked from commit 1417d7e40e)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:53:20 -05:00
Jan Kiszka
7672b714b2 kvm: i8254: Fix conversion of in-kernel to userspace state
Due to a offset between the clock used to generate the in-kernel
count_load_time (CLOCK_MONOTONIC) and the clock used for processing this
in userspace (vm_clock), reading back the output of PIT channel 2 via
port 0x61 was broken. One use cases that suffered from it was the CPU
frequency calibration of SeaBIOS, which also affected IDE/AHCI timeouts.

This fixes it by calibrating the offset between both clocks on
kvm_pit_get and adjusting the kernel value before saving it in the
userspace state. As the calibration only works while the vm_clock is
running, we cache the in-kernel state across stopped phases.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
(cherry picked from commit 0cdd3d1444)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:53:13 -05:00
Jim Meyering
ca09717e8e kvm/apic: correct short memset
kvm_put_apic_state's attempt to clear *kapic before setting its
bits cleared sizeof(void*) bytes (no more than 8) rather than the
intended 1024 (KVM_APIC_REG_SIZE) bytes. Spotted by coverity.

Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
(cherry picked from commit 0614cb82ca)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:53:05 -05:00
Harsh Prateek Bora
0cc21de484 configure: report missing libraries for virtfs
Signed-off-by: Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 263ddcc81b)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:52:57 -05:00
Harsh Prateek Bora
08375616a0 trace/simple.c: fix deprecated glib2 interface
Signed-off-by: Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
(cherry picked from commit 0d665005c7)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:52:44 -05:00
Max Filippov
b993b863e7 target-xtensa: fix CCOUNT for conditional branches
Taken conditional branches fail to update CCOUNT register because
accumulated ccount_delta is reset during translation of non-taken
branch. To fix it only update CCOUNT once per conditional branch
instruction translation.

This fixes guest linux freeze on LTP waitpid06 test.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit d865f30739)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:48:56 -05:00
Max Filippov
07ff37597b exec: fix TB invalidation after breakpoint insertion/deletion
tb_invalidate_phys_addr has to be called with the exact physical address of
the breakpoint we add/remove, not just the page's base address.
Otherwise we easily fail to flush the right TB.

This breakage was introduced by the commit f3705d5329 "memory: make
phys_page_find() return an unadjusted".

This appeared to work for some guest architectures because their
cpu_get_phys_page_debug implementation returns full translated physical
address, not just the base of the TARGET_PAGE_SIZE-sized page.

Reported-by: TeLeMan <geleman@gmail.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit 9d70c4b7b8)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:48:46 -05:00
Max Filippov
e77326d99c target-xtensa: add MMU pagewalking tests
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit c305e32f43)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:48:38 -05:00
Max Filippov
8b3ac66120 target-xtensa: control page table lookup explicitly
Hardware pagetable walking may not be nested. Stop guessing and pass
explicit flag to the get_physical_addr_mmu function that controls page
table lookup.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit 57705a676c)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:48:31 -05:00
Max Filippov
2eb4d314ce target-xtensa: update autorefill TLB entries conditionally
This is to avoid interference of internal QEMU helpers
(cpu_get_phys_page_debug, tb_invalidate_virtual_addr) with guest-visible
TLB state.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit ae4e7982e6)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:48:23 -05:00
Max Filippov
adda59173c target-xtensa: extract TLB entry setting method
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit 16bde77a29)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:48:13 -05:00
Max Filippov
b696aeab6a target-xtensa: update EXCVADDR in case of page table lookup
According to ISA, 4.4.2.6, EXCVADDR may be changed by any TLB miss, even
if the miss is handled entirely by processor hardware.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit 39e7d37f0f)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:48:06 -05:00
Max Filippov
6514fe5047 target-xtensa: flush TLB page for new MMU mapping
Both old and new mappings need flushing because their VPN may be
different in MMU case.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit e323bdeff2)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:47:58 -05:00
Christian Borntraeger
c63c453889 virtio-blk: Fix geometry sector calculation
Currently the sector value for the geometry is masked, even if the
user usesa command line parameter that explicitely gives a number.
This breaks dasd devices on s390. A dasd device can have
a physical block size of 4096 (== same for logical block size)
and a typcial geometry of 15 heads and 12 sectors per cyl.
The ibm partition detection relies on a correct geometry
reported by the device. Unfortunately the current code changes
12 to 8. This would be necessary if the total size is
not a multiple of logical sector size,  but for dasd this
is not the case.

This patch checks the device size and only applies sector
mask if necessary.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
CC: Christoph Hellwig <hch@lst.de>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 136be99e6e)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2012-06-25 08:47:47 -05:00
29 changed files with 468 additions and 97 deletions

View File

@@ -271,6 +271,7 @@ endif
install-doc: $(DOCS) install-doc: $(DOCS)
$(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)" $(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)"
$(INSTALL_DATA) qemu-doc.html qemu-tech.html "$(DESTDIR)$(qemu_docdir)" $(INSTALL_DATA) qemu-doc.html qemu-tech.html "$(DESTDIR)$(qemu_docdir)"
$(INSTALL_DATA) QMP/qmp-commands.txt "$(DESTDIR)$(qemu_docdir)"
ifdef CONFIG_POSIX ifdef CONFIG_POSIX
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1" $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
$(INSTALL_DATA) qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1" $(INSTALL_DATA) qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1"

View File

@@ -1 +1 @@
1.1.0 1.1.1

View File

@@ -471,6 +471,8 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
QCOW_OFLAG_COMPRESSED | QCOW_OFLAG_ZERO); QCOW_OFLAG_COMPRESSED | QCOW_OFLAG_ZERO);
*cluster_offset &= L2E_OFFSET_MASK; *cluster_offset &= L2E_OFFSET_MASK;
break; break;
default:
abort();
} }
qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);

View File

@@ -367,7 +367,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
} }
for(i = 0; i < table_size; i++) { for(i = 0; i < table_size; i++) {
cpu_to_be64s(&new_table[i]); be64_to_cpus(&new_table[i]);
} }
/* Hook up the new refcount table in the qcow2 header */ /* Hook up the new refcount table in the qcow2 header */

View File

@@ -298,14 +298,6 @@ static int qcow2_open(BlockDriverState *bs, int flags)
goto fail; goto fail;
} }
if (!bs->read_only && s->autoclear_features != 0) {
s->autoclear_features = 0;
ret = qcow2_update_header(bs);
if (ret < 0) {
goto fail;
}
}
/* Check support for various header values */ /* Check support for various header values */
if (header.refcount_order != 4) { if (header.refcount_order != 4) {
report_unsupported(bs, "%d bit reference counts", report_unsupported(bs, "%d bit reference counts",
@@ -411,6 +403,15 @@ static int qcow2_open(BlockDriverState *bs, int flags)
goto fail; goto fail;
} }
/* Clear unknown autoclear feature bits */
if (!bs->read_only && s->autoclear_features != 0) {
s->autoclear_features = 0;
ret = qcow2_update_header(bs);
if (ret < 0) {
goto fail;
}
}
/* Initialise locks */ /* Initialise locks */
qemu_co_mutex_init(&s->lock); qemu_co_mutex_init(&s->lock);

View File

@@ -1957,7 +1957,7 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
int64_t pos, int size, int load) int64_t pos, int size, int load)
{ {
int fd, create; int fd, create;
int ret = 0; int ret = 0, remaining = size;
unsigned int data_len; unsigned int data_len;
uint64_t vmstate_oid; uint64_t vmstate_oid;
uint32_t vdi_index; uint32_t vdi_index;
@@ -1968,11 +1968,11 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
return fd; return fd;
} }
while (size) { while (remaining) {
vdi_index = pos / SD_DATA_OBJ_SIZE; vdi_index = pos / SD_DATA_OBJ_SIZE;
offset = pos % SD_DATA_OBJ_SIZE; offset = pos % SD_DATA_OBJ_SIZE;
data_len = MIN(size, SD_DATA_OBJ_SIZE); data_len = MIN(remaining, SD_DATA_OBJ_SIZE);
vmstate_oid = vid_to_vmstate_oid(s->inode.vdi_id, vdi_index); vmstate_oid = vid_to_vmstate_oid(s->inode.vdi_id, vdi_index);
@@ -1993,9 +1993,9 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
} }
pos += data_len; pos += data_len;
size -= data_len; remaining -= data_len;
ret += data_len;
} }
ret = size;
cleanup: cleanup:
closesocket(fd); closesocket(fd);
return ret; return ret;

7
configure vendored
View File

@@ -2811,7 +2811,11 @@ fi
open_by_hande_at=no open_by_hande_at=no
cat > $TMPC << EOF cat > $TMPC << EOF
#include <fcntl.h> #include <fcntl.h>
#if !defined(AT_EMPTY_PATH)
# error missing definition
#else
int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); } int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
#endif
EOF EOF
if compile_prog "" "" ; then if compile_prog "" "" ; then
open_by_handle_at=yes open_by_handle_at=yes
@@ -2915,7 +2919,8 @@ if test "$softmmu" = yes ; then
tools="$tools fsdev/virtfs-proxy-helper\$(EXESUF)" tools="$tools fsdev/virtfs-proxy-helper\$(EXESUF)"
else else
if test "$virtfs" = yes; then if test "$virtfs" = yes; then
feature_not_found "virtfs" echo "VirtFS is supported only on Linux and requires libcap-devel and libattr-devel"
exit 1
fi fi
virtfs=no virtfs=no
fi fi

3
exec.c
View File

@@ -1492,7 +1492,8 @@ void tb_invalidate_phys_addr(target_phys_addr_t addr)
static void breakpoint_invalidate(CPUArchState *env, target_ulong pc) static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
{ {
tb_invalidate_phys_addr(cpu_get_phys_page_debug(env, pc)); tb_invalidate_phys_addr(cpu_get_phys_page_debug(env, pc) |
(pc & ~TARGET_PAGE_MASK));
} }
#endif #endif
#endif /* TARGET_HAS_ICE */ #endif /* TARGET_HAS_ICE */

View File

@@ -159,6 +159,10 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t track, uint8_t sect,
drv->sect = sect; drv->sect = sect;
} }
if (drv->bs == NULL || !bdrv_is_inserted(drv->bs)) {
ret = 2;
}
return ret; return ret;
} }

View File

@@ -462,7 +462,7 @@ static void ahci_check_cmd_bh(void *opaque)
static void ahci_init_d2h(AHCIDevice *ad) static void ahci_init_d2h(AHCIDevice *ad)
{ {
uint8_t init_fis[0x20]; uint8_t init_fis[20];
IDEState *ide_state = &ad->port.ifs[0]; IDEState *ide_state = &ad->port.ifs[0];
memset(init_fis, 0, sizeof(init_fis)); memset(init_fis, 0, sizeof(init_fis));
@@ -619,7 +619,7 @@ static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis)
d2h_fis[11] = cmd_fis[11]; d2h_fis[11] = cmd_fis[11];
d2h_fis[12] = cmd_fis[12]; d2h_fis[12] = cmd_fis[12];
d2h_fis[13] = cmd_fis[13]; d2h_fis[13] = cmd_fis[13];
for (i = 14; i < 0x20; i++) { for (i = 14; i < 20; i++) {
d2h_fis[i] = 0; d2h_fis[i] = 0;
} }

View File

@@ -84,6 +84,14 @@ static const VMStateDescription vmstate_ahci = {
.unmigratable = 1, .unmigratable = 1,
}; };
static void pci_ich9_reset(void *opaque)
{
struct AHCIPCIState *d = opaque;
msi_reset(&d->card);
ahci_reset(opaque);
}
static int pci_ich9_ahci_init(PCIDevice *dev) static int pci_ich9_ahci_init(PCIDevice *dev)
{ {
struct AHCIPCIState *d; struct AHCIPCIState *d;
@@ -102,7 +110,7 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
/* XXX Software should program this register */ /* XXX Software should program this register */
d->card.config[0x90] = 1 << 6; /* Address Map Register - AHCI mode */ d->card.config[0x90] = 1 << 6; /* Address Map Register - AHCI mode */
qemu_register_reset(ahci_reset, d); qemu_register_reset(pci_ich9_reset, d);
msi_init(dev, 0x50, 1, true, false); msi_init(dev, 0x50, 1, true, false);
d->ahci.irq = d->card.irq[0]; d->ahci.irq = d->card.irq[0];
@@ -133,7 +141,7 @@ static int pci_ich9_uninit(PCIDevice *dev)
d = DO_UPCAST(struct AHCIPCIState, card, dev); d = DO_UPCAST(struct AHCIPCIState, card, dev);
msi_uninit(dev); msi_uninit(dev);
qemu_unregister_reset(ahci_reset, d); qemu_unregister_reset(pci_ich9_reset, d);
ahci_uninit(&d->ahci); ahci_uninit(&d->ahci);
return 0; return 0;

View File

@@ -1107,6 +1107,9 @@ static void intel_hda_reset(DeviceState *dev)
DeviceState *qdev; DeviceState *qdev;
HDACodecDevice *cdev; HDACodecDevice *cdev;
if (d->msi) {
msi_reset(&d->pci);
}
intel_hda_regs_reset(d); intel_hda_regs_reset(d);
d->wall_base_ns = qemu_get_clock_ns(vm_clock); d->wall_base_ns = qemu_get_clock_ns(vm_clock);

View File

@@ -29,7 +29,7 @@ void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic)
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
int i; int i;
memset(kapic, 0, sizeof(kapic)); memset(kapic, 0, sizeof(*kapic));
kvm_apic_set_reg(kapic, 0x2, s->id << 24); kvm_apic_set_reg(kapic, 0x2, s->id << 24);
kvm_apic_set_reg(kapic, 0x8, s->tpr); kvm_apic_set_reg(kapic, 0x8, s->tpr);
kvm_apic_set_reg(kapic, 0xd, s->log_dest << 24); kvm_apic_set_reg(kapic, 0xd, s->log_dest << 24);

View File

@@ -23,31 +23,63 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include "qemu-timer.h" #include "qemu-timer.h"
#include "sysemu.h"
#include "hw/i8254.h" #include "hw/i8254.h"
#include "hw/i8254_internal.h" #include "hw/i8254_internal.h"
#include "kvm.h" #include "kvm.h"
#define KVM_PIT_REINJECT_BIT 0 #define KVM_PIT_REINJECT_BIT 0
#define CALIBRATION_ROUNDS 3
typedef struct KVMPITState { typedef struct KVMPITState {
PITCommonState pit; PITCommonState pit;
LostTickPolicy lost_tick_policy; LostTickPolicy lost_tick_policy;
bool state_valid;
} KVMPITState; } KVMPITState;
static void kvm_pit_get(PITCommonState *s) static int64_t abs64(int64_t v)
{ {
return v < 0 ? -v : v;
}
static void kvm_pit_get(PITCommonState *pit)
{
KVMPITState *s = DO_UPCAST(KVMPITState, pit, pit);
struct kvm_pit_state2 kpit; struct kvm_pit_state2 kpit;
struct kvm_pit_channel_state *kchan; struct kvm_pit_channel_state *kchan;
struct PITChannelState *sc; struct PITChannelState *sc;
int64_t offset, clock_offset;
struct timespec ts;
int i, ret; int i, ret;
if (s->state_valid) {
return;
}
/*
* Measure the delta between CLOCK_MONOTONIC, the base used for
* kvm_pit_channel_state::count_load_time, and vm_clock. Take the
* minimum of several samples to filter out scheduling noise.
*/
clock_offset = INT64_MAX;
for (i = 0; i < CALIBRATION_ROUNDS; i++) {
offset = qemu_get_clock_ns(vm_clock);
clock_gettime(CLOCK_MONOTONIC, &ts);
offset -= ts.tv_nsec;
offset -= (int64_t)ts.tv_sec * 1000000000;
if (abs64(offset) < abs64(clock_offset)) {
clock_offset = offset;
}
}
if (kvm_has_pit_state2()) { if (kvm_has_pit_state2()) {
ret = kvm_vm_ioctl(kvm_state, KVM_GET_PIT2, &kpit); ret = kvm_vm_ioctl(kvm_state, KVM_GET_PIT2, &kpit);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "KVM_GET_PIT2 failed: %s\n", strerror(ret)); fprintf(stderr, "KVM_GET_PIT2 failed: %s\n", strerror(ret));
abort(); abort();
} }
s->channels[0].irq_disabled = kpit.flags & KVM_PIT_FLAGS_HPET_LEGACY; pit->channels[0].irq_disabled = kpit.flags & KVM_PIT_FLAGS_HPET_LEGACY;
} else { } else {
/* /*
* kvm_pit_state2 is superset of kvm_pit_state struct, * kvm_pit_state2 is superset of kvm_pit_state struct,
@@ -61,7 +93,7 @@ static void kvm_pit_get(PITCommonState *s)
} }
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
kchan = &kpit.channels[i]; kchan = &kpit.channels[i];
sc = &s->channels[i]; sc = &pit->channels[i];
sc->count = kchan->count; sc->count = kchan->count;
sc->latched_count = kchan->latched_count; sc->latched_count = kchan->latched_count;
sc->count_latched = kchan->count_latched; sc->count_latched = kchan->count_latched;
@@ -74,10 +106,10 @@ static void kvm_pit_get(PITCommonState *s)
sc->mode = kchan->mode; sc->mode = kchan->mode;
sc->bcd = kchan->bcd; sc->bcd = kchan->bcd;
sc->gate = kchan->gate; sc->gate = kchan->gate;
sc->count_load_time = kchan->count_load_time; sc->count_load_time = kchan->count_load_time + clock_offset;
} }
sc = &s->channels[0]; sc = &pit->channels[0];
sc->next_transition_time = sc->next_transition_time =
pit_get_next_transition_time(sc, sc->count_load_time); pit_get_next_transition_time(sc, sc->count_load_time);
} }
@@ -173,6 +205,19 @@ static void kvm_pit_irq_control(void *opaque, int n, int enable)
kvm_pit_put(pit); kvm_pit_put(pit);
} }
static void kvm_pit_vm_state_change(void *opaque, int running,
RunState state)
{
KVMPITState *s = opaque;
if (running) {
s->state_valid = false;
} else {
kvm_pit_get(&s->pit);
s->state_valid = true;
}
}
static int kvm_pit_initfn(PITCommonState *pit) static int kvm_pit_initfn(PITCommonState *pit)
{ {
KVMPITState *s = DO_UPCAST(KVMPITState, pit, pit); KVMPITState *s = DO_UPCAST(KVMPITState, pit, pit);
@@ -215,6 +260,8 @@ static int kvm_pit_initfn(PITCommonState *pit)
qdev_init_gpio_in(&pit->dev.qdev, kvm_pit_irq_control, 1); qdev_init_gpio_in(&pit->dev.qdev, kvm_pit_irq_control, 1);
qemu_add_vm_change_state_handler(kvm_pit_vm_state_change, s);
return 0; return 0;
} }

View File

@@ -52,7 +52,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
{ {
PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev); PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev);
PCIBridgeDev *bridge_dev = DO_UPCAST(PCIBridgeDev, bridge, br); PCIBridgeDev *bridge_dev = DO_UPCAST(PCIBridgeDev, bridge, br);
int err; int err, ret;
pci_bridge_map_irq(br, NULL, pci_bridge_dev_map_irq_fn); pci_bridge_map_irq(br, NULL, pci_bridge_dev_map_irq_fn);
err = pci_bridge_initfn(dev); err = pci_bridge_initfn(dev);
if (err) { if (err) {
@@ -86,6 +86,8 @@ slotid_error:
shpc_cleanup(dev, &bridge_dev->bar); shpc_cleanup(dev, &bridge_dev->bar);
shpc_error: shpc_error:
memory_region_destroy(&bridge_dev->bar); memory_region_destroy(&bridge_dev->bar);
ret = pci_bridge_exitfn(dev);
assert(!ret);
bridge_error: bridge_error:
return err; return err;
} }

View File

@@ -20,6 +20,7 @@
#include "qdev.h" #include "qdev.h"
#include "monitor.h" #include "monitor.h"
#include "qmp-commands.h" #include "qmp-commands.h"
#include "arch_init.h"
/* /*
* Aliases were a bad idea from the start. Let's keep them * Aliases were a bad idea from the start. Let's keep them
@@ -29,16 +30,18 @@ typedef struct QDevAlias
{ {
const char *typename; const char *typename;
const char *alias; const char *alias;
uint32_t arch_mask;
} QDevAlias; } QDevAlias;
static const QDevAlias qdev_alias_table[] = { static const QDevAlias qdev_alias_table[] = {
{ "virtio-blk-pci", "virtio-blk" }, { "virtio-blk-pci", "virtio-blk", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
{ "virtio-net-pci", "virtio-net" }, { "virtio-net-pci", "virtio-net", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
{ "virtio-serial-pci", "virtio-serial" }, { "virtio-serial-pci", "virtio-serial", QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
{ "virtio-balloon-pci", "virtio-balloon" }, { "virtio-balloon-pci", "virtio-balloon",
{ "virtio-blk-s390", "virtio-blk" }, QEMU_ARCH_ALL & ~QEMU_ARCH_S390X },
{ "virtio-net-s390", "virtio-net" }, { "virtio-blk-s390", "virtio-blk", QEMU_ARCH_S390X },
{ "virtio-serial-s390", "virtio-serial" }, { "virtio-net-s390", "virtio-net", QEMU_ARCH_S390X },
{ "virtio-serial-s390", "virtio-serial", QEMU_ARCH_S390X },
{ "lsi53c895a", "lsi" }, { "lsi53c895a", "lsi" },
{ "ich9-ahci", "ahci" }, { "ich9-ahci", "ahci" },
{ } { }
@@ -50,6 +53,11 @@ static const char *qdev_class_get_alias(DeviceClass *dc)
int i; int i;
for (i = 0; qdev_alias_table[i].typename; i++) { for (i = 0; qdev_alias_table[i].typename; i++) {
if (qdev_alias_table[i].arch_mask &&
!(qdev_alias_table[i].arch_mask & arch_type)) {
continue;
}
if (strcmp(qdev_alias_table[i].typename, typename) == 0) { if (strcmp(qdev_alias_table[i].typename, typename) == 0) {
return qdev_alias_table[i].alias; return qdev_alias_table[i].alias;
} }
@@ -110,6 +118,11 @@ static const char *find_typename_by_alias(const char *alias)
int i; int i;
for (i = 0; qdev_alias_table[i].alias; i++) { for (i = 0; qdev_alias_table[i].alias; i++) {
if (qdev_alias_table[i].arch_mask &&
!(qdev_alias_table[i].arch_mask & arch_type)) {
continue;
}
if (strcmp(qdev_alias_table[i].alias, alias) == 0) { if (strcmp(qdev_alias_table[i].alias, alias) == 0) {
return qdev_alias_table[i].typename; return qdev_alias_table[i].typename;
} }

View File

@@ -150,6 +150,7 @@ int qdev_init(DeviceState *dev)
rc = dc->init(dev); rc = dc->init(dev);
if (rc < 0) { if (rc < 0) {
object_unparent(OBJECT(dev));
qdev_free(dev); qdev_free(dev);
return rc; return rc;
} }

View File

@@ -781,6 +781,13 @@ static inline dma_addr_t rtl8139_addr64(uint32_t low, uint32_t high)
#endif #endif
} }
/* Workaround for buggy guest driver such as linux who allocates rx
* rings after the receiver were enabled. */
static bool rtl8139_cp_rx_valid(RTL8139State *s)
{
return !(s->RxRingAddrLO == 0 && s->RxRingAddrHI == 0);
}
static int rtl8139_can_receive(VLANClientState *nc) static int rtl8139_can_receive(VLANClientState *nc)
{ {
RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque; RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;
@@ -791,18 +798,15 @@ static int rtl8139_can_receive(VLANClientState *nc)
return 1; return 1;
if (!rtl8139_receiver_enabled(s)) if (!rtl8139_receiver_enabled(s))
return 1; return 1;
/* network/host communication happens only in normal mode */
if ((s->Cfg9346 & Chip9346_op_mask) != Cfg9346_Normal)
return 0;
if (rtl8139_cp_receiver_enabled(s)) { if (rtl8139_cp_receiver_enabled(s) && rtl8139_cp_rx_valid(s)) {
/* ??? Flow control not implemented in c+ mode. /* ??? Flow control not implemented in c+ mode.
This is a hack to work around slirp deficiencies anyway. */ This is a hack to work around slirp deficiencies anyway. */
return 1; return 1;
} else { } else {
avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr, avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr,
s->RxBufferSize); s->RxBufferSize);
return (avail == 0 || avail >= 1514); return (avail == 0 || avail >= 1514 || (s->IntrMask & RxOverflow));
} }
} }
@@ -836,12 +840,6 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
return -1; return -1;
} }
/* check whether we are in normal mode */
if ((s->Cfg9346 & Chip9346_op_mask) != Cfg9346_Normal) {
DPRINTF("not in normal op mode\n");
return -1;
}
/* XXX: check this */ /* XXX: check this */
if (s->RxConfig & AcceptAllPhys) { if (s->RxConfig & AcceptAllPhys) {
/* promiscuous: receive all */ /* promiscuous: receive all */
@@ -946,6 +944,10 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
if (rtl8139_cp_receiver_enabled(s)) if (rtl8139_cp_receiver_enabled(s))
{ {
if (!rtl8139_cp_rx_valid(s)) {
return size;
}
DPRINTF("in C+ Rx mode ================\n"); DPRINTF("in C+ Rx mode ================\n");
/* begin C+ receiver mode */ /* begin C+ receiver mode */

View File

@@ -147,9 +147,11 @@ static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s)
static void virtio_blk_handle_scsi(VirtIOBlockReq *req) static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
{ {
#ifdef __linux__
int ret; int ret;
int status = VIRTIO_BLK_S_OK;
int i; int i;
#endif
int status = VIRTIO_BLK_S_OK;
/* /*
* We require at least one output segment each for the virtio_blk_outhdr * We require at least one output segment each for the virtio_blk_outhdr
@@ -489,7 +491,22 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
stw_raw(&blkcfg.min_io_size, s->conf->min_io_size / blk_size); stw_raw(&blkcfg.min_io_size, s->conf->min_io_size / blk_size);
stw_raw(&blkcfg.opt_io_size, s->conf->opt_io_size / blk_size); stw_raw(&blkcfg.opt_io_size, s->conf->opt_io_size / blk_size);
blkcfg.heads = heads; blkcfg.heads = heads;
blkcfg.sectors = secs & ~s->sector_mask; /*
* We must ensure that the block device capacity is a multiple of
* the logical block size. If that is not the case, lets use
* sector_mask to adopt the geometry to have a correct picture.
* For those devices where the capacity is ok for the given geometry
* we dont touch the sector value of the geometry, since some devices
* (like s390 dasd) need a specific value. Here the capacity is already
* cyls*heads*secs*blk_size and the sector value is not block size
* divided by 512 - instead it is the amount of blk_size blocks
* per track (cylinder).
*/
if (bdrv_getlength(s->bs) / heads / secs % blk_size) {
blkcfg.sectors = secs & ~s->sector_mask;
} else {
blkcfg.sectors = secs;
}
blkcfg.size_max = 0; blkcfg.size_max = 0;
blkcfg.physical_block_exp = get_physical_block_exp(s->conf); blkcfg.physical_block_exp = get_physical_block_exp(s->conf);
blkcfg.alignment_offset = 0; blkcfg.alignment_offset = 0;

View File

@@ -537,6 +537,15 @@ static void blk_bh(void *opaque)
blk_handle_requests(blkdev); blk_handle_requests(blkdev);
} }
/*
* We need to account for the grant allocations requiring contiguous
* chunks; the worst case number would be
* max_req * max_seg + (max_req - 1) * (max_seg - 1) + 1,
* but in order to keep things simple just use
* 2 * max_req * max_seg.
*/
#define MAX_GRANTS(max_req, max_seg) (2 * (max_req) * (max_seg))
static void blk_alloc(struct XenDevice *xendev) static void blk_alloc(struct XenDevice *xendev)
{ {
struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev); struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
@@ -548,6 +557,11 @@ static void blk_alloc(struct XenDevice *xendev)
if (xen_mode != XEN_EMULATE) { if (xen_mode != XEN_EMULATE) {
batch_maps = 1; batch_maps = 1;
} }
if (xc_gnttab_set_max_grants(xendev->gnttabdev,
MAX_GRANTS(max_requests, BLKIF_MAX_SEGMENTS_PER_REQUEST)) < 0) {
xen_be_printf(xendev, 0, "xc_gnttab_set_max_grants failed: %s\n",
strerror(errno));
}
} }
static int blk_init(struct XenDevice *xendev) static int blk_init(struct XenDevice *xendev)

View File

@@ -57,7 +57,13 @@ int setenv(const char *name, const char *value, int overwrite)
static BOOL WINAPI qemu_ctrl_handler(DWORD type) static BOOL WINAPI qemu_ctrl_handler(DWORD type)
{ {
exit(STATUS_CONTROL_C_EXIT); qemu_system_shutdown_request();
/* Windows 7 kills application when the function returns.
Sleep here to give QEMU a try for closing.
Sleep period is 10000ms because Windows kills the program
after 10 seconds anyway. */
Sleep(10000);
return TRUE; return TRUE;
} }

View File

@@ -232,6 +232,29 @@ to grow.
@end table @end table
@item qed
Image format with support for backing files and compact image files (when your
filesystem or transport medium does not support holes). Good performance due
to less metadata than the more featureful qcow2 format, especially with
cache=writethrough or cache=directsync. Consider using qcow2 which will soon
have a similar optimization and is most actively developed.
Supported options:
@table @code
@item backing_file
File name of a base image (see @option{create} subcommand).
@item backing_fmt
Image file format of backing file (optional). Useful if the format cannot be
autodetected because it has no header, like some vhd/vpc files.
@item cluster_size
Changes the cluster size (must be power-of-2 between 4K and 64K). Smaller
cluster sizes can improve the image file size whereas larger cluster sizes
generally provide better performance.
@item table_size
Changes the number of clusters per L1/L2 table (must be power-of-2 between 1
and 16). There is normally no need to change this value but this option can be
used for performance benchmarking.
@end table
@item qcow @item qcow
Old QEMU image format. Left for compatibility. Old QEMU image format. Left for compatibility.

View File

@@ -337,6 +337,9 @@ static void readline_completion(ReadLineState *rs)
} }
readline_show_prompt(rs); readline_show_prompt(rs);
} }
for (i = 0; i < rs->nb_completions; i++) {
g_free(rs->completions[i]);
}
} }
/* return true if command handled */ /* return true if command handled */

View File

@@ -370,9 +370,12 @@ void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb,
uint32_t *vpn, uint32_t wi, uint32_t *ei); uint32_t *vpn, uint32_t wi, uint32_t *ei);
int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb, int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb,
uint32_t *pwi, uint32_t *pei, uint8_t *pring); uint32_t *pwi, uint32_t *pei, uint8_t *pring);
void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env,
xtensa_tlb_entry *entry, bool dtlb,
unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte);
void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb, void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte); unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte);
int xtensa_get_physical_addr(CPUXtensaState *env, int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
uint32_t vaddr, int is_write, int mmu_idx, uint32_t vaddr, int is_write, int mmu_idx,
uint32_t *paddr, uint32_t *page_size, unsigned *access); uint32_t *paddr, uint32_t *page_size, unsigned *access);
void reset_mmu(CPUXtensaState *env); void reset_mmu(CPUXtensaState *env);

View File

@@ -135,11 +135,11 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUXtensaState *env, target_ulong add
uint32_t page_size; uint32_t page_size;
unsigned access; unsigned access;
if (xtensa_get_physical_addr(env, addr, 0, 0, if (xtensa_get_physical_addr(env, false, addr, 0, 0,
&paddr, &page_size, &access) == 0) { &paddr, &page_size, &access) == 0) {
return paddr; return paddr;
} }
if (xtensa_get_physical_addr(env, addr, 2, 0, if (xtensa_get_physical_addr(env, false, addr, 2, 0,
&paddr, &page_size, &access) == 0) { &paddr, &page_size, &access) == 0) {
return paddr; return paddr;
} }
@@ -448,30 +448,48 @@ static bool is_access_granted(unsigned access, int is_write)
} }
} }
static int autorefill_mmu(CPUXtensaState *env, uint32_t vaddr, bool dtlb, static int get_pte(CPUXtensaState *env, uint32_t vaddr, uint32_t *pte);
uint32_t *wi, uint32_t *ei, uint8_t *ring);
static int get_physical_addr_mmu(CPUXtensaState *env, static int get_physical_addr_mmu(CPUXtensaState *env, bool update_tlb,
uint32_t vaddr, int is_write, int mmu_idx, uint32_t vaddr, int is_write, int mmu_idx,
uint32_t *paddr, uint32_t *page_size, unsigned *access) uint32_t *paddr, uint32_t *page_size, unsigned *access,
bool may_lookup_pt)
{ {
bool dtlb = is_write != 2; bool dtlb = is_write != 2;
uint32_t wi; uint32_t wi;
uint32_t ei; uint32_t ei;
uint8_t ring; uint8_t ring;
uint32_t vpn;
uint32_t pte;
const xtensa_tlb_entry *entry = NULL;
xtensa_tlb_entry tmp_entry;
int ret = xtensa_tlb_lookup(env, vaddr, dtlb, &wi, &ei, &ring); int ret = xtensa_tlb_lookup(env, vaddr, dtlb, &wi, &ei, &ring);
if ((ret == INST_TLB_MISS_CAUSE || ret == LOAD_STORE_TLB_MISS_CAUSE) && if ((ret == INST_TLB_MISS_CAUSE || ret == LOAD_STORE_TLB_MISS_CAUSE) &&
(mmu_idx != 0 || ((vaddr ^ env->sregs[PTEVADDR]) & 0xffc00000)) && may_lookup_pt && get_pte(env, vaddr, &pte) == 0) {
autorefill_mmu(env, vaddr, dtlb, &wi, &ei, &ring) == 0) { ring = (pte >> 4) & 0x3;
wi = 0;
split_tlb_entry_spec_way(env, vaddr, dtlb, &vpn, wi, &ei);
if (update_tlb) {
wi = ++env->autorefill_idx & 0x3;
xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, pte);
env->sregs[EXCVADDR] = vaddr;
qemu_log("%s: autorefill(%08x): %08x -> %08x\n",
__func__, vaddr, vpn, pte);
} else {
xtensa_tlb_set_entry_mmu(env, &tmp_entry, dtlb, wi, ei, vpn, pte);
entry = &tmp_entry;
}
ret = 0; ret = 0;
} }
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
const xtensa_tlb_entry *entry = if (entry == NULL) {
xtensa_tlb_get_entry(env, dtlb, wi, ei); entry = xtensa_tlb_get_entry(env, dtlb, wi, ei);
}
if (ring < mmu_idx) { if (ring < mmu_idx) {
return dtlb ? return dtlb ?
@@ -494,30 +512,21 @@ static int get_physical_addr_mmu(CPUXtensaState *env,
return 0; return 0;
} }
static int autorefill_mmu(CPUXtensaState *env, uint32_t vaddr, bool dtlb, static int get_pte(CPUXtensaState *env, uint32_t vaddr, uint32_t *pte)
uint32_t *wi, uint32_t *ei, uint8_t *ring)
{ {
uint32_t paddr; uint32_t paddr;
uint32_t page_size; uint32_t page_size;
unsigned access; unsigned access;
uint32_t pt_vaddr = uint32_t pt_vaddr =
(env->sregs[PTEVADDR] | (vaddr >> 10)) & 0xfffffffc; (env->sregs[PTEVADDR] | (vaddr >> 10)) & 0xfffffffc;
int ret = get_physical_addr_mmu(env, pt_vaddr, 0, 0, int ret = get_physical_addr_mmu(env, false, pt_vaddr, 0, 0,
&paddr, &page_size, &access); &paddr, &page_size, &access, false);
qemu_log("%s: trying autorefill(%08x) -> %08x\n", __func__, qemu_log("%s: trying autorefill(%08x) -> %08x\n", __func__,
vaddr, ret ? ~0 : paddr); vaddr, ret ? ~0 : paddr);
if (ret == 0) { if (ret == 0) {
uint32_t vpn; *pte = ldl_phys(paddr);
uint32_t pte = ldl_phys(paddr);
*ring = (pte >> 4) & 0x3;
*wi = (++env->autorefill_idx) & 0x3;
split_tlb_entry_spec_way(env, vaddr, dtlb, &vpn, *wi, ei);
xtensa_tlb_set_entry(env, dtlb, *wi, *ei, vpn, pte);
qemu_log("%s: autorefill(%08x): %08x -> %08x\n",
__func__, vaddr, vpn, pte);
} }
return ret; return ret;
} }
@@ -553,13 +562,13 @@ static int get_physical_addr_region(CPUXtensaState *env,
* *
* \return 0 if ok, exception cause code otherwise * \return 0 if ok, exception cause code otherwise
*/ */
int xtensa_get_physical_addr(CPUXtensaState *env, int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
uint32_t vaddr, int is_write, int mmu_idx, uint32_t vaddr, int is_write, int mmu_idx,
uint32_t *paddr, uint32_t *page_size, unsigned *access) uint32_t *paddr, uint32_t *page_size, unsigned *access)
{ {
if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
return get_physical_addr_mmu(env, vaddr, is_write, mmu_idx, return get_physical_addr_mmu(env, update_tlb,
paddr, page_size, access); vaddr, is_write, mmu_idx, paddr, page_size, access, true);
} else if (xtensa_option_bits_enabled(env->config, } else if (xtensa_option_bits_enabled(env->config,
XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) | XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |
XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION))) { XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION))) {

View File

@@ -79,7 +79,7 @@ void tlb_fill(CPUXtensaState *env1, target_ulong vaddr, int is_write, int mmu_id
uint32_t paddr; uint32_t paddr;
uint32_t page_size; uint32_t page_size;
unsigned access; unsigned access;
int ret = xtensa_get_physical_addr(env, vaddr, is_write, mmu_idx, int ret = xtensa_get_physical_addr(env, true, vaddr, is_write, mmu_idx,
&paddr, &page_size, &access); &paddr, &page_size, &access);
qemu_log("%s(%08x, %d, %d) -> %08x, ret = %d\n", __func__, qemu_log("%s(%08x, %d, %d) -> %08x, ret = %d\n", __func__,
@@ -103,7 +103,7 @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
uint32_t paddr; uint32_t paddr;
uint32_t page_size; uint32_t page_size;
unsigned access; unsigned access;
int ret = xtensa_get_physical_addr(env, vaddr, 2, 0, int ret = xtensa_get_physical_addr(env, false, vaddr, 2, 0,
&paddr, &page_size, &access); &paddr, &page_size, &access);
if (ret == 0) { if (ret == 0) {
tb_invalidate_phys_addr(paddr); tb_invalidate_phys_addr(paddr);
@@ -655,6 +655,16 @@ uint32_t HELPER(ptlb)(uint32_t v, uint32_t dtlb)
} }
} }
void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env,
xtensa_tlb_entry *entry, bool dtlb,
unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte)
{
entry->vaddr = vpn;
entry->paddr = pte & xtensa_tlb_get_addr_mask(env, dtlb, wi);
entry->asid = (env->sregs[RASID] >> ((pte >> 1) & 0x18)) & 0xff;
entry->attr = pte & 0xf;
}
void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb, void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte) unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte)
{ {
@@ -665,10 +675,8 @@ void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
if (entry->asid) { if (entry->asid) {
tlb_flush_page(env, entry->vaddr); tlb_flush_page(env, entry->vaddr);
} }
entry->vaddr = vpn; xtensa_tlb_set_entry_mmu(env, entry, dtlb, wi, ei, vpn, pte);
entry->paddr = pte & xtensa_tlb_get_addr_mask(env, dtlb, wi); tlb_flush_page(env, entry->vaddr);
entry->asid = (env->sregs[RASID] >> ((pte >> 1) & 0x18)) & 0xff;
entry->attr = pte & 0xf;
} else { } else {
qemu_log("%s %d, %d, %d trying to set immutable entry\n", qemu_log("%s %d, %d, %d trying to set immutable entry\n",
__func__, dtlb, wi, ei); __func__, dtlb, wi, ei);

View File

@@ -388,6 +388,7 @@ static bool gen_check_loop_end(DisasContext *dc, int slot)
dc->next_pc == dc->lend) { dc->next_pc == dc->lend) {
int label = gen_new_label(); int label = gen_new_label();
gen_advance_ccount(dc);
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);
tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1); tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);
gen_jumpi(dc, dc->lbeg, slot); gen_jumpi(dc, dc->lbeg, slot);
@@ -410,6 +411,7 @@ static void gen_brcond(DisasContext *dc, TCGCond cond,
{ {
int label = gen_new_label(); int label = gen_new_label();
gen_advance_ccount(dc);
tcg_gen_brcond_i32(cond, t0, t1, label); tcg_gen_brcond_i32(cond, t0, t1, label);
gen_jumpi_check_loop_end(dc, 0); gen_jumpi_check_loop_end(dc, 0);
gen_set_label(label); gen_set_label(label);

View File

@@ -293,26 +293,219 @@ test store_prohibited
assert eq, a2, a3 assert eq, a2, a3
test_end test_end
test dtlb_autoload /* Set up page table entry vaddr->paddr, ring=pte_ring, attr=pte_attr
set_vector kernel, 0 * and DTLB way 7 to cover this PTE, ring=pt_ring, attr=pt_attr
*/
movi a2, 0xd4000000 .macro pt_setup pt_ring, pt_attr, pte_ring, vaddr, paddr, pte_attr
movi a2, 0x80000000
wsr a2, ptevaddr wsr a2, ptevaddr
movi a3, 0x00001013
s32i a3, a2, 4 movi a3, 0x80000007 | (((\vaddr) >> 10) & 0xfffff000) /* way 7 */
movi a4, 0x04000003 | ((\pt_ring) << 4) /* PADDR 64M */
wdtlb a4, a3
isync
movi a3, ((\paddr) & 0xfffff000) | ((\pte_ring) << 4) | (\pte_attr)
movi a1, ((\vaddr) >> 12) << 2
add a2, a1, a2
s32i a3, a2, 0
movi a3, 0x80000007 | (((\vaddr) >> 10) & 0xfffff000) /* way 7 */
movi a4, 0x04000000 | ((\pt_ring) << 4) | (\pt_attr) /* PADDR 64M */
wdtlb a4, a3
isync
movi a3, (\vaddr)
.endm
/* out: PS.RING=ring, PS.EXCM=excm, a3=vaddr */
.macro go_ring ring, excm, vaddr
movi a3, 10f
pitlb a3, a3
ritlb1 a2, a3
movi a1, 0x10
or a2, a2, a1
movi a1, 0x000ff000
and a3, a3, a1
movi a1, 4
or a3, a3, a1
witlb a2, a3
movi a3, 10f
movi a1, 0x000fffff
and a1, a3, a1
movi a2, 0
wsr a2, excvaddr
movi a3, \vaddr
movi a2, 0x4000f | ((\ring) << 6) | ((\excm) << 4)
jx a1
10:
wsr a2, ps
isync
.endm
/* in: a3 -- virtual address to test */
.macro assert_auto_tlb
movi a2, 0x4000f
wsr a2, ps
isync
pdtlb a2, a3
movi a1, 0xfffff01f
and a2, a2, a1
movi a1, 0xfffff000
and a1, a1, a3
xor a1, a1, a2
assert gei, a1, 0x10
movi a2, 0x14
assert lt, a1, a2
.endm
/* in: a3 -- virtual address to test */
.macro assert_no_auto_tlb
movi a2, 0x4000f
wsr a2, ps
isync
pdtlb a2, a3 pdtlb a2, a3
movi a1, 0x10 movi a1, 0x10
and a1, a1, a2 and a1, a1, a2
assert eqi, a1, 0 assert eqi, a1, 0
.endm
.macro assert_sr sr, v
rsr a2, \sr
movi a1, (\v)
assert eq, a1, a2
.endm
.macro assert_epc1_1m vaddr
movi a2, (\vaddr)
movi a1, 0xfffff
and a1, a1, a2
rsr a2, epc1
assert eq, a1, a2
.endm
test dtlb_autoload
set_vector kernel, 0
pt_setup 0, 3, 1, 0x1000, 0x1000, 3
assert_no_auto_tlb
l8ui a1, a3, 0 l8ui a1, a3, 0
pdtlb a2, a3
movi a1, 0xfffff010 rsr a2, excvaddr
and a1, a1, a2 assert eq, a2, a3
movi a3, 0x00001010
assert eq, a1, a3 assert_auto_tlb
movi a1, 0xf test_end
and a1, a1, a2
assert lti, a1, 4 test autoload_load_store_privilege
set_vector kernel, 0
set_vector double, 2f
pt_setup 0, 3, 0, 0x2000, 0x2000, 3
movi a3, 0x2004
assert_no_auto_tlb
movi a2, 0x4005f /* ring 1 + excm => cring == 0 */
wsr a2, ps
isync
1:
l32e a2, a3, -4 /* ring used */
test_fail
2:
rsr a2, excvaddr
addi a1, a3, -4
assert eq, a1, a2
assert_auto_tlb
assert_sr depc, 1b
assert_sr exccause, 26
test_end
test autoload_pte_load_prohibited
set_vector kernel, 2f
pt_setup 0, 3, 0, 0x3000, 0, 0xc
assert_no_auto_tlb
1:
l32i a2, a3, 0
test_fail
2:
rsr a2, excvaddr
assert eq, a2, a3
assert_auto_tlb
assert_sr epc1, 1b
assert_sr exccause, 28
test_end
test autoload_pt_load_prohibited
set_vector kernel, 2f
pt_setup 0, 0xc, 0, 0x4000, 0x4000, 3
assert_no_auto_tlb
1:
l32i a2, a3, 0
test_fail
2:
rsr a2, excvaddr
assert eq, a2, a3
assert_no_auto_tlb
assert_sr epc1, 1b
assert_sr exccause, 24
test_end
test autoload_pt_privilege
set_vector kernel, 2f
pt_setup 0, 3, 1, 0x5000, 0, 3
go_ring 1, 0, 0x5001
l8ui a2, a3, 0
1:
syscall
2:
rsr a2, excvaddr
assert eq, a2, a3
assert_auto_tlb
assert_epc1_1m 1b
assert_sr exccause, 1
test_end
test autoload_pte_privilege
set_vector kernel, 2f
pt_setup 0, 3, 0, 0x6000, 0, 3
go_ring 1, 0, 0x6001
1:
l8ui a2, a3, 0
syscall
2:
rsr a2, excvaddr
assert eq, a2, a3
assert_auto_tlb
assert_epc1_1m 1b
assert_sr exccause, 26
test_end
test autoload_3_level_pt
set_vector kernel, 2f
pt_setup 1, 3, 1, 0x00400000, 0, 3
pt_setup 1, 3, 1, 0x80001000, 0x2000000, 3
go_ring 1, 0, 0x00400001
1:
l8ui a2, a3, 0
syscall
2:
rsr a2, excvaddr
assert eq, a2, a3
assert_no_auto_tlb
assert_epc1_1m 1b
assert_sr exccause, 24
test_end test_end
test_suite_end test_suite_end

View File

@@ -161,8 +161,11 @@ static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3,
} }
timestamp = get_clock(); timestamp = get_clock();
#if GLIB_CHECK_VERSION(2, 30, 0)
idx = g_atomic_int_add((gint *)&trace_idx, 1) % TRACE_BUF_LEN;
#else
idx = g_atomic_int_exchange_and_add((gint *)&trace_idx, 1) % TRACE_BUF_LEN; idx = g_atomic_int_exchange_and_add((gint *)&trace_idx, 1) % TRACE_BUF_LEN;
#endif
trace_buf[idx] = (TraceRecord){ trace_buf[idx] = (TraceRecord){
.event = event, .event = event,
.timestamp_ns = timestamp, .timestamp_ns = timestamp,