Compare commits

...

59 Commits

Author SHA1 Message Date
Michael Roth db51dfc1fc Update version for 2.5.1.1 release
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com
2016-05-09 11:55:58 -05:00
Michael S. Tsirkin 5b7236f725 cadence_uart: bounds check write offset
cadence_uart_init() initializes an I/O memory region of size 0x1000
bytes.  However in uart_write(), the 'offset' parameter (offset within
region) is divided by 4 and then used to index the array 'r' of size
CADENCE_UART_R_MAX which is much smaller: (0x48/4).  If 'offset>>=2'
exceeds CADENCE_UART_R_MAX, this will cause an out-of-bounds memory
write where the offset and the value are controlled by guest.

This will corrupt QEMU memory, in most situations this causes the vm to
crash.

Fix by checking the offset against the array size.

Cc: qemu-stable@nongnu.org
Reported-by: 李强 <liqiang6-s@360.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
Message-id: 20160418100735.GA517@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 5eb0b194e9)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-05-09 11:55:58 -05:00
Gerd Hoffmann 0bcdb632f8 Revert "ehci: make idt processing more robust"
This reverts commit 156a2e4dbf.

Breaks FreeBSD.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit a49923d283)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-05-08 22:37:18 -05:00
Gerd Hoffmann 706bab670b ehci: apply limit to iTD/sidt descriptors
Commit "156a2e4 ehci: make idt processing more robust" tries to avoid a
DoS by the guest (create a circular iTD queue and let qemu ehci
emulation run in circles forever).  Unfortunately this has two problems:
First it misses the case of siTDs, and second it reportedly breaks
FreeBSD.

So lets go for a different approach: just count the number of iTDs and
siTDs we have seen per frame and apply a limit.  That should really
catch all cases now.

Reported-by: 杜少博 <dushaobo@360.cn>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 1ae3f2f178)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-05-08 22:37:09 -05:00
Gerd Hoffmann 44b86aa32e vga: make sure vga register setup for vbe stays intact (CVE-2016-3712).
Call vbe_update_vgaregs() when the guest touches GFX, SEQ or CRT
registers, to make sure the vga registers will always have the
values needed by vbe mode.  This makes sure the sanity checks
applied by vbe_fixup_regs() are effective.

Without this guests can muck with shift_control, can turn on planar
vga modes or text mode emulation while VBE is active, making qemu
take code paths meant for CGA compatibility, but with the very
large display widths and heigts settable using VBE registers.

Which is good for one or another buffer overflow.  Not that
critical as they typically read overflows happening somewhere
in the display code.  So guests can DoS by crashing qemu with a
segfault, but it is probably not possible to break out of the VM.

Fixes: CVE-2016-3712
Reported-by: Zuozhi Fzz <zuozhi.fzz@alibaba-inc.com>
Reported-by: P J P <ppandit@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-05-08 20:56:43 -05:00
Gerd Hoffmann a6e5e5dd4b vga: update vga register setup on vbe changes
Call the new vbe_update_vgaregs() function on vbe configuration
changes, to make sure vga registers are up-to-date.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-05-08 20:56:40 -05:00
Gerd Hoffmann 2f2f74e87c vga: factor out vga register setup
When enabling vbe mode qemu will setup a bunch of vga registers to make
sure the vga emulation operates in correct mode for a linear
framebuffer.  Move that code to a separate function so we can call it
from other places too.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-05-08 20:56:38 -05:00
Gerd Hoffmann 46aff2c7e9 vga: add vbe_enabled() helper
Makes code a bit easier to read.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-05-08 20:56:34 -05:00
Gerd Hoffmann 4f0323d26c vga: fix banked access bounds checking (CVE-2016-3710)
vga allows banked access to video memory using the window at 0xa00000
and it supports a different access modes with different address
calculations.

The VBE bochs extentions support banked access too, using the
VBE_DISPI_INDEX_BANK register.  The code tries to take the different
address calculations into account and applies different limits to
VBE_DISPI_INDEX_BANK depending on the current access mode.

Which is probably effective in stopping misprogramming by accident.
But from a security point of view completely useless as an attacker
can easily change access modes after setting the bank register.

Drop the bogus check, add range checks to vga_mem_{readb,writeb}
instead.

Fixes: CVE-2016-3710
Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-05-08 20:56:30 -05:00
Michael Roth a58047f7fb Update version for 2.5.1 release
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-29 15:47:56 -05:00
Denis V. Lunev 5f409b108f hyperv: cpu hotplug fix with HyperV enabled
With Hyper-V enabled CPU hotplug stops working. The CPU appears
in device manager on Windows but does not appear in peformance
monitor and control panel.

The root of the problem is the following. Windows checks
HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE bit in CPUID. The
presence of this bit is enough to cure the situation.

The bit should be set when CPU hotplug is allowed for HyperV VM.
The check that hot_add_cpu callback is defined is enough from the
protocol point of view. Though this callback is defined almost
always thus there is no need to export that knowledge in the
other way.

Signed-off-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Richard Henderson <rth@twiddle.net>
CC: Eduardo Habkost <ehabkost@redhat.com>
CC: "Andreas Färber" <afaerber@suse.de>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit 4467c6c118)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 18:02:30 -05:00
Fam Zheng 078de11898 vmdk: Fix converting to streamOptimized
Commit d62d9dc4b8 lifted streamOptimized images's version to 3, but we
now refuse to open version 3 images read-write.  We need to make
streamOptimized an exception to allow converting to it. This fixes the
accidentally broken iotests case 059 for the same reason.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 3db1d98a20)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:41:10 -05:00
Fam Zheng acea76c162 vmdk: Create streamOptimized as version 3
VMware products accept only version 3 for streamOptimized, let's bump
the version.

Reported-by: Radoslav Gerganov <rgerganov@vmware.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit d62d9dc4b8)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:41:04 -05:00
Prasad J Pandit 80b6e5723f usb: check USB configuration descriptor object
When processing remote NDIS control message packets, the USB Net
device emulator checks to see if the USB configuration descriptor
object is of RNDIS type(2). But it does not check if it is null,
which leads to a null dereference error. Add check to avoid it.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1455188480-14688-1-git-send-email-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 80eecda8e5)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:56 -05:00
Prasad J Pandit 9bddb45dbc usb: check RNDIS message length
When processing remote NDIS control message packets, the USB Net
device emulator uses a fixed length(4096) data buffer. The incoming
packet length could exceed this limit. Add a check to avoid it.

Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1455648821-17340-2-git-send-email-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 64c9bc181f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:52 -05:00
Prasad J Pandit e3a2cdfcb5 usb: check RNDIS buffer offsets & length
When processing remote NDIS control message packets,
the USB Net device emulator uses a fixed length(4096) data buffer.
The incoming informationBufferOffset & Length combination could
overflow and cross that range. Check control message buffer
offsets and length to avoid it.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1455648821-17340-3-git-send-email-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit fe3c546c5f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:46 -05:00
Prasad J Pandit 4dcd2f13b1 usb: check page select value while processing iTD
While processing isochronous transfer descriptors(iTD), the page
select(PG) field value could lead to an OOB read access. Add
check to avoid it.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1453233406-12165-1-git-send-email-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 49d925ce50)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:40 -05:00
Prasad J Pandit 38e09211b6 net: ne2000: fix bounds check in ioport operations
While doing ioport r/w operations, ne2000 device emulation suffers
from OOB r/w errors. Update respective array bounds check to avoid
OOB access.

Reported-by: Ling Liu <liuling-it@360.cn>
Cc: qemu-stable@nongnu.org
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit aa7f9966df)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:34 -05:00
Prasad J Pandit d0ee85b4e4 net: check packet payload length
While computing IP checksum, 'net_checksum_calculate' reads
payload length from the packet. It could exceed the given 'data'
buffer size. Add a check to avoid it.

Reported-by: Liu Ling <liuling-it@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 362786f14a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:27 -05:00
Prasad J Pandit 4f046a6ba1 ide: ahci: reset ncq object to unused on error
When processing NCQ commands, AHCI device emulation prepares a
NCQ transfer object; To which an aio control block(aiocb) object
is assigned in 'execute_ncq_command'. In case, when the NCQ
command is invalid, the 'aiocb' object is not assigned, and NCQ
transfer object is left as 'used'. This leads to a use after
free kind of error in 'bdrv_aio_cancel_async' via 'ahci_reset_port'.
Reset NCQ transfer object to 'unused' to avoid it.

[Maintainer edit: s/ACHI/AHCI/ in the commit message. --js]

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 1452282511-4116-1-git-send-email-ppandit@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 4ab0359a8a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:40:20 -05:00
P J P b47809c6b3 i386: avoid null pointer dereference
Hello,

A null pointer dereference issue was reported by Mr Ling Liu, CC'd here. It
occurs while doing I/O port write operations via hmp interface. In that,
'current_cpu' remains null as it is not called from cpu_exec loop, which
results in the said issue.

Below is a proposed (tested)patch to fix this issue; Does it look okay?

===
From ae88a4947fab9a148cd794f8ad2d812e7f5a1d0f Mon Sep 17 00:00:00 2001
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Fri, 18 Dec 2015 11:16:07 +0530
Subject: [PATCH] i386: avoid null pointer dereference

When I/O port write operation is called from hmp interface,
'current_cpu' remains null, as it is not called from cpu_exec()
loop. This leads to a null pointer dereference in vapic_write
routine. Add check to avoid it.

Reported-by: Ling Liu <liuling-it@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <alpine.LFD.2.20.1512181129320.9805@wniryva>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: P J P <ppandit@redhat.com>
(cherry picked from commit 4c1396cb57)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:39:27 -05:00
Wolfgang Bumiller 24fe899c3c hmp: fix sendkey out of bounds write (CVE-2015-8619)
When processing 'sendkey' command, hmp_sendkey routine null
terminates the 'keyname_buf' array. This results in an OOB
write issue, if 'keyname_len' was to fall outside of
'keyname_buf' array.

Since the keyname's length is known the keyname_buf can be
removed altogether by adding a length parameter to
index_from_key() and using it for the error output as well.

Reported-by: Ling Liu <liuling-it@360.cn>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Message-Id: <20160113080958.GA18934@olga>
[Comparison with "<" dumbed down, test for junk after strtoul()
tweaked]
Signed-off-by: Markus Armbruster <armbru@redhat.com>

(cherry picked from commit 64ffbe04ea)

Conflicts:
	hmp.c

*removed dependency on 7fb1cf16

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:38:16 -05:00
John Snow aaf4fb6afb ahci: Do not unmap NULL addresses
Definitely don't try to unmap a garbage address.

Reported-by: Zuozhi fzz <zuozhi.fzz@alibaba-inc.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Message-id: 1454103689-13042-2-git-send-email-jsnow@redhat.com
(cherry picked from commit 99b4cb7106)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:35:36 -05:00
Greg Kurz a2ae168821 migration: allow machine to enforce configuration section migration
Migration of pseries-2.3 doesn't have configuration section. Unfortunately,
QEMU 2.4/2.4.1/2.5 are buggy and always stream and expect the configuration
section, and break migration both ways.

This patch introduces a property which allows to enforce a configuration
section for machines who don't have one.

It can be set at startup:

-machine enforce-config-section=on

or later from the QEMU monitor:

qom-set /machine enforce-config-section on

It is up to the tooling to set or unset this property according to the
version of the QEMU at the other end of the pipe.

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 902c053d83)

Conflicts:
	qemu-options.hx

* removed context dependency on 87252e1b
* added to provide 2.5<->2.5.1 migration compat option for
  pseries-2.3 machines

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-22 17:20:12 -05:00
Marcel Apfelbaum bad094d524 vl.c: Fix regression in machine error message
Commit e1ce0c3cb (vl.c: fix regression when reading machine type
from config file) fixed the error message when the machine type
was supplied inside the config file. However now the option name
is not displayed correctly if the error happens when the machine
is specified at command line.

Running
    ./x86_64-softmmu/qemu-system-x86_64 -M q35-1.5 -redir tcp:8022::22
will result in the error message:
    qemu-system-x86_64: -redir tcp:8022::22: unsupported machine type
    Use -machine help to list supported machines

Fixed it by restoring the error location and also extracted the code
dealing with machine options into a separate function.

Reported-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <1455303747-19776-2-git-send-email-ehabkost@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit 34f405ae6d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 18:21:32 -05:00
Alberto Garcia 4b0b1ec8e0 quorum: Fix crash in quorum_aio_cb()
quorum_aio_cb() emits the QUORUM_REPORT_BAD event if there's
an I/O error in a Quorum child. However sacb->aiocb must be
correctly initialized for this to happen. read_quorum_children() and
read_fifo_child() are not doing this, which results in a QEMU crash.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 8138570d071ba7e25db3736979234a1fd71dbd05.1457610443.git.berto@igalia.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit b9c600d207)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 18:18:19 -05:00
Peter Maydell cab1cc7245 target-arm: Make reserved ranges in ID_AA64* spaces RAZ, not UNDEF
The v8 ARM ARM defines that unused spaces in the ID_AA64* system
register ranges are Reserved and must RAZ, rather than being UNDEF.
Implement this.

In particular, ARM v8.2 adds a new feature register ID_AA64MMFR2,
and newer versions of the Linux kernel will attempt to read this,
which causes them not to boot up on versions of QEMU missing this fix.

Since the encoding .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6
is actually defined in ARMv8 (as ID_MMFR4), we give it an entry in
the ARMCPU struct so CPUs can override it, though since none do
this too will just RAZ.

Cc: qemu-stable@nongnu.org
Reported-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1455890863-11203-1-git-send-email-peter.maydell@linaro.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
(cherry picked from commit e20d84c140)

Conflicts:
	target-arm/helper.c

* remove context dep on 4054bfa9

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 17:48:45 -05:00
Michael S. Tsirkin 9ae02175b4 vhost-user: don't merge regions with different fds
vhost currently merges regions with contiguious virtual and physical
addresses.  This breaks for vhost-user since that also needs fds to
match.

Add a vhost_ops entry to compare the fds for vhost-user only.

Cc: qemu-stable@nongnu.org
Cc: Victor Kaplansky <victork@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit ffe42cc14c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 17:36:07 -05:00
Laszlo Ersek 30929793b0 fw_cfg: unbreak migration compatibility for 2.4 and earlier machines
When I reviewed Marc's fw_cfg DMA patches, I completely missed that the
way we set dma_enabled would break migration.

Gerd explained the right way (see reference below): dma_enabled should be
set to true by default, and only true->false transitions should be
possible:

- when the user requests that with

    -global fw_cfg_mem.dma_enabled=off

  or

   -global fw_cfg_io.dma_enabled=off

  as appropriate for the platform,

- when HW_COMPAT_2_4 dictates it,

- when board code initializes fw_cfg without requesting DMA support.

Cc: Marc Marí <markmb@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Alexandre DERUMIER <aderumier@odiso.com>
Cc: qemu-stable@nongnu.org
Ref: http://thread.gmane.org/gmane.comp.emulators.qemu/390272/focus=391042
Ref: https://bugs.launchpad.net/qemu/+bug/1536487
Suggested-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-id: 1455823860-22268-1-git-send-email-lersek@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit e6915b5f3a)

Conflicts:
	include/hw/compat.h

* remove cosmetic dep on c9c0afbb

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 17:33:59 -05:00
Marcel Apfelbaum c5c9841ce8 hw/virtio: group virtio flags into an enum
Minimizes the possibility to assign
the same bit to different features.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit fc1769b758)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 17:25:13 -05:00
Marcel Apfelbaum 6b62303eb8 hw/virtio: fix double use of a virtio flag
Commits 1811e64c and a6df8adf use the same virtio feature bit 4
for different features.

Fix it by using different bits.

Reported-by: Laurent Vivier <lvivier@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 631a438755)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 17:24:57 -05:00
Greg Kurz c06f342009 spapr: skip configuration section during migration of older machines
Since QEMU 2.4, we have a configuration section in the migration stream.
This must be skipped for older machines, like it is already done for x86.

This patch fixes the migration of pseries-2.3 from/to QEMU 2.3, but it
breaks migration of the same machine from/to QEMU 2.4/2.4.1/2.5. We do
that anyway because QEMU 2.3 is likely to be more widely deployed than
newer QEMU versions.

Fixes: 61964c23e5
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 09b5e30da5)

Conflicts:
	hw/ppc/spapr.c

*remove dep on 5013c5474

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 17:17:33 -05:00
Laszlo Ersek cb873eaa6d e1000: eliminate infinite loops on out-of-bounds transfer start
The start_xmit() and e1000_receive_iov() functions implement DMA transfers
iterating over a set of descriptors that the guest's e1000 driver
prepares:

- the TDLEN and RDLEN registers store the total size of the descriptor
  area,

- while the TDH and RDH registers store the offset (in whole tx / rx
  descriptors) into the area where the transfer is supposed to start.

Each time a descriptor is processed, the TDH and RDH register is bumped
(as appropriate for the transfer direction).

QEMU already contains logic to deal with bogus transfers submitted by the
guest:

- Normally, the transmit case wants to increase TDH from its initial value
  to TDT. (TDT is allowed to be numerically smaller than the initial TDH
  value; wrapping at or above TDLEN bytes to zero is normal.) The failsafe
  that QEMU currently has here is a check against reaching the original
  TDH value again -- a complete wraparound, which should never happen.

- In the receive case RDH is increased from its initial value until
  "total_size" bytes have been received; preferably in a single step, or
  in "s->rxbuf_size" byte steps, if the latter is smaller. However, null
  RX descriptors are skipped without receiving data, while RDH is
  incremented just the same. QEMU tries to prevent an infinite loop
  (processing only null RX descriptors) by detecting whether RDH assumes
  its original value during the loop. (Again, wrapping from RDLEN to 0 is
  normal.)

What both directions miss is that the guest could program TDLEN and RDLEN
so low, and the initial TDH and RDH so high, that these registers will
immediately be truncated to zero, and then never reassume their initial
values in the loop -- a full wraparound will never occur.

The condition that expresses this is:

  xdh_start >= s->mac_reg[XDLEN] / sizeof(desc)

i.e., TDH or RDH start out after the last whole rx or tx descriptor that
fits into the TDLEN or RDLEN sized area.

This condition could be checked before we enter the loops, but
pci_dma_read() / pci_dma_write() knows how to fill in buffers safely for
bogus DMA addresses, so we just extend the existing failsafes with the
above condition.

This is CVE-2016-1981.

Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Petr Matousek <pmatouse@redhat.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Prasad Pandit <ppandit@redhat.com>
Cc: Michael Roth <mdroth@linux.vnet.ibm.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: qemu-stable@nongnu.org
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1296044
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit dd793a7488)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:55:27 -05:00
Jeff Cody 4853a5a80f block: qemu-iotests - add test for snapshot, commit, snapshot bug
Signed-off-by: Jeff Cody <jcody@redhat.com>
Message-id: 2dbc05efba2f683cb3aaf71aaa9b776ebf7ec57c.1454376655.git.jcody@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
[Moved test number from 143 to 144]
Signed-off-by: Max Reitz <mreitz@redhat.com>

(cherry picked from commit 8983b670f6)

Conflicts:
	tests/qemu-iotests/group

*removed context dependencies on newer test groups

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:53:35 -05:00
Jeff Cody a375e0b03e block: set device_list.tqe_prev to NULL on BDS removal
This fixes a regression introduced with commit 3f09bfbc7.  Multiple
bugs arise in conjunction with live snapshots and mirroring operations
(which include active layer commit).

After a live snapshot occurs, the active layer and the base layer both
have a non-NULL tqe_prev field in the device_list, although the base
node's tqe_prev field points to a NULL entry.  This non-NULL tqe_prev
field occurs after the bdrv_append() in the external snapshot calls
change_parent_backing_link().

In change_parent_backing_link(), when the previous active layer is
removed from device_list, the device_list.tqe_prev pointer is not
set to NULL.

The operating scheme in the block layer is to indicate that a BDS belongs
in the bdrv_states device_list iff the device_list.tqe_prev pointer
is non-NULL.

This patch does two things:

1.) Introduces a new block layer helper bdrv_device_remove() to remove a
    BDS from the device_list, and
2.) uses that new API, which also fixes the regression once used in
    change_parent_backing_link().

Signed-off-by: Jeff Cody <jcody@redhat.com>
Message-id: 0cd51e11c0666c04ddb7c05293fe94afeb551e89.1454376655.git.jcody@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit f8aa905a4f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:51:48 -05:00
Eric Blake a38a283fc7 qmp: Fix reference-counting of qnull on empty output visit
Commit 6c2f9a15 ensured that we would not return NULL when the
caller used an output visitor but had nothing to visit. But
in doing so, it added a FIXME about a reference count leak
that could abort qemu in the (unlikely) case of SIZE_MAX such
visits (more plausible on 32-bit).  (Although that commit
suggested we might fix it in time for 2.5, we ran out of time;
fortunately, it is unlikely enough to bite that it was not
worth worrying about during the 2.5 release.)

This fixes things by documenting the internal contracts, and
explaining why the internal function can return NULL and only
the public facing interface needs to worry about qnull(),
thus avoiding over-referencing the qnull_ global object.

It does not, however, fix the stupidity of the stack mixing
up two separate pieces of information; add a FIXME to explain
that issue, which will be fixed shortly in a future patch.

Signed-off-by: Eric Blake <eblake@redhat.com>
Cc: qemu-stable@nongnu.org
Message-Id: <1454075341-13658-25-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit a861564015)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:50:34 -05:00
Dr. David Alan Gilbert 225d50fbb1 cpus: use broadcast on qemu_pause_cond
Jiri saw a hang on pause_all_vcpus called from postcopy_start,
where the cpus are all apparently stopped ('stopped' flag set)
but pause_all_vcpus is still stuck on a cond_wait on qemu_paused_cond.
We suspect this is happening if a qmp_stop is called at about the
same time as the postcopy code calls that pause_all_vcpus;
although they both should have the main lock held, Paolo spotted
the cond_wait unlocks the global lock so perhaps they both
could end up waiting at the same time?

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reported-by: Jiri Denemark <jdenemar@redhat.com>
Message-Id: <1453716498-27238-1-git-send-email-dgilbert@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 96bce6831b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:47:04 -05:00
Gabriel L. Somlo 020282d3e6 fw_cfg: avoid calculating invalid current entry pointer
When calculating a pointer to the currently selected fw_cfg item, the
following is used:

  FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];

When s->cur_entry is FW_CFG_INVALID, we are calculating the address of
a non-existent element in s->entries[arch][...], which is undefined.

This patch ensures the resulting entry pointer is set to NULL whenever
s->cur_entry is FW_CFG_INVALID.

Reported-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Message-id: 1446733972-1602-5-git-send-email-somlo@cmu.edu
Cc: Marc Marí <markmb@redhat.com>
Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 66f8fd9dda)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:45:24 -05:00
Halil Pasic 091af18104 s390x/css: fix control flags during csch
From the beginning, css support contained an error in csch handling:
instead of setting the clear bit in the function control bits twice, we
need to set the clear pending bit in the activity control bits. Let's
fix this.

Cc: qemu-stable@nongnu.org
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
(cherry picked from commit 4c6bf79a22)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:42:26 -05:00
Pierre Morel d98392379a s390x/ioinst: set type and len for SEI response
If no event information is pending, the return code
is set to 0x0005 and the length of the response is
set to 8 bytes.

Signed-off-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Song Shan Gong <gongss@linux.vnet.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
(cherry picked from commit f70202be53)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:42:13 -05:00
Christian Borntraeger 643c8d8ec1 block/raw-posix: avoid bogus fixup for cylinders on DASD disks
large volume DASD that have > 64k cylinders do claim to have
0xFFFE cylinders as special value in the old 16 bit field. We
want to pass this "token" along to the guest, instead of
calculating the real number. Otherwise qemu might fail with
"cyls must be between 1 and 65535"

Cc: qemu-stable@nongnu.org
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 972b543c6b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:41:43 -05:00
Gerd Hoffmann 3ede27db32 ehci: update irq on reset
After clearing the status register we also have to update the irq line
status.  Otherwise a irq which happends to be pending at reset time
causes a interrupt storm.  And the guest can't stop as the status
register doesn't indicate any pending interrupt.

Both NetBSD and FreeBSD hang on shutdown because of that.

Cc: qemu-stable@nongnu.org
Reported-by: Andrey Korolyov <andrey@xdel.ru>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1453203884-4125-1-git-send-email-kraxel@redhat.com
(cherry picked from commit 5a8660741a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:41:14 -05:00
Laurent Vivier 9849b1912f net: set endianness on all backend devices
commit 5be7d9f1b1
       vhost-net: tell tap backend about the vnet endianness

makes vhost net to set the endianness of the device, but only for
the first device.

In case of multiqueue, we have multiple devices... This patch sets the
endianness for all the devices of the interface.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit a407644079)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:36:19 -05:00
Prasad J Pandit fe90bdc25b net: ne2000: check ring buffer control registers
Ne2000 NIC uses ring buffer of NE2000_MEM_SIZE(49152)
bytes to process network packets. Registers PSTART & PSTOP
define ring buffer size & location. Setting these registers
to invalid values could lead to infinite loop or OOB r/w
access issues. Add check to avoid it.

Reported-by: Yang Hongke <yanghongke@huawei.com>
Tested-by: Yang Hongke <yanghongke@huawei.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 415ab35a44)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:34:56 -05:00
Li Zhijian aaa5271327 net/filter: fix nf->netdev_id leak
Cc: Jason Wang <jasowang@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 671f66f87f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:34:23 -05:00
Li Zhijian abda95cb01 net/dump: fix nfds->filename leak
Cc: Jason Wang <jasowang@redhat.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit b50c7d452f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:34:15 -05:00
Max Reitz 6a49a71cc6 blockdev: Fix 'change' for slot devices
'change' and related operations did not work when used on guest devices
featuring removable media but no actual tray, because
blk_dev_is_tray_open() always returned false for them and the
blockdev-{insert,remove}-medium commands required it to return true.

Fix this by making blockdev-{insert,remove}-medium work on tray-less
devices. Also, blockdev-{open,close}-tray are now explicitly no-ops when
invoked on such devices, and blk_dev_change_media_cb() is instead
called by blockdev-{insert,remove}-medium (for tray-less devices only).

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Message-id: 1454096953-31773-3-git-send-email-mreitz@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 12c7ec87a7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:23:54 -05:00
Max Reitz e1a8a09124 block: Add blk_dev_has_tray()
Pull out the check whether a block device has a tray from
blk_dev_is_tray_open() into its own function so both attributes (whether
there is a tray vs. whether that tray is open) can be queried
independently.

Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Message-id: 1454096953-31773-2-git-send-email-mreitz@redhat.com
(cherry picked from commit 8f3a73bc57)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-17 16:23:28 -05:00
Prasad J Pandit 7a2c1c8e66 net: rocker: fix an incorrect array bounds check
While processing transmit(tx) descriptors in 'tx_consume' routine
the switch emulator suffers from an off-by-one error, if a
descriptor was to have more than allowed(ROCKER_TX_FRAGS_MAX=16)
fragments. Fix an incorrect bounds check to avoid it.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 007cd223de)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:39:32 -05:00
Marc-André Lureau 702a8d165c ivshmem: remove redundant assignment, fix crash with msi=off
Fix crash when msi=false introduced in 660c97ee (msi_vectors is NULL in
this case)

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit 47213eb110)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:35:51 -05:00
Marc-André Lureau 3e96d5dcf2 ivshmem: no need for opaque argument
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit 2c64846972)
*context dependency for 47213eb
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:35:25 -05:00
P J P 16a2875735 scsi: initialise info object with appropriate size
While processing controller 'CTRL_GET_INFO' command, the routine
'megasas_ctrl_get_info' overflows the '&info' object size. Use its
appropriate size to null initialise it.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <alpine.LFD.2.20.1512211501420.22471@wniryva>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: P J P <ppandit@redhat.com>
(cherry picked from commit 36fef36b91)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:21:11 -05:00
Greg Kurz 4588b0d856 virtio-9p: use accessor to get thread_pool
The aio_context_new() function does not allocate a thread pool. This is
deferred to the first call to the aio_get_thread_pool() accessor. It is
hence forbidden to access the thread_pool field directly, as it may be
NULL. The accessor *must* be used always.

Fixes: ebac1202c9
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Tested-by: Michael Tokarev <mjt@tls.msk.ru>
Cc: qemu-stable@nongnu.org
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
(cherry picked from commit 4b3a4f2d45)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:20:55 -05:00
Stefano Stabellini ff083d3c3b xenfb: avoid reading twice the same fields from the shared page
Reading twice the same field could give the guest an attack of
opportunity. In the case of event->type, gcc could compile the switch
statement into a jump table, effectively ending up reading the type
field multiple times.

This is part of XSA-155.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
(cherry picked from commit 7ea11bf376)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:20:35 -05:00
Stefano Stabellini 4d59e78dfe xen/blkif: Avoid double access to src->nr_segments
src is stored in shared memory and src->nr_segments is dereferenced
twice at the end of the function.  If a compiler decides to compile this
into two separate memory accesses then the size limitation could be
bypassed.

Fix it by removing the double access to src->nr_segments.

This is part of XSA-155.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
(cherry picked from commit f9e98e5d7a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:20:17 -05:00
Peter Maydell 52a7b27947 configure: Fix shell syntax to placate OpenBSD's pdksh
Unfortunately the OpenBSD pdksh does not like brackets inside
the right part of a ${variable+word} parameter expansion:

  $ echo "${a+($b)}"
  ksh: ${a+($b)}": bad substitution

though both bash and dash accept them. In any case this line
was causing odd output in the case where nettle is not present:
  nettle    no ()

(because if nettle is not present then $nettle will be "no",
not a null string or unset).

Rewrite it to just use an if.

This bug was originally introduced in becaeb726 and was present
in the 2.4.0 release.

Fixes: https://bugs.launchpad.net/qemu/+bug/1525682
Reported-by: Dmitrij D. Czarkoff
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1450105357-8516-1-git-send-email-peter.maydell@linaro.org
(cherry picked from commit 18f49881cf)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:19:47 -05:00
Greg Kurz d4aed70099 target-ppc: kvm: fix floating point registers sync on little-endian hosts
On VSX capable CPUs, the 32 FP registers are mapped to the high-bits
of the 32 first VSX registers. So if you have:

VSR31 = (uint128) 0x0102030405060708090a0b0c0d0e0f00

then

FPR31 = (uint64) 0x0102030405060708

The kernel stores the VSX registers in the fp_state struct following the
host endian element ordering.

On big-endian:

fp_state.fpr[31][0] = 0x0102030405060708
fp_state.fpr[31][1] = 0x090a0b0c0d0e0f00

On little-endian:

fp_state.fpr[31][0] = 0x090a0b0c0d0e0f00
fp_state.fpr[31][1] = 0x0102030405060708

The KVM_GET_ONE_REG and KVM_SET_ONE_REG ioctls preserve this ordering, but
QEMU considers it as big-endian and always copies element [0] to the
fpr[] array and element [1] to the vsr[] array. This does not work with
little-endian hosts, and you will get:

(qemu) p $f31
0x90a0b0c0d0e0f00

instead of:

(qemu) p $f31
0x102030405060708

This patch fixes the element ordering for little-endian hosts.

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 3a4b791b4c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:10:47 -05:00
P J P 42ae4a3c61 net: vmxnet3: avoid memory leakage in activate_device
Vmxnet3 device emulator does not check if the device is active
before activating it, also it did not free the transmit & receive
buffers while deactivating the device, thus resulting in memory
leakage on the host. This patch fixes both these issues to avoid
host memory leakage.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Cc: qemu-stable@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit aa4a3dce1c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:08:24 -05:00
Gerd Hoffmann 0d335804e3 ehci: make idt processing more robust
Make ehci_process_itd return an error in case we didn't do any actual
iso transfer because we've found no active transaction.  That'll avoid
ehci happily run in circles forever if the guest builds a loop out of
idts.

This is CVE-2015-8558.

Cc: qemu-stable@nongnu.org
Reported-by: Qinghao Tang <luodalongde@gmail.com>
Tested-by: P J P <ppandit@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 156a2e4dbf)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-03-15 12:07:11 -05:00
58 changed files with 741 additions and 209 deletions

View File

@ -1 +1 @@
2.5.0
2.5.1.1

24
block.c
View File

@ -1976,21 +1976,25 @@ void bdrv_close_all(void)
}
}
/* Note that bs->device_list.tqe_prev is initially null,
* and gets set to non-null by QTAILQ_INSERT_TAIL(). Establish
* the useful invariant "bs in bdrv_states iff bs->tqe_prev" by
* resetting it to null on remove. */
void bdrv_device_remove(BlockDriverState *bs)
{
QTAILQ_REMOVE(&bdrv_states, bs, device_list);
bs->device_list.tqe_prev = NULL;
}
/* make a BlockDriverState anonymous by removing from bdrv_state and
* graph_bdrv_state list.
Also, NULL terminate the device_name to prevent double remove */
void bdrv_make_anon(BlockDriverState *bs)
{
/*
* Take care to remove bs from bdrv_states only when it's actually
* in it. Note that bs->device_list.tqe_prev is initially null,
* and gets set to non-null by QTAILQ_INSERT_TAIL(). Establish
* the useful invariant "bs in bdrv_states iff bs->tqe_prev" by
* resetting it to null on remove.
*/
/* Take care to remove bs from bdrv_states only when it's actually
* in it. */
if (bs->device_list.tqe_prev) {
QTAILQ_REMOVE(&bdrv_states, bs, device_list);
bs->device_list.tqe_prev = NULL;
bdrv_device_remove(bs);
}
if (bs->node_name[0] != '\0') {
QTAILQ_REMOVE(&graph_bdrv_states, bs, node_list);
@ -2031,7 +2035,7 @@ static void change_parent_backing_link(BlockDriverState *from,
if (!to->device_list.tqe_prev) {
QTAILQ_INSERT_BEFORE(from, to, device_list);
}
QTAILQ_REMOVE(&bdrv_states, from, device_list);
bdrv_device_remove(from);
}
}

View File

@ -457,6 +457,14 @@ bool blk_dev_has_removable_media(BlockBackend *blk)
return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb);
}
/*
* Does @blk's attached device model have a tray?
*/
bool blk_dev_has_tray(BlockBackend *blk)
{
return blk->dev_ops && blk->dev_ops->is_tray_open;
}
/*
* Notify @blk's attached device model of a media eject request.
* If @force is true, the medium is about to be yanked out forcefully.
@ -473,7 +481,7 @@ void blk_dev_eject_request(BlockBackend *blk, bool force)
*/
bool blk_dev_is_tray_open(BlockBackend *blk)
{
if (blk->dev_ops && blk->dev_ops->is_tray_open) {
if (blk_dev_has_tray(blk)) {
return blk->dev_ops->is_tray_open(blk->dev_opaque);
}
return false;

View File

@ -646,8 +646,9 @@ static BlockAIOCB *read_quorum_children(QuorumAIOCB *acb)
}
for (i = 0; i < s->num_children; i++) {
bdrv_aio_readv(s->children[i]->bs, acb->sector_num, &acb->qcrs[i].qiov,
acb->nb_sectors, quorum_aio_cb, &acb->qcrs[i]);
acb->qcrs[i].aiocb = bdrv_aio_readv(s->children[i]->bs, acb->sector_num,
&acb->qcrs[i].qiov, acb->nb_sectors,
quorum_aio_cb, &acb->qcrs[i]);
}
return &acb->common;
@ -662,9 +663,10 @@ static BlockAIOCB *read_fifo_child(QuorumAIOCB *acb)
qemu_iovec_init(&acb->qcrs[acb->child_iter].qiov, acb->qiov->niov);
qemu_iovec_clone(&acb->qcrs[acb->child_iter].qiov, acb->qiov,
acb->qcrs[acb->child_iter].buf);
bdrv_aio_readv(s->children[acb->child_iter]->bs, acb->sector_num,
&acb->qcrs[acb->child_iter].qiov, acb->nb_sectors,
quorum_aio_cb, &acb->qcrs[acb->child_iter]);
acb->qcrs[acb->child_iter].aiocb =
bdrv_aio_readv(s->children[acb->child_iter]->bs, acb->sector_num,
&acb->qcrs[acb->child_iter].qiov, acb->nb_sectors,
quorum_aio_cb, &acb->qcrs[acb->child_iter]);
return &acb->common;
}

View File

@ -783,7 +783,6 @@ static int hdev_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
{
BDRVRawState *s = bs->opaque;
struct hd_geometry ioctl_geo = {0};
uint32_t blksize;
/* If DASD, get its geometry */
if (check_for_dasd(s->fd) < 0) {
@ -803,12 +802,6 @@ static int hdev_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
}
geo->heads = ioctl_geo.heads;
geo->sectors = ioctl_geo.sectors;
if (!probe_physical_blocksize(s->fd, &blksize)) {
/* overwrite cyls: HDIO_GETGEO result is incorrect for big drives */
geo->cylinders = bdrv_nb_sectors(bs) / (blksize / BDRV_SECTOR_SIZE)
/ (geo->heads * geo->sectors);
return 0;
}
geo->cylinders = ioctl_geo.cylinders;
return 0;

View File

@ -570,6 +570,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
VmdkExtent *extent;
BDRVVmdkState *s = bs->opaque;
int64_t l1_backup_offset = 0;
bool compressed;
ret = bdrv_pread(file->bs, sizeof(magic), &header, sizeof(header));
if (ret < 0) {
@ -644,6 +645,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
header = footer.header;
}
compressed =
le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
if (le32_to_cpu(header.version) > 3) {
char buf[64];
snprintf(buf, sizeof(buf), "VMDK version %" PRId32,
@ -651,7 +654,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
error_setg(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
bdrv_get_device_or_node_name(bs), "vmdk", buf);
return -ENOTSUP;
} else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR)) {
} else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR) &&
!compressed) {
/* VMware KB 2064959 explains that version 3 added support for
* persistent changed block tracking (CBT), and backup software can
* read it as version=1 if it doesn't care about the changed area
@ -1654,7 +1658,13 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
}
magic = cpu_to_be32(VMDK4_MAGIC);
memset(&header, 0, sizeof(header));
header.version = zeroed_grain ? 2 : 1;
if (compress) {
header.version = 3;
} else if (zeroed_grain) {
header.version = 2;
} else {
header.version = 1;
}
header.flags = VMDK4_FLAG_RGD | VMDK4_FLAG_NL_DETECT
| (compress ? VMDK4_FLAG_COMPRESS | VMDK4_FLAG_MARKER : 0)
| (zeroed_grain ? VMDK4_FLAG_ZERO_GRAIN : 0);

View File

@ -2306,6 +2306,11 @@ void qmp_blockdev_open_tray(const char *device, bool has_force, bool force,
return;
}
if (!blk_dev_has_tray(blk)) {
/* Ignore this command on tray-less devices */
return;
}
if (blk_dev_is_tray_open(blk)) {
return;
}
@ -2336,6 +2341,11 @@ void qmp_blockdev_close_tray(const char *device, Error **errp)
return;
}
if (!blk_dev_has_tray(blk)) {
/* Ignore this command on tray-less devices */
return;
}
if (!blk_dev_is_tray_open(blk)) {
return;
}
@ -2365,7 +2375,7 @@ void qmp_x_blockdev_remove_medium(const char *device, Error **errp)
return;
}
if (has_device && !blk_dev_is_tray_open(blk)) {
if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
error_setg(errp, "Tray of device '%s' is not open", device);
return;
}
@ -2384,12 +2394,19 @@ void qmp_x_blockdev_remove_medium(const char *device, Error **errp)
/* This follows the convention established by bdrv_make_anon() */
if (bs->device_list.tqe_prev) {
QTAILQ_REMOVE(&bdrv_states, bs, device_list);
bs->device_list.tqe_prev = NULL;
bdrv_device_remove(bs);
}
blk_remove_bs(blk);
if (!blk_dev_has_tray(blk)) {
/* For tray-less devices, blockdev-open-tray is a no-op (or may not be
* called at all); therefore, the medium needs to be ejected here.
* Do it after blk_remove_bs() so blk_is_inserted(blk) returns the @load
* value passed here (i.e. false). */
blk_dev_change_media_cb(blk, false);
}
out:
aio_context_release(aio_context);
}
@ -2415,7 +2432,7 @@ static void qmp_blockdev_insert_anon_medium(const char *device,
return;
}
if (has_device && !blk_dev_is_tray_open(blk)) {
if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
error_setg(errp, "Tray of device '%s' is not open", device);
return;
}
@ -2428,6 +2445,15 @@ static void qmp_blockdev_insert_anon_medium(const char *device,
blk_insert_bs(blk, bs);
QTAILQ_INSERT_TAIL(&bdrv_states, bs, device_list);
if (!blk_dev_has_tray(blk)) {
/* For tray-less devices, blockdev-close-tray is a no-op (or may not be
* called at all); therefore, the medium needs to be pushed into the
* slot here.
* Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load
* value passed here (i.e. true). */
blk_dev_change_media_cb(blk, true);
}
}
void qmp_x_blockdev_insert_medium(const char *device, const char *node_name,

6
configure vendored
View File

@ -4758,7 +4758,11 @@ echo "GTK GL support $gtk_gl"
echo "GNUTLS support $gnutls"
echo "GNUTLS hash $gnutls_hash"
echo "libgcrypt $gcrypt"
echo "nettle $nettle ${nettle+($nettle_version)}"
if test "$nettle" = "yes"; then
echo "nettle $nettle ($nettle_version)"
else
echo "nettle $nettle"
fi
echo "libtasn1 $tasn1"
echo "VTE support $vte"
echo "curses support $curses"

4
cpus.c
View File

@ -986,7 +986,7 @@ static void qemu_wait_io_event_common(CPUState *cpu)
if (cpu->stop) {
cpu->stop = false;
cpu->stopped = true;
qemu_cond_signal(&qemu_pause_cond);
qemu_cond_broadcast(&qemu_pause_cond);
}
flush_queued_work(cpu);
cpu->thread_kicked = false;
@ -1387,7 +1387,7 @@ void cpu_stop_current(void)
current_cpu->stop = false;
current_cpu->stopped = true;
cpu_exit(current_cpu);
qemu_cond_signal(&qemu_pause_cond);
qemu_cond_broadcast(&qemu_pause_cond);
}
}

18
hmp.c
View File

@ -1734,21 +1734,18 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
int has_hold_time = qdict_haskey(qdict, "hold-time");
int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
Error *err = NULL;
char keyname_buf[16];
char *separator;
int keyname_len;
while (1) {
separator = strchr(keys, '-');
keyname_len = separator ? separator - keys : strlen(keys);
pstrcpy(keyname_buf, sizeof(keyname_buf), keys);
/* Be compatible with old interface, convert user inputted "<" */
if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) {
pstrcpy(keyname_buf, sizeof(keyname_buf), "less");
if (keys[0] == '<' && keyname_len == 1) {
keys = "less";
keyname_len = 4;
}
keyname_buf[keyname_len] = 0;
keylist = g_malloc0(sizeof(*keylist));
keylist->value = g_malloc0(sizeof(*keylist->value));
@ -1761,16 +1758,17 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
}
tmp = keylist;
if (strstart(keyname_buf, "0x", NULL)) {
if (strstart(keys, "0x", NULL)) {
char *endp;
int value = strtoul(keyname_buf, &endp, 0);
if (*endp != '\0') {
int value = strtoul(keys, &endp, 0);
assert(endp <= keys + keyname_len);
if (endp != keys + keyname_len) {
goto err_out;
}
keylist->value->type = KEY_VALUE_KIND_NUMBER;
keylist->value->u.number = value;
} else {
int idx = index_from_key(keyname_buf);
int idx = index_from_key(keys, keyname_len);
if (idx == Q_KEY_CODE_MAX) {
goto err_out;
}
@ -1792,7 +1790,7 @@ out:
return;
err_out:
monitor_printf(mon, "invalid parameter: %s\n", keyname_buf);
monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys);
goto out;
}

View File

@ -36,6 +36,6 @@ static int coroutine_enter_func(void *arg)
void co_run_in_worker_bh(void *opaque)
{
Coroutine *co = opaque;
thread_pool_submit_aio(qemu_get_aio_context()->thread_pool,
thread_pool_submit_aio(aio_get_thread_pool(qemu_get_aio_context()),
coroutine_enter_func, co, coroutine_enter_cb, co);
}

View File

@ -85,8 +85,10 @@ static inline void blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_reque
d->nr_sectors = s->nr_sectors;
return;
}
if (n > src->nr_segments)
n = src->nr_segments;
/* prevent the compiler from optimizing the code and using src->nr_segments instead */
barrier();
if (n > dst->nr_segments)
n = dst->nr_segments;
for (i = 0; i < n; i++)
dst->seg[i] = src->seg[i];
}
@ -106,8 +108,10 @@ static inline void blkif_get_x86_64_req(blkif_request_t *dst, blkif_x86_64_reque
d->nr_sectors = s->nr_sectors;
return;
}
if (n > src->nr_segments)
n = src->nr_segments;
/* prevent the compiler from optimizing the code and using src->nr_segments instead */
barrier();
if (n > dst->nr_segments)
n = dst->nr_segments;
for (i = 0; i < n; i++)
dst->seg[i] = src->seg[i];
}

View File

@ -374,6 +374,9 @@ static void uart_write(void *opaque, hwaddr offset,
DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value);
offset >>= 2;
if (offset >= CADENCE_UART_R_MAX) {
return;
}
switch (offset) {
case R_IER: /* ier (wts imr) */
s->r[R_IMR] |= value;

View File

@ -283,6 +283,21 @@ static bool machine_get_suppress_vmdesc(Object *obj, Error **errp)
return ms->suppress_vmdesc;
}
static void machine_set_enforce_config_section(Object *obj, bool value,
Error **errp)
{
MachineState *ms = MACHINE(obj);
ms->enforce_config_section = value;
}
static bool machine_get_enforce_config_section(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
return ms->enforce_config_section;
}
static int error_on_sysbus_device(SysBusDevice *sbdev, void *opaque)
{
error_report("Option '-device %s' cannot be handled by this machine",
@ -437,6 +452,12 @@ static void machine_initfn(Object *obj)
object_property_set_description(obj, "suppress-vmdesc",
"Set on to disable self-describing migration",
NULL);
object_property_add_bool(obj, "enforce-config-section",
machine_get_enforce_config_section,
machine_set_enforce_config_section, NULL);
object_property_set_description(obj, "enforce-config-section",
"Set on to enforce configuration section migration",
NULL);
/* Register notifier when init is done for sysbus sanity checks */
ms->sysbus_notifier.notify = machine_init_notify;

View File

@ -140,6 +140,13 @@ static uint32_t expand4[256];
static uint16_t expand2[256];
static uint8_t expand4to8[16];
static void vbe_update_vgaregs(VGACommonState *s);
static inline bool vbe_enabled(VGACommonState *s)
{
return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
}
static void vga_update_memory_access(VGACommonState *s)
{
hwaddr base, offset, size;
@ -177,6 +184,7 @@ static void vga_update_memory_access(VGACommonState *s)
size = 0x8000;
break;
}
assert(offset + size <= s->vram_size);
memory_region_init_alias(&s->chain4_alias, memory_region_owner(&s->vram),
"vga.chain4", &s->vram, offset, size);
memory_region_add_subregion_overlap(s->legacy_address_space, base,
@ -476,6 +484,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
#endif
s->sr[s->sr_index] = val & sr_mask[s->sr_index];
vbe_update_vgaregs(s);
if (s->sr_index == VGA_SEQ_CLOCK_MODE) {
s->update_retrace_info(s);
}
@ -507,6 +516,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
#endif
s->gr[s->gr_index] = val & gr_mask[s->gr_index];
vbe_update_vgaregs(s);
vga_update_memory_access(s);
break;
case VGA_CRT_IM:
@ -525,10 +535,12 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
if (s->cr_index == VGA_CRTC_OVERFLOW) {
s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
(val & 0x10);
vbe_update_vgaregs(s);
}
return;
}
s->cr[s->cr_index] = val;
vbe_update_vgaregs(s);
switch(s->cr_index) {
case VGA_CRTC_H_TOTAL:
@ -561,7 +573,7 @@ static void vbe_fixup_regs(VGACommonState *s)
uint16_t *r = s->vbe_regs;
uint32_t bits, linelength, maxy, offset;
if (!(r[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
if (!vbe_enabled(s)) {
/* vbe is turned off -- nothing to do */
return;
}
@ -636,6 +648,49 @@ static void vbe_fixup_regs(VGACommonState *s)
s->vbe_start_addr = offset / 4;
}
/* we initialize the VGA graphic mode */
static void vbe_update_vgaregs(VGACommonState *s)
{
int h, shift_control;
if (!vbe_enabled(s)) {
/* vbe is turned off -- nothing to do */
return;
}
/* graphic mode + memory map 1 */
s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
VGA_GR06_GRAPHICS_MODE;
s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
/* width */
s->cr[VGA_CRTC_H_DISP] =
(s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
/* height (only meaningful if < 1024) */
h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
s->cr[VGA_CRTC_V_DISP_END] = h;
s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
((h >> 7) & 0x02) | ((h >> 3) & 0x40);
/* line compare to 1023 */
s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
shift_control = 0;
s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
} else {
shift_control = 2;
/* set chain 4 mode */
s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
/* activate all planes */
s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
}
s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
(shift_control << 5);
s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
}
static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
{
VGACommonState *s = opaque;
@ -712,13 +767,10 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
case VBE_DISPI_INDEX_Y_OFFSET:
s->vbe_regs[s->vbe_index] = val;
vbe_fixup_regs(s);
vbe_update_vgaregs(s);
break;
case VBE_DISPI_INDEX_BANK:
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
val &= (s->vbe_bank_mask >> 2);
} else {
val &= s->vbe_bank_mask;
}
val &= s->vbe_bank_mask;
s->vbe_regs[s->vbe_index] = val;
s->bank_offset = (val << 16);
vga_update_memory_access(s);
@ -726,52 +778,19 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
case VBE_DISPI_INDEX_ENABLE:
if ((val & VBE_DISPI_ENABLED) &&
!(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
int h, shift_control;
s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0;
s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
vbe_fixup_regs(s);
vbe_update_vgaregs(s);
/* clear the screen */
if (!(val & VBE_DISPI_NOCLEARMEM)) {
memset(s->vram_ptr, 0,
s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
}
/* we initialize the VGA graphic mode */
/* graphic mode + memory map 1 */
s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
VGA_GR06_GRAPHICS_MODE;
s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
/* width */
s->cr[VGA_CRTC_H_DISP] =
(s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
/* height (only meaningful if < 1024) */
h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
s->cr[VGA_CRTC_V_DISP_END] = h;
s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
((h >> 7) & 0x02) | ((h >> 3) & 0x40);
/* line compare to 1023 */
s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
shift_control = 0;
s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
} else {
shift_control = 2;
/* set chain 4 mode */
s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
/* activate all planes */
s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
}
s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
(shift_control << 5);
s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
} else {
s->bank_offset = 0;
}
@ -817,13 +836,21 @@ uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
/* chain 4 mode : simplest access */
assert(addr < s->vram_size);
ret = s->vram_ptr[addr];
} else if (s->gr[VGA_GFX_MODE] & 0x10) {
/* odd/even mode (aka text mode mapping) */
plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
ret = s->vram_ptr[((addr & ~1) << 1) | plane];
addr = ((addr & ~1) << 1) | plane;
if (addr >= s->vram_size) {
return 0xff;
}
ret = s->vram_ptr[addr];
} else {
/* standard VGA latched access */
if (addr * sizeof(uint32_t) >= s->vram_size) {
return 0xff;
}
s->latch = ((uint32_t *)s->vram_ptr)[addr];
if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
@ -880,6 +907,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
plane = addr & 3;
mask = (1 << plane);
if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
assert(addr < s->vram_size);
s->vram_ptr[addr] = val;
#ifdef DEBUG_VGA_MEM
printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
@ -893,6 +921,9 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
mask = (1 << plane);
if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
addr = ((addr & ~1) << 1) | plane;
if (addr >= s->vram_size) {
return;
}
s->vram_ptr[addr] = val;
#ifdef DEBUG_VGA_MEM
printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
@ -966,6 +997,9 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
mask = s->sr[VGA_SEQ_PLANE_WRITE];
s->plane_updated |= mask; /* only used to detect font change */
write_mask = mask16[mask];
if (addr * sizeof(uint32_t) >= s->vram_size) {
return;
}
((uint32_t *)s->vram_ptr)[addr] =
(((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
(val & write_mask);
@ -1044,7 +1078,7 @@ static void vga_get_offsets(VGACommonState *s,
{
uint32_t start_addr, line_offset, line_compare;
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
if (vbe_enabled(s)) {
line_offset = s->vbe_line_offset;
start_addr = s->vbe_start_addr;
line_compare = 65535;
@ -1369,7 +1403,7 @@ static int vga_get_bpp(VGACommonState *s)
{
int ret;
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
if (vbe_enabled(s)) {
ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
} else {
ret = 0;
@ -1381,7 +1415,7 @@ static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
{
int width, height;
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
if (vbe_enabled(s)) {
width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
} else {

View File

@ -784,18 +784,20 @@ static void xenfb_invalidate(void *opaque)
static void xenfb_handle_events(struct XenFB *xenfb)
{
uint32_t prod, cons;
uint32_t prod, cons, out_cons;
struct xenfb_page *page = xenfb->c.page;
prod = page->out_prod;
if (prod == page->out_cons)
out_cons = page->out_cons;
if (prod == out_cons)
return;
xen_rmb(); /* ensure we see ring contents up to prod */
for (cons = page->out_cons; cons != prod; cons++) {
for (cons = out_cons; cons != prod; cons++) {
union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
uint8_t type = event->type;
int x, y, w, h;
switch (event->type) {
switch (type) {
case XENFB_TYPE_UPDATE:
if (xenfb->up_count == UP_QUEUE)
xenfb->up_fullscreen = 1;

View File

@ -634,13 +634,18 @@ static int vapic_prepare(VAPICROMState *s)
static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
unsigned int size)
{
CPUState *cs = current_cpu;
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
hwaddr rom_paddr;
VAPICROMState *s = opaque;
X86CPU *cpu;
CPUX86State *env;
hwaddr rom_paddr;
cpu_synchronize_state(cs);
if (!current_cpu) {
return;
}
cpu_synchronize_state(current_cpu);
cpu = X86_CPU(current_cpu);
env = &cpu->env;
/*
* The VAPIC supports two PIO-based hypercalls, both via port 0x7E.

View File

@ -661,6 +661,10 @@ static bool ahci_map_fis_address(AHCIDevice *ad)
static void ahci_unmap_fis_address(AHCIDevice *ad)
{
if (ad->res_fis == NULL) {
DPRINTF(ad->port_no, "Attempt to unmap NULL FIS address\n");
return;
}
dma_memory_unmap(ad->hba->as, ad->res_fis, 256,
DMA_DIRECTION_FROM_DEVICE, 256);
ad->res_fis = NULL;
@ -677,6 +681,10 @@ static bool ahci_map_clb_address(AHCIDevice *ad)
static void ahci_unmap_clb_address(AHCIDevice *ad)
{
if (ad->lst == NULL) {
DPRINTF(ad->port_no, "Attempt to unmap NULL CLB address\n");
return;
}
dma_memory_unmap(ad->hba->as, ad->lst, 1024,
DMA_DIRECTION_FROM_DEVICE, 1024);
ad->lst = NULL;
@ -910,6 +918,7 @@ static void ncq_err(NCQTransferState *ncq_tfs)
ide_state->error = ABRT_ERR;
ide_state->status = READY_STAT | ERR_STAT;
ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag);
ncq_tfs->used = 0;
}
static void ncq_finish(NCQTransferState *ncq_tfs)

View File

@ -350,17 +350,14 @@ static void ivshmem_vector_poll(PCIDevice *dev,
}
}
static CharDriverState* create_eventfd_chr_device(void * opaque, EventNotifier *n,
static CharDriverState* create_eventfd_chr_device(IVShmemState *s,
EventNotifier *n,
int vector)
{
/* create a event character device based on the passed eventfd */
IVShmemState *s = opaque;
PCIDevice *pdev = PCI_DEVICE(s);
int eventfd = event_notifier_get_fd(n);
CharDriverState *chr;
s->msi_vectors[vector].pdev = pdev;
chr = qemu_chr_open_eventfd(eventfd);
if (chr == NULL) {

View File

@ -908,7 +908,8 @@ start_xmit(E1000State *s)
* bogus values to TDT/TDLEN.
* there's nothing too intelligent we could do about this.
*/
if (s->mac_reg[TDH] == tdh_start) {
if (s->mac_reg[TDH] == tdh_start ||
tdh_start >= s->mac_reg[TDLEN] / sizeof(desc)) {
DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n",
tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]);
break;
@ -1165,7 +1166,8 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
s->mac_reg[RDH] = 0;
/* see comment in start_xmit; same here */
if (s->mac_reg[RDH] == rdh_start) {
if (s->mac_reg[RDH] == rdh_start ||
rdh_start >= s->mac_reg[RDLEN] / sizeof(desc)) {
DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
set_ics(s, 0, E1000_ICS_RXO);

View File

@ -154,6 +154,10 @@ static int ne2000_buffer_full(NE2000State *s)
{
int avail, index, boundary;
if (s->stop <= s->start) {
return 1;
}
index = s->curpag << 8;
boundary = s->boundary << 8;
if (index < boundary)
@ -467,8 +471,9 @@ static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr,
uint32_t val)
{
addr &= ~1; /* XXX: check exact behaviour if not even */
if (addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
if (addr < 32
|| (addr >= NE2000_PMEM_START
&& addr + sizeof(uint32_t) <= NE2000_MEM_SIZE)) {
stl_le_p(s->mem + addr, val);
}
}
@ -497,8 +502,9 @@ static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr)
static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr)
{
addr &= ~1; /* XXX: check exact behaviour if not even */
if (addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
if (addr < 32
|| (addr >= NE2000_PMEM_START
&& addr + sizeof(uint32_t) <= NE2000_MEM_SIZE)) {
return ldl_le_p(s->mem + addr);
} else {
return 0xffffffff;

View File

@ -232,6 +232,9 @@ static int tx_consume(Rocker *r, DescInfo *info)
frag_addr = rocker_tlv_get_le64(tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR]);
frag_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]);
if (iovcnt >= ROCKER_TX_FRAGS_MAX) {
goto err_too_many_frags;
}
iov[iovcnt].iov_len = frag_len;
iov[iovcnt].iov_base = g_malloc(frag_len);
if (!iov[iovcnt].iov_base) {
@ -244,10 +247,7 @@ static int tx_consume(Rocker *r, DescInfo *info)
err = -ROCKER_ENXIO;
goto err_bad_io;
}
if (++iovcnt > ROCKER_TX_FRAGS_MAX) {
goto err_too_many_frags;
}
iovcnt++;
}
if (iovcnt) {

View File

@ -300,21 +300,19 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
VirtioBusState *vbus = VIRTIO_BUS(qbus);
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
int r, e, i;
int r, e, i, j;
if (!k->set_guest_notifiers) {
error_report("binding does not support guest notifiers");
r = -ENOSYS;
goto err;
return -ENOSYS;
}
r = vhost_net_set_vnet_endian(dev, ncs[0].peer, true);
if (r < 0) {
goto err;
}
for (i = 0; i < total_queues; i++) {
vhost_net_set_vq_index(get_vhost_net(ncs[i].peer), i * 2);
for (j = 0; j < total_queues; j++) {
r = vhost_net_set_vnet_endian(dev, ncs[j].peer, true);
if (r < 0) {
goto err_endian;
}
vhost_net_set_vq_index(get_vhost_net(ncs[j].peer), j * 2);
}
r = k->set_guest_notifiers(qbus->parent, total_queues * 2, true);
@ -343,8 +341,9 @@ err_start:
fflush(stderr);
}
err_endian:
vhost_net_set_vnet_endian(dev, ncs[0].peer, false);
err:
while (--j >= 0) {
vhost_net_set_vnet_endian(dev, ncs[j].peer, false);
}
return r;
}

View File

@ -1194,8 +1194,13 @@ static void vmxnet3_reset_mac(VMXNET3State *s)
static void vmxnet3_deactivate_device(VMXNET3State *s)
{
VMW_CBPRN("Deactivating vmxnet3...");
s->device_active = false;
if (s->device_active) {
VMW_CBPRN("Deactivating vmxnet3...");
vmxnet_tx_pkt_reset(s->tx_pkt);
vmxnet_tx_pkt_uninit(s->tx_pkt);
vmxnet_rx_pkt_uninit(s->rx_pkt);
s->device_active = false;
}
}
static void vmxnet3_reset(VMXNET3State *s)
@ -1204,7 +1209,6 @@ static void vmxnet3_reset(VMXNET3State *s)
vmxnet3_deactivate_device(s);
vmxnet3_reset_interrupt_states(s);
vmxnet_tx_pkt_reset(s->tx_pkt);
s->drv_shmem = 0;
s->tx_sop = true;
s->skip_current_tx_pkt = false;
@ -1431,6 +1435,12 @@ static void vmxnet3_activate_device(VMXNET3State *s)
return;
}
/* Verify if device is active */
if (s->device_active) {
VMW_CFPRN("Vmxnet3 device is active");
return;
}
vmxnet3_adjust_by_guest_type(s);
vmxnet3_update_features(s);
vmxnet3_update_pm_state(s);
@ -1627,7 +1637,7 @@ static void vmxnet3_handle_command(VMXNET3State *s, uint64_t cmd)
break;
case VMXNET3_CMD_QUIESCE_DEV:
VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - pause the device");
VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - deactivate the device");
vmxnet3_deactivate_device(s);
break;
@ -1741,7 +1751,7 @@ vmxnet3_io_bar1_write(void *opaque,
* shared address only after we get the high part
*/
if (val == 0) {
s->device_active = false;
vmxnet3_deactivate_device(s);
}
s->temp_shared_guest_driver_memory = val;
s->drv_shmem = 0;
@ -2021,9 +2031,7 @@ static bool vmxnet3_peer_has_vnet_hdr(VMXNET3State *s)
static void vmxnet3_net_uninit(VMXNET3State *s)
{
g_free(s->mcast_list);
vmxnet_tx_pkt_reset(s->tx_pkt);
vmxnet_tx_pkt_uninit(s->tx_pkt);
vmxnet_rx_pkt_uninit(s->rx_pkt);
vmxnet3_deactivate_device(s);
qemu_del_nic(s->nic);
}

View File

@ -270,7 +270,8 @@ static int fw_cfg_select(FWCfgState *s, uint16_t key)
static uint8_t fw_cfg_read(FWCfgState *s)
{
int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);
FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
FWCfgEntry *e = (s->cur_entry == FW_CFG_INVALID) ? NULL :
&s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
uint8_t ret;
if (s->cur_entry == FW_CFG_INVALID || !e->data || s->cur_offset >= e->len)
@ -338,7 +339,8 @@ static void fw_cfg_dma_transfer(FWCfgState *s)
}
arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);
e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
e = (s->cur_entry == FW_CFG_INVALID) ? NULL :
&s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
if (dma.control & FW_CFG_DMA_CTL_READ) {
read = 1;
@ -780,17 +782,19 @@ FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
DeviceState *dev;
FWCfgState *s;
uint32_t version = FW_CFG_VERSION;
bool dma_enabled = dma_iobase && dma_as;
bool dma_requested = dma_iobase && dma_as;
dev = qdev_create(NULL, TYPE_FW_CFG_IO);
qdev_prop_set_uint32(dev, "iobase", iobase);
qdev_prop_set_uint32(dev, "dma_iobase", dma_iobase);
qdev_prop_set_bit(dev, "dma_enabled", dma_enabled);
if (!dma_requested) {
qdev_prop_set_bit(dev, "dma_enabled", false);
}
fw_cfg_init1(dev);
s = FW_CFG(dev);
if (dma_enabled) {
if (s->dma_enabled) {
/* 64 bits for the address field */
s->dma_as = dma_as;
s->dma_addr = 0;
@ -816,11 +820,13 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
SysBusDevice *sbd;
FWCfgState *s;
uint32_t version = FW_CFG_VERSION;
bool dma_enabled = dma_addr && dma_as;
bool dma_requested = dma_addr && dma_as;
dev = qdev_create(NULL, TYPE_FW_CFG_MEM);
qdev_prop_set_uint32(dev, "data_width", data_width);
qdev_prop_set_bit(dev, "dma_enabled", dma_enabled);
if (!dma_requested) {
qdev_prop_set_bit(dev, "dma_enabled", false);
}
fw_cfg_init1(dev);
@ -830,7 +836,7 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
s = FW_CFG(dev);
if (dma_enabled) {
if (s->dma_enabled) {
s->dma_as = dma_as;
s->dma_addr = 0;
sysbus_mmio_map(sbd, 2, dma_addr);
@ -875,7 +881,7 @@ static Property fw_cfg_io_properties[] = {
DEFINE_PROP_UINT32("iobase", FWCfgIoState, iobase, -1),
DEFINE_PROP_UINT32("dma_iobase", FWCfgIoState, dma_iobase, -1),
DEFINE_PROP_BOOL("dma_enabled", FWCfgIoState, parent_obj.dma_enabled,
false),
true),
DEFINE_PROP_END_OF_LIST(),
};
@ -915,7 +921,7 @@ static const TypeInfo fw_cfg_io_info = {
static Property fw_cfg_mem_properties[] = {
DEFINE_PROP_UINT32("data_width", FWCfgMemState, data_width, -1),
DEFINE_PROP_BOOL("dma_enabled", FWCfgMemState, parent_obj.dma_enabled,
false),
true),
DEFINE_PROP_END_OF_LIST(),
};

View File

@ -2327,6 +2327,7 @@ static void spapr_compat_2_3(Object *obj)
{
savevm_skip_section_footers();
global_state_set_optional();
savevm_skip_configuration();
}
static void spapr_compat_2_2(Object *obj)

View File

@ -701,7 +701,7 @@ int css_do_csch(SubchDev *sch)
/* Trigger the clear function. */
s->ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_CLEAR_FUNC;
s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_ACTL_CLEAR_PEND;
do_subchannel_work(sch, NULL);
ret = 0;

View File

@ -718,7 +718,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
BusChild *kid;
int num_pd_disks = 0;
memset(&info, 0x0, cmd->iov_size);
memset(&info, 0x0, dcmd_size);
if (cmd->iov_size < dcmd_size) {
trace_megasas_dcmd_invalid_xfer_len(cmd->index, cmd->iov_size,
dcmd_size);

View File

@ -128,9 +128,16 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
}
usb_packet_copy(p, s->setup_buf, p->iov.size);
s->setup_index = 0;
p->actual_length = 0;
s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
s->setup_index = 0;
if (s->setup_len > sizeof(s->data_buf)) {
fprintf(stderr,
"usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
s->setup_len, sizeof(s->data_buf));
p->status = USB_RET_STALL;
return;
}
request = (s->setup_buf[0] << 8) | s->setup_buf[1];
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
@ -151,13 +158,6 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
}
s->setup_state = SETUP_STATE_DATA;
} else {
if (s->setup_len > sizeof(s->data_buf)) {
fprintf(stderr,
"usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
s->setup_len, sizeof(s->data_buf));
p->status = USB_RET_STALL;
return;
}
if (s->setup_len == 0)
s->setup_state = SETUP_STATE_ACK;
else
@ -176,7 +176,7 @@ static void do_token_in(USBDevice *s, USBPacket *p)
request = (s->setup_buf[0] << 8) | s->setup_buf[1];
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
index = (s->setup_buf[5] << 8) | s->setup_buf[4];
switch(s->setup_state) {
case SETUP_STATE_ACK:
if (!(s->setup_buf[0] & USB_DIR_IN)) {

View File

@ -653,7 +653,8 @@ typedef struct USBNetState {
static int is_rndis(USBNetState *s)
{
return s->dev.config->bConfigurationValue == DEV_RNDIS_CONFIG_VALUE;
return s->dev.config ?
s->dev.config->bConfigurationValue == DEV_RNDIS_CONFIG_VALUE : 0;
}
static int ndis_query(USBNetState *s, uint32_t oid,
@ -914,8 +915,9 @@ static int rndis_query_response(USBNetState *s,
bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
buflen = le32_to_cpu(buf->InformationBufferLength);
if (bufoffs + buflen > length)
if (buflen > length || bufoffs >= length || bufoffs + buflen > length) {
return USB_RET_STALL;
}
infobuflen = ndis_query(s, le32_to_cpu(buf->OID),
bufoffs + (uint8_t *) buf, buflen, infobuf,
@ -960,8 +962,9 @@ static int rndis_set_response(USBNetState *s,
bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
buflen = le32_to_cpu(buf->InformationBufferLength);
if (bufoffs + buflen > length)
if (buflen > length || bufoffs >= length || bufoffs + buflen > length) {
return USB_RET_STALL;
}
ret = ndis_set(s, le32_to_cpu(buf->OID),
bufoffs + (uint8_t *) buf, buflen);
@ -1211,8 +1214,9 @@ static void usb_net_handle_dataout(USBNetState *s, USBPacket *p)
if (le32_to_cpu(msg->MessageType) == RNDIS_PACKET_MSG) {
uint32_t offs = 8 + le32_to_cpu(msg->DataOffset);
uint32_t size = le32_to_cpu(msg->DataLength);
if (offs + size <= len)
if (offs < len && size < len && offs + size <= len) {
qemu_send_packet(qemu_get_queue(s->nic), s->out_buf + offs, size);
}
}
s->out_ptr -= len;
memmove(s->out_buf, &s->out_buf[len], s->out_ptr);

View File

@ -865,6 +865,7 @@ void ehci_reset(void *opaque)
s->usbsts = USBSTS_HALT;
s->usbsts_pending = 0;
s->usbsts_frindex = 0;
ehci_update_irq(s);
s->astate = EST_INACTIVE;
s->pstate = EST_INACTIVE;
@ -1404,21 +1405,23 @@ static int ehci_process_itd(EHCIState *ehci,
if (itd->transact[i] & ITD_XACT_ACTIVE) {
pg = get_field(itd->transact[i], ITD_XACT_PGSEL);
off = itd->transact[i] & ITD_XACT_OFFSET_MASK;
ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
ptr2 = (itd->bufptr[pg+1] & ITD_BUFPTR_MASK);
len = get_field(itd->transact[i], ITD_XACT_LENGTH);
if (len > max * mult) {
len = max * mult;
}
if (len > BUFF_SIZE) {
if (len > BUFF_SIZE || pg > 6) {
return -1;
}
ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
qemu_sglist_init(&ehci->isgl, ehci->device, 2, ehci->as);
if (off + len > 4096) {
/* transfer crosses page border */
if (pg == 6) {
return -1; /* avoid page pg + 1 */
}
ptr2 = (itd->bufptr[pg + 1] & ITD_BUFPTR_MASK);
uint32_t len2 = off + len - 4096;
uint32_t len1 = len - len2;
qemu_sglist_add(&ehci->isgl, ptr1 + off, len1);
@ -2000,6 +2003,7 @@ static int ehci_state_writeback(EHCIQueue *q)
static void ehci_advance_state(EHCIState *ehci, int async)
{
EHCIQueue *q = NULL;
int itd_count = 0;
int again;
do {
@ -2024,10 +2028,12 @@ static void ehci_advance_state(EHCIState *ehci, int async)
case EST_FETCHITD:
again = ehci_state_fetchitd(ehci, async);
itd_count++;
break;
case EST_FETCHSITD:
again = ehci_state_fetchsitd(ehci, async);
itd_count++;
break;
case EST_ADVANCEQUEUE:
@ -2076,7 +2082,8 @@ static void ehci_advance_state(EHCIState *ehci, int async)
break;
}
if (again < 0) {
if (again < 0 || itd_count > 16) {
/* TODO: notify guest (raise HSE irq?) */
fprintf(stderr, "processing error - resetting ehci HC\n");
ehci_reset(ehci);
again = 0;

View File

@ -612,6 +612,25 @@ static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr)
return -1;
}
static bool vhost_user_can_merge(struct vhost_dev *dev,
uint64_t start1, uint64_t size1,
uint64_t start2, uint64_t size2)
{
ram_addr_t ram_addr;
int mfd, rfd;
MemoryRegion *mr;
mr = qemu_ram_addr_from_host((void *)(uintptr_t)start1, &ram_addr);
assert(mr);
mfd = qemu_get_ram_fd(ram_addr);
mr = qemu_ram_addr_from_host((void *)(uintptr_t)start2, &ram_addr);
assert(mr);
rfd = qemu_get_ram_fd(ram_addr);
return mfd == rfd;
}
const VhostOps user_ops = {
.backend_type = VHOST_BACKEND_TYPE_USER,
.vhost_backend_init = vhost_user_init,
@ -634,4 +653,5 @@ const VhostOps user_ops = {
.vhost_set_vring_enable = vhost_user_set_vring_enable,
.vhost_requires_shm_log = vhost_user_requires_shm_log,
.vhost_migration_done = vhost_user_migration_done,
.vhost_backend_can_merge = vhost_user_can_merge,
};

View File

@ -259,6 +259,13 @@ static void vhost_dev_assign_memory(struct vhost_dev *dev,
continue;
}
if (dev->vhost_ops->vhost_backend_can_merge &&
!dev->vhost_ops->vhost_backend_can_merge(dev, uaddr, size,
reg->userspace_addr,
reg->memory_size)) {
continue;
}
if (merged) {
--to;
assert(to >= 0);

View File

@ -59,30 +59,33 @@ typedef struct VirtioBusClass VirtioPCIBusClass;
#define VIRTIO_PCI_BUS_CLASS(klass) \
OBJECT_CLASS_CHECK(VirtioPCIBusClass, klass, TYPE_VIRTIO_PCI_BUS)
enum {
VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT,
VIRTIO_PCI_FLAG_DISABLE_LEGACY_BIT,
VIRTIO_PCI_FLAG_DISABLE_MODERN_BIT,
VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT,
VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT,
VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT,
};
/* Need to activate work-arounds for buggy guests at vmstate load. */
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT 0
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION \
(1 << VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT)
/* Performance improves when virtqueue kick processing is decoupled from the
* vcpu thread using ioeventfd for some devices. */
#define VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT 1
#define VIRTIO_PCI_FLAG_USE_IOEVENTFD (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT)
/* virtio version flags */
#define VIRTIO_PCI_FLAG_DISABLE_LEGACY_BIT 2
#define VIRTIO_PCI_FLAG_DISABLE_MODERN_BIT 3
#define VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT 4
#define VIRTIO_PCI_FLAG_DISABLE_LEGACY (1 << VIRTIO_PCI_FLAG_DISABLE_LEGACY_BIT)
#define VIRTIO_PCI_FLAG_DISABLE_MODERN (1 << VIRTIO_PCI_FLAG_DISABLE_MODERN_BIT)
#define VIRTIO_PCI_FLAG_DISABLE_PCIE (1 << VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT)
/* migrate extra state */
#define VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT 4
#define VIRTIO_PCI_FLAG_MIGRATE_EXTRA (1 << VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT)
/* have pio notification for modern device ? */
#define VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT 5
#define VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY \
(1 << VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT)

View File

@ -196,6 +196,7 @@ int bdrv_create(BlockDriver *drv, const char* filename,
int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
BlockDriverState *bdrv_new_root(void);
BlockDriverState *bdrv_new(void);
void bdrv_device_remove(BlockDriverState *bs);
void bdrv_make_anon(BlockDriverState *bs);
void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top);

View File

@ -686,6 +686,7 @@ void blk_set_bs(BlockBackend *blk, BlockDriverState *bs);
void blk_dev_change_media_cb(BlockBackend *blk, bool load);
bool blk_dev_has_removable_media(BlockBackend *blk);
bool blk_dev_has_tray(BlockBackend *blk);
void blk_dev_eject_request(BlockBackend *blk, bool force);
bool blk_dev_is_tray_open(BlockBackend *blk);
bool blk_dev_is_medium_locked(BlockBackend *blk);

View File

@ -124,6 +124,7 @@ struct MachineState {
char *firmware;
bool iommu;
bool suppress_vmdesc;
bool enforce_config_section;
ram_addr_t ram_size;
ram_addr_t maxram_size;

View File

@ -18,6 +18,14 @@
.driver = "virtio-pci",\
.property = "migrate-extra",\
.value = "off",\
},{\
.driver = "fw_cfg_mem",\
.property = "dma_enabled",\
.value = "off",\
},{\
.driver = "fw_cfg_io",\
.property = "dma_enabled",\
.value = "off",\
},
#define HW_COMPAT_2_3 \

View File

@ -70,6 +70,9 @@ typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev,
typedef bool (*vhost_requires_shm_log_op)(struct vhost_dev *dev);
typedef int (*vhost_migration_done_op)(struct vhost_dev *dev,
char *mac_addr);
typedef bool (*vhost_backend_can_merge_op)(struct vhost_dev *dev,
uint64_t start1, uint64_t size1,
uint64_t start2, uint64_t size2);
typedef struct VhostOps {
VhostBackendType backend_type;
@ -97,6 +100,7 @@ typedef struct VhostOps {
vhost_set_vring_enable_op vhost_set_vring_enable;
vhost_requires_shm_log_op vhost_requires_shm_log;
vhost_migration_done_op vhost_migration_done;
vhost_backend_can_merge_op vhost_backend_can_merge;
} VhostOps;
extern const VhostOps user_ops;

View File

@ -433,7 +433,7 @@ static inline int vnc_display_pw_expire(const char *id, time_t expires)
void curses_display_init(DisplayState *ds, int full_screen);
/* input.c */
int index_from_key(const char *key);
int index_from_key(const char *key, size_t key_length);
/* gtk.c */
void early_gtk_display_init(int opengl);

View File

@ -878,13 +878,19 @@ bool qemu_savevm_state_blocked(Error **errp)
return false;
}
static bool enforce_config_section(void)
{
MachineState *machine = MACHINE(qdev_get_machine());
return machine->enforce_config_section;
}
void qemu_savevm_state_header(QEMUFile *f)
{
trace_savevm_state_header();
qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
qemu_put_be32(f, QEMU_VM_FILE_VERSION);
if (!savevm_state.skip_configuration) {
if (!savevm_state.skip_configuration || enforce_config_section()) {
qemu_put_byte(f, QEMU_VM_CONFIGURATION);
vmstate_save_state(f, &vmstate_configuration, &savevm_state, 0);
}
@ -1839,7 +1845,7 @@ int qemu_loadvm_state(QEMUFile *f)
return -ENOTSUP;
}
if (!savevm_state.skip_configuration) {
if (!savevm_state.skip_configuration || enforce_config_section()) {
if (qemu_get_byte(f) != QEMU_VM_CONFIGURATION) {
error_report("Configuration section missing");
return -EINVAL;

View File

@ -59,6 +59,11 @@ void net_checksum_calculate(uint8_t *data, int length)
int hlen, plen, proto, csum_offset;
uint16_t csum;
/* Ensure data has complete L2 & L3 headers. */
if (length < 14 + 20) {
return;
}
if ((data[14] & 0xf0) != 0x40)
return; /* not IPv4 */
hlen = (data[14] & 0x0f) * 4;
@ -76,8 +81,9 @@ void net_checksum_calculate(uint8_t *data, int length)
return;
}
if (plen < csum_offset+2)
return;
if (plen < csum_offset + 2 || 14 + hlen + plen > length) {
return;
}
data[14+hlen+csum_offset] = 0;
data[14+hlen+csum_offset+1] = 0;

View File

@ -329,6 +329,13 @@ static void filter_dump_instance_init(Object *obj)
file_dump_set_filename, NULL);
}
static void filter_dump_instance_finalize(Object *obj)
{
NetFilterDumpState *nfds = FILTER_DUMP(obj);
g_free(nfds->filename);
}
static void filter_dump_class_init(ObjectClass *oc, void *data)
{
NetFilterClass *nfc = NETFILTER_CLASS(oc);
@ -343,6 +350,7 @@ static const TypeInfo filter_dump_info = {
.parent = TYPE_NETFILTER,
.class_init = filter_dump_class_init,
.instance_init = filter_dump_instance_init,
.instance_finalize = filter_dump_instance_finalize,
.instance_size = sizeof(NetFilterDumpState),
};

View File

@ -204,6 +204,7 @@ static void netfilter_finalize(Object *obj)
if (nf->netdev && !QTAILQ_EMPTY(&nf->netdev->filters)) {
QTAILQ_REMOVE(&nf->netdev->filters, nf, next);
}
g_free(nf->netdev_id);
}
static void netfilter_class_init(ObjectClass *oc, void *data)

View File

@ -2048,8 +2048,7 @@
# respond to the eject request
# - if the BlockBackend denoted by @device does not have a guest device attached
# to it
# - if the guest device does not have an actual tray and is empty, for instance
# for floppy disk drives
# - if the guest device does not have an actual tray
#
# @device: block device name
#

View File

@ -29,6 +29,15 @@ typedef QTAILQ_HEAD(QStack, QStackEntry) QStack;
struct QmpOutputVisitor
{
Visitor visitor;
/* FIXME: we are abusing stack to hold two separate pieces of
* information: the current root object in slot 0, and the stack
* of N objects still being built in slots 1 through N (for N+1
* slots in use). Worse, our behavior is inconsistent:
* qmp_output_add_obj() visiting two top-level scalars in a row
* discards the first in favor of the second, but visiting two
* top-level objects in a row tries to append the second object
* into the first (since the first object was placed in the stack
* in both slot 0 and 1, but only popped from slot 1). */
QStack stack;
};
@ -41,10 +50,12 @@ static QmpOutputVisitor *to_qov(Visitor *v)
return container_of(v, QmpOutputVisitor, visitor);
}
/* Push @value onto the stack of current QObjects being built */
static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value)
{
QStackEntry *e = g_malloc0(sizeof(*e));
assert(value);
e->value = value;
if (qobject_type(e->value) == QTYPE_QLIST) {
e->is_list_head = true;
@ -52,44 +63,53 @@ static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value)
QTAILQ_INSERT_HEAD(&qov->stack, e, node);
}
/* Pop a value off the stack of QObjects being built, and return it. */
static QObject *qmp_output_pop(QmpOutputVisitor *qov)
{
QStackEntry *e = QTAILQ_FIRST(&qov->stack);
QObject *value;
assert(e);
QTAILQ_REMOVE(&qov->stack, e, node);
value = e->value;
assert(value);
g_free(e);
return value;
}
/* Grab the root QObject, if any */
static QObject *qmp_output_first(QmpOutputVisitor *qov)
{
QStackEntry *e = QTAILQ_LAST(&qov->stack, QStack);
/*
* FIXME Wrong, because qmp_output_get_qobject() will increment
* the refcnt *again*. We need to think through how visitors
* handle null.
*/
if (!e) {
return qnull();
/* No root */
return NULL;
}
assert(e->value);
return e->value;
}
/* Peek at the top of the stack of QObjects being built.
* The stack must not be empty. */
static QObject *qmp_output_last(QmpOutputVisitor *qov)
{
QStackEntry *e = QTAILQ_FIRST(&qov->stack);
assert(e && e->value);
return e->value;
}
/* Add @value to the current QObject being built.
* If the stack is visiting a dictionary or list, @value is now owned
* by that container. Otherwise, @value is now the root. */
static void qmp_output_add_obj(QmpOutputVisitor *qov, const char *name,
QObject *value)
{
QObject *cur;
if (QTAILQ_EMPTY(&qov->stack)) {
/* Stack was empty, track this object as root */
qmp_output_push_obj(qov, value);
return;
}
@ -98,13 +118,17 @@ static void qmp_output_add_obj(QmpOutputVisitor *qov, const char *name,
switch (qobject_type(cur)) {
case QTYPE_QDICT:
assert(name);
qdict_put_obj(qobject_to_qdict(cur), name, value);
break;
case QTYPE_QLIST:
qlist_append_obj(qobject_to_qlist(cur), value);
break;
default:
/* The previous root was a scalar, replace it with a new root */
/* FIXME this is abusing the stack; see comment above */
qobject_decref(qmp_output_pop(qov));
assert(QTAILQ_EMPTY(&qov->stack));
qmp_output_push_obj(qov, value);
break;
}
@ -198,11 +222,14 @@ static void qmp_output_type_any(Visitor *v, QObject **obj, const char *name,
qmp_output_add_obj(qov, name, *obj);
}
/* Finish building, and return the root object. Will not be NULL. */
QObject *qmp_output_get_qobject(QmpOutputVisitor *qov)
{
QObject *obj = qmp_output_first(qov);
if (obj) {
qobject_incref(obj);
} else {
obj = qnull();
}
return obj;
}

View File

@ -41,7 +41,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" igd-passthru=on|off controls IGD GFX passthrough support (default=off)\n"
" aes-key-wrap=on|off controls support for AES key wrapping (default=on)\n"
" dea-key-wrap=on|off controls support for DEA key wrapping (default=on)\n"
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n",
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
" enforce-config-section=on|off enforce configuration section migration (default=off)\n",
QEMU_ARCH_ALL)
STEXI
@item -machine [type=]@var{name}[,prop=@var{value}[,...]]

View File

@ -150,6 +150,7 @@ typedef struct ARMCPU {
uint32_t id_mmfr1;
uint32_t id_mmfr2;
uint32_t id_mmfr3;
uint32_t id_mmfr4;
uint32_t id_isar0;
uint32_t id_isar1;
uint32_t id_isar2;

View File

@ -4092,12 +4092,14 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = cpu->id_isar5 },
/* 6..7 are as yet unallocated and must RAZ */
{ .name = "ID_ISAR6", .cp = 15, .crn = 0, .crm = 2,
.opc1 = 0, .opc2 = 6, .access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_ISAR7", .cp = 15, .crn = 0, .crm = 2,
.opc1 = 0, .opc2 = 7, .access = PL1_R, .type = ARM_CP_CONST,
{ .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = cpu->id_mmfr4 },
/* 7 is as yet unallocated and must RAZ */
{ .name = "ID_ISAR7_RESERVED", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
REGINFO_SENTINEL
};
@ -4151,7 +4153,11 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_arm_cp_regs(cpu, not_v7_cp_reginfo);
}
if (arm_feature(env, ARM_FEATURE_V8)) {
/* AArch64 ID registers, which all have impdef reset values */
/* AArch64 ID registers, which all have impdef reset values.
* Note that within the ID register ranges the unused slots
* must all RAZ, not UNDEF; future architecture versions may
* define new registers here.
*/
ARMCPRegInfo v8_idregs[] = {
{ .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0,
@ -4161,6 +4167,30 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = cpu->id_aa64pfr1},
{ .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64PFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64PFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64PFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64PFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64PFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
@ -4174,6 +4204,14 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = cpu->id_aa64dfr1 },
{ .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64DFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST,
@ -4182,6 +4220,14 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = cpu->id_aa64afr1 },
{ .name = "ID_AA64AFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64AFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
@ -4190,6 +4236,30 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = cpu->id_aa64isar1 },
{ .name = "ID_AA64ISAR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64ISAR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64ISAR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64ISAR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64ISAR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
@ -4198,6 +4268,30 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = cpu->id_aa64mmfr1 },
{ .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64MMFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64MMFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "ID_AA64MMFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "MVFR0_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
@ -4210,6 +4304,26 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = cpu->mvfr2 },
{ .name = "MVFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "MVFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "MVFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
{ .name = "MVFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
.resetvalue = 0 },
REGINFO_SENTINEL
};
/* RVBAR_EL1 is only implemented if EL1 is the highest EL */

View File

@ -601,6 +601,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (cpu->hyperv_crash && has_msr_hv_crash) {
c->edx |= HV_X64_GUEST_CRASH_MSR_AVAILABLE;
}
c->edx |= HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE;
if (cpu->hyperv_reset && has_msr_hv_reset) {
c->eax |= HV_X64_MSR_RESET_AVAILABLE;
}

View File

@ -650,8 +650,13 @@ static int kvm_put_fp(CPUState *cs)
for (i = 0; i < 32; i++) {
uint64_t vsr[2];
#ifdef HOST_WORDS_BIGENDIAN
vsr[0] = float64_val(env->fpr[i]);
vsr[1] = env->vsr[i];
#else
vsr[0] = env->vsr[i];
vsr[1] = float64_val(env->fpr[i]);
#endif
reg.addr = (uintptr_t) &vsr;
reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i);
@ -721,10 +726,17 @@ static int kvm_get_fp(CPUState *cs)
vsx ? "VSR" : "FPR", i, strerror(errno));
return ret;
} else {
#ifdef HOST_WORDS_BIGENDIAN
env->fpr[i] = vsr[0];
if (vsx) {
env->vsr[i] = vsr[1];
}
#else
env->fpr[i] = vsr[1];
if (vsx) {
env->vsr[i] = vsr[0];
}
#endif
}
}
}

View File

@ -616,7 +616,8 @@ static void ioinst_handle_chsc_sei(ChscReq *req, ChscResp *res)
(*res_flags) &= ~0x80;
}
} else {
res->code = cpu_to_be16(0x0004);
res->code = cpu_to_be16(0x0005);
res->len = cpu_to_be16(CHSC_MIN_RESP_LEN);
}
}

View File

@ -0,0 +1,114 @@
#!/bin/bash
# Check live snapshot, followed by active commit, and another snapshot.
#
# This test is to catch the error case of BZ #1300209:
# https://bugzilla.redhat.com/show_bug.cgi?id=1300209
#
# Copyright (C) 2016 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# creator
owner=jcody@redhat.com
seq=`basename $0`
echo "QA output created by $seq"
here=`pwd`
status=1 # failure is the default!
TMP_SNAP1=${TEST_DIR}/tmp.qcow2
TMP_SNAP2=${TEST_DIR}/tmp2.qcow2
_cleanup()
{
_cleanup_qemu
rm -f "${TEST_IMG}" "${TMP_SNAP1}" "${TMP_SNAP2}"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
. ./common.qemu
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
size=512M
_make_test_img $size
echo
echo === Launching QEMU ===
echo
qemu_comm_method="qmp"
_launch_qemu -drive file="${TEST_IMG}",if=virtio
h=$QEMU_HANDLE
echo
echo === Performing Live Snapshot 1 ===
echo
_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" "return"
# First live snapshot, new overlay as active layer
_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
'arguments': {
'device': 'virtio0',
'snapshot-file':'${TMP_SNAP1}',
'format': 'qcow2'
}
}" "return"
echo
echo === Performing block-commit on active layer ===
echo
# Block commit on active layer, push the new overlay into base
_send_qemu_cmd $h "{ 'execute': 'block-commit',
'arguments': {
'device': 'virtio0'
}
}" "READY"
_send_qemu_cmd $h "{ 'execute': 'block-job-complete',
'arguments': {
'device': 'virtio0'
}
}" "COMPLETED"
echo
echo === Performing Live Snapshot 2 ===
echo
# New live snapshot, new overlays as active layer
_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
'arguments': {
'device': 'virtio0',
'snapshot-file':'${TMP_SNAP2}',
'format': 'qcow2'
}
}" "return"
# success, all done
echo "*** done"
rm -f $seq.full
status=0

View File

@ -0,0 +1,24 @@
QA output created by 144
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=536870912
=== Launching QEMU ===
=== Performing Live Snapshot 1 ===
{"return": {}}
Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16
{"return": {}}
=== Performing block-commit on active layer ===
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "virtio0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "virtio0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
=== Performing Live Snapshot 2 ===
Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16
{"return": {}}
*** done

View File

@ -140,3 +140,4 @@
137 rw auto
138 rw auto quick
139 rw auto quick
144 rw auto quick

View File

@ -461,6 +461,8 @@ static void test_visitor_out_empty(TestOutputVisitorData *data,
arg = qmp_output_get_qobject(data->qov);
g_assert(qobject_type(arg) == QTYPE_QNULL);
/* Check that qnull reference counting is sane */
g_assert(arg->refcnt == 2);
qobject_decref(arg);
}

View File

@ -57,12 +57,13 @@ struct QEMUPutLEDEntry {
static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers =
QTAILQ_HEAD_INITIALIZER(led_handlers);
int index_from_key(const char *key)
int index_from_key(const char *key, size_t key_length)
{
int i;
for (i = 0; QKeyCode_lookup[i] != NULL; i++) {
if (!strcmp(key, QKeyCode_lookup[i])) {
if (!strncmp(key, QKeyCode_lookup[i], key_length) &&
!QKeyCode_lookup[i][key_length]) {
break;
}
}

37
vl.c
View File

@ -2757,6 +2757,31 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
return popt;
}
static void set_machine_options(MachineClass **machine_class)
{
const char *optarg;
QemuOpts *opts;
Location loc;
loc_push_none(&loc);
opts = qemu_get_machine_opts();
qemu_opts_loc_restore(opts);
optarg = qemu_opt_get(opts, "type");
if (optarg) {
*machine_class = machine_parse(optarg);
}
if (*machine_class == NULL) {
error_report("No machine specified, and there is no default");
error_printf("Use -machine help to list supported machines\n");
exit(1);
}
loc_pop(&loc);
}
static int machine_set_property(void *opaque,
const char *name, const char *value,
Error **errp)
@ -4025,17 +4050,7 @@ int main(int argc, char **argv, char **envp)
replay_configure(icount_opts);
opts = qemu_get_machine_opts();
optarg = qemu_opt_get(opts, "type");
if (optarg) {
machine_class = machine_parse(optarg);
}
if (machine_class == NULL) {
error_report("No machine specified, and there is no default");
error_printf("Use -machine help to list supported machines\n");
exit(1);
}
set_machine_options(&machine_class);
set_memory_options(&ram_slots, &maxram_size, machine_class);