Compare commits

...

194 Commits

Author SHA1 Message Date
Gerd Hoffmann
9df074ae9a 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>
[BR: BSC#978160 CVE-2016-3712]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-05-16 14:30:24 -06:00
Gerd Hoffmann
b3f8963ed3 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>
[BR: BSC#978160 CVE-2016-3712]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-05-16 14:30:18 -06:00
Gerd Hoffmann
7eaf4dc41d 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>
[BR: BSC#978160 CVE-2016-3712]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-05-16 14:30:12 -06:00
Gerd Hoffmann
17c60d679d vga: add vbe_enabled() helper
Makes code a bit easier to read.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
[BR: BSC#978160 CVE-2016-3712]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-05-16 14:30:05 -06:00
Gerd Hoffmann
722e8b6983 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>
[BR: BSC#978158 CVE-2016-3710]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-05-16 14:29:59 -06:00
Prasad J Pandit
9e069596f8 i386: kvmvapic: initialise imm32 variable
When processing Task Priorty Register(TPR) access, it could leak
automatic stack variable 'imm32' in patch_instruction().
Initialise the variable to avoid it.

Reported by: Donghai Zdh <donghai.zdh@alibaba-inc.com>

Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
[BR: BSC#975700 CVE-2016-4020]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:49:29 -06:00
Prasad J Pandit
afcb3aa75e net: mipsnet: check packet length against buffer
When receiving packets over MIPSnet network device, it uses
 receive buffer of size 1514 bytes. In case the controller
accepts large(MTU) packets, it could lead to memory corruption.
Add check to avoid it.

Reported by: Oleksandr Bazhaniuk <oleksandr.bazhaniuk@intel.com>

Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
[BR: BSC#975136 CVE-2016-4002]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:48:55 -06:00
Prasad J Pandit
b762a46c59 net: stellaris_enet: check packet length against receive buffer
When receiving packets over Stellaris ethernet controller, it
uses receive buffer of size 2048 bytes. In case the controller
accepts large(MTU) packets, it could lead to memory corruption.
Add check to avoid it.

Reported-by: Oleksandr Bazhaniuk <oleksandr.bazhaniuk@intel.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 1460095428-22698-1-git-send-email-ppandit@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 3a15cc0e1e)
[BR: BSC#975128 CVE-2016-4001]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:31:36 -06:00
Prasad J Pandit
038cdbe856 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)
[BR: BSC#970037 CVE-2016-2857]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:31:05 -06:00
Ladi Prosek
a4c21c23f7 rng: add request queue support to rng-random
Requests are now created in the RngBackend parent class and the
code path is shared by both rng-egd and rng-random.

This commit fixes the rng-random implementation which processed
only one request at a time and simply discarded all but the most
recent one. In the guest this manifested as delayed completion
of reads from virtio-rng, i.e. a read was completed only after
another read was issued.

By switching rng-random to use the same request queue as rng-egd,
the unsafe stack-based allocation of the entropy buffer is
eliminated and replaced with g_malloc.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Message-Id: <1456994238-9585-5-git-send-email-lprosek@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
(cherry picked from commit 60253ed1e6)
[BR: BSC#970036 CVE-2016-2858]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:30:29 -06:00
Ladi Prosek
f9ee835b11 rng: move request queue cleanup from RngEgd to RngBackend
RngBackend is now in charge of cleaning up the linked list on
instance finalization. It also exposes a function to finalize
individual RngRequest instances, called by its child classes.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Message-Id: <1456994238-9585-4-git-send-email-lprosek@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
(cherry picked from commit 9f14b0add1)
[BR: support patch for BSC#970036]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:29:57 -06:00
Ladi Prosek
9338f44b1e rng: move request queue from RngEgd to RngBackend
The 'requests' field now lives in the RngBackend parent class.
There are no functional changes in this commit.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Message-Id: <1456994238-9585-3-git-send-email-lprosek@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
(cherry picked from commit 74074e8a7c)
[BR: support patch for BSC#970036]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:29:27 -06:00
Ladi Prosek
8cb6271fe4 rng: remove the unused request cancellation code
rng_backend_cancel_requests had no callers and none of the code
deleted in this commit ever ran.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Message-Id: <1456994238-9585-2-git-send-email-lprosek@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
(cherry picked from commit 3c52ddcdc5)
[BR: support patch for BSC#970036]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:28:51 -06:00
Prasad J Pandit
5edc5b4690 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)
[BR: BSC#969350 CVE-2016-2841]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:28:14 -06:00
Paolo Bonzini
f3dbcc6c2b exec: skip MMIO regions correctly in cpu_physical_memory_write_rom_internal
Loading the BIOS in the mac99 machine is interesting, because there is a
PROM in the middle of the BIOS region (from 16K to 32K).  Before memory
region accesses were clamped, when QEMU was asked to load a BIOS from
0xfff00000 to 0xffffffff it would put even those 16K from the BIOS file
into the region.  This is weird because those 16K were not actually
visible between 0xfff04000 and 0xfff07fff.  However, it worked.

After clamping was added, this also worked.  In this case, the
cpu_physical_memory_write_rom_internal function split the write in
three parts: the first 16K were copied, the PROM area (second 16K) were
ignored, then the rest was copied.

Problems then started with commit 965eb2f (exec: do not clamp accesses
to MMIO regions, 2015-06-17).  Clamping accesses is not done for MMIO
regions because they can overlap wildly, and MMIO registers can be
expected to perform full-width accesses based only on their address
(with no respect for adjacent registers that could decode to completely
different MemoryRegions).  However, this lack of clamping also applied
to the PROM area!  cpu_physical_memory_write_rom_internal thus failed
to copy the third range above, i.e. only copied the first 16K of the BIOS.

In effect, address_space_translate is expecting _something else_ to do
the clamping for MMIO regions if the incoming length is large.  This
"something else" is memory_access_size in the case of address_space_rw,
so use the same logic in cpu_physical_memory_write_rom_internal.

Reported-by: Alexander Graf <agraf@redhat.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
Fixes: 965eb2f
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit b242e0e0e2)
[BR: BSC#969122 CVE-2015-8818]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:27:39 -06:00
Paolo Bonzini
db27c2e97d exec: do not clamp accesses to MMIO regions
It is common for MMIO registers to overlap, for example a 4 byte register
at 0xcf8 (totally random choice... :)) and a 1 byte register at 0xcf9.
If these registers are implemented via separate MemoryRegions, it is
wrong to clamp the accesses as the value written would be truncated.

Hence for these regions the effects of commit 23820db (exec: Respect
as_translate_internal length clamp, 2015-03-16, previously applied as
commit c3c1bb99) must be skipped.

Tested-by: Hervé Poussineau <hpoussin@reactos.org>
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 965eb2fcdf)
[BR: support patch for BSC#969122]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:27:12 -06:00
Peter Crosthwaite
f18e9ab50f exec: Respect as_tranlsate_internal length clamp
address_space_translate_internal will clamp the *plen length argument
based on the size of the memory region being queried. The iommu walker
logic in addresss_space_translate was ignoring this by discarding the
post fn call value of *plen. Fix by just always using *plen as the
length argument throughout the fn, removing the len local variable.

This fixes a bootloader bug when a single elf section spans multiple
QEMU memory regions.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-Id: <1426570554-15940-1-git-send-email-peter.crosthwaite@xilinx.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit c3c1bb99d1)
[BR: BSC#969121 CVE-2015-8817]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:26:43 -06:00
Prasad J Pandit
9a7141de94 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)
[BR: BSC#967969 CVE-2016-2538]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:26:09 -06:00
Gerd Hoffmann
04c5b5ee58 vnc: fix memory corruption (CVE-2015-5225)
The _cmp_bytes variable added by commit "bea60dd ui/vnc: fix potential
memory corruption issues" can become negative.  Result is (possibly
exploitable) memory corruption.  Reason for that is it uses the stride
instead of bytes per scanline to apply limits.

For the server surface is is actually fine.  vnc creates that itself,
there is never any padding and thus scanline length always equals stride.

For the guest surface scanline length and stride are typically identical
too, but it doesn't has to be that way.  So add and use a new variable
(guest_ll) for the guest scanline length.  Also rename min_stride to
line_bytes to make more clear what it actually is.  Finally sprinkle
in an assert() to make sure we never use a negative _cmp_bytes again.

Reported-by: 范祚至(库特) <zuozhi.fzz@alibaba-inc.com>
Reviewed-by: P J P <ppandit@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit eb8934b041)
[AF: BSC#942845]
Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:24:39 -06:00
Laszlo Ersek
905b4aca85 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)
[BR: BSC#963782 CVE-2016-1981]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:24:39 -06:00
Prasad J Pandit
2f31685bef usb: ehci: add capability mmio write function
USB Ehci emulation supports host controller capability registers.
But its mmio '.write' function was missing, which lead to a null
pointer dereference issue. Add a do nothing 'ehci_caps_write'
definition to avoid it; Do nothing because capability registers
are Read Only(RO).

Reported-by: Zuozhi Fzz <zuozhi.fzz@alibaba-inc.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
[BR: BSC#964413 CVE-2016-2198]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:24:39 -06:00
Wolfgang Bumiller
64c69285c9 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)
[BR: BSC#960334 CVE-2015-8619]
Signed-off-by: Bruce Rogers <brogers@suse.com>

Conflicts:
	hmp.c
        ui/input-legacy.c
2016-04-28 10:24:39 -06:00
Dana Rubin
63809d69ca net/vmxnet3: Refine l2 header validation
Validation of l2 header length assumed minimal packet size as
eth_header + 2 * vlan_header regardless of the actual protocol.

This caused crash for valid non-IP packets shorter than 22 bytes, as
'tx_pkt->packet_type' hasn't been assigned for such packets, and
'vmxnet3_on_tx_done_update_stats()' expects it to be properly set.

Refine header length validation in 'vmxnet_tx_pkt_parse_headers'.
Check its return value during packet processing flow.

As a side effect, in case IPv4 and IPv6 header validation failure,
corrupt packets will be dropped.

Signed-off-by: Dana Rubin <dana.rubin@ravellosystems.com>
Signed-off-by: Shmulik Ladkani <shmulik.ladkani@ravellosystems.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 7278b36fcab9af469563bd7b9dadebe2ae25e48)
[CYL: BSC#960835 CVE-2015-8744]
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:24:39 -06:00
P J P
d98edfff7c 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)
[CYL: BSC#959386 CVE-2015-8568 CVE-2015-8567]
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>

Conflicts:
	hw/net/vmxnet3.c

Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:24:39 -06:00
Shmulik Ladkani
7577718e58 vmxnet3: Support reading IMR registers on bar0
Instead of asserting, return the actual IMR register value.
This is aligned with what's returned on ESXi.

Signed-off-by: Shmulik Ladkani <shmulik.ladkani@ravellosystems.com>
Tested-by: Dana Rubin <dana.rubin@ravellosystems.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit c6048f849c)
[CYL: BSC#960708 CVE-2015-8745]
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:24:39 -06:00
Prasad J Pandit
9b2ae7d811 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)
[LM: BSC#961333 CVE-2016-1568]
Signed-off-by: Lin Ma <lma@suse.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:24:39 -06:00
John Snow
c663eecb2c ahci: add ncq_err helper
Set some appropriate error bits for NCQ for us.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1435016308-6150-4-git-send-email-jsnow@redhat.com
(cherry picked from commit a55c8231d0)
[LM: BSC#961333 CVE-2016-1568]
Signed-off-by: Lin Ma <lma@suse.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:24:39 -06:00
Prasad J Pandit
a3db912d8c 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)
[LM: BSC#960725 CVE-2015-8743]
Signed-off-by: Lin Ma <lma@suse.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:24:39 -06:00
Marc-André Lureau
9b97a3f345 msix: implement pba write (but read-only)
qpci_msix_pending() writes on pba region, causing qemu to SEGV:

  Program received signal SIGSEGV, Segmentation fault.
  [Switching to Thread 0x7ffff7fba8c0 (LWP 25882)]
  0x0000000000000000 in ?? ()
  (gdb) bt
  #0  0x0000000000000000 in  ()
  #1  0x00005555556556c5 in memory_region_oldmmio_write_accessor (mr=0x5555579f3f80, addr=0, value=0x7fffffffbf68, size=4, shift=0, mask=4294967295, attrs=...) at /home/elmarco/src/qemu/memory.c:434
  #2  0x00005555556558e1 in access_with_adjusted_size (addr=0, value=0x7fffffffbf68, size=4, access_size_min=1, access_size_max=4, access=0x55555565563e <memory_region_oldmmio_write_accessor>, mr=0x5555579f3f80, attrs=...) at /home/elmarco/src/qemu/memory.c:506
  #3  0x00005555556581eb in memory_region_dispatch_write (mr=0x5555579f3f80, addr=0, data=0, size=4, attrs=...) at /home/elmarco/src/qemu/memory.c:1176
  #4  0x000055555560b6f9 in address_space_rw (as=0x555555eff4e0 <address_space_memory>, addr=3759147008, attrs=..., buf=0x7fffffffc1b0 "", len=4, is_write=true) at /home/elmarco/src/qemu/exec.c:2439
  #5  0x000055555560baa2 in cpu_physical_memory_rw (addr=3759147008, buf=0x7fffffffc1b0 "", len=4, is_write=1) at /home/elmarco/src/qemu/exec.c:2534
  #6  0x000055555564c005 in cpu_physical_memory_write (addr=3759147008, buf=0x7fffffffc1b0, len=4) at /home/elmarco/src/qemu/include/exec/cpu-common.h:80
  #7  0x000055555564cd9c in qtest_process_command (chr=0x55555642b890, words=0x5555578de4b0) at /home/elmarco/src/qemu/qtest.c:378
  #8  0x000055555564db77 in qtest_process_inbuf (chr=0x55555642b890, inbuf=0x55555641b340) at /home/elmarco/src/qemu/qtest.c:569
  #9  0x000055555564dc07 in qtest_read (opaque=0x55555642b890, buf=0x7fffffffc2e0 "writel 0xe0100800 0x0\n", size=22) at /home/elmarco/src/qemu/qtest.c:581
  #10 0x000055555574ce3e in qemu_chr_be_write (s=0x55555642b890, buf=0x7fffffffc2e0 "writel 0xe0100800 0x0\n", len=22) at qemu-char.c:306
  #11 0x0000555555751263 in tcp_chr_read (chan=0x55555642bcf0, cond=G_IO_IN, opaque=0x55555642b890) at qemu-char.c:2876
  #12 0x00007ffff64c9a8a in g_main_context_dispatch (context=0x55555641c400) at gmain.c:3122

(without this patch, this can be reproduced with the ivshmem qtest)

Implement an empty mmio write to avoid the crash.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 43b11a91dd)
[LM: BSC#958917 CVE-2015-7549]
Signed-off-by: Lin Ma <lma@suse.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:24:38 -06:00
Gerd Hoffmann
931cfa0fb9 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)
[BR: BSC#976109 CVE-2016-4037]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-04-28 10:24:03 -06:00
Michael S. Tsirkin
e218b06dec virtio-serial: fix ANY_LAYOUT
Don't assume a specific layout for control messages.
Required by virtio 1.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 7882080388)
[LM: BSC#940929 CVE-2015-5745]
Signed-off-by: Lin Ma <lma@suse.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 11:15:39 -07:00
Prasad J Pandit
b9370016d3 ui: vnc: avoid floating point exception
While sending 'SetPixelFormat' messages to a VNC server,
the client could set the 'red-max', 'green-max' and 'blue-max'
values to be zero. This leads to a floating point exception in
write_png_palette while doing frame buffer updates.

Reported-by: Lian Yihan <lianyihan@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 4c65fed8bd)
[LM: BSC#958491 CVE-2015-8504]
Signed-off-by: Lin Ma <lma@suse.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 11:14:56 -07:00
P J P
43d010a2d8 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)
[BR: BSC#961556 CVE-2015-8613]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 11:14:24 -07:00
P J P
e99b6ca6ae 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)
[BR: BSC#962320 CVE-2016-1922]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 11:13:35 -07:00
Prasad J Pandit
07333a4557 fw_cfg: add check to validate current entry value
When processing firmware configurations, an OOB r/w access occurs
if 's->cur_entry' is set to be invalid(FW_CFG_INVALID=0xffff).
Add a check to validate 's->cur_entry' to avoid such access.

Reported-by: Donghai Zdh <donghai.zdh@alibaba-inc.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
[BR: BSC#961691 CVE-2016-1714]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 11:11:01 -07:00
Jason Wang
198b341669 virtio-net: correctly drop truncated packets
When packet is truncated during receiving, we drop the packets but
neither discard the descriptor nor add and signal used
descriptor. This will lead several issues:

- sg mappings are leaked
- rx will be stalled if a lots of packets were truncated

In order to be consistent with vhost, fix by discarding the descriptor
in this case.

Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

(cherry picked from commit 0cf33fb6b4)
[BR: BSC#947159 CVE-2015-7295]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 11:10:13 -07:00
Jason Wang
ac665f787b virtio: introduce virtqueue_discard()
This patch introduces virtqueue_discard() to discard a descriptor and
unmap the sgs. This will be used by the patch that will discard
descriptor when packet is truncated.

Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

(cherry picked from commit 29b9f5efd7)
[BR: BSC#947159 CVE-2015-7295]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 11:09:20 -07:00
Jason Wang
d29342b3ef virtio: introduce virtqueue_unmap_sg()
Factor out sg unmapping logic. This will be reused by the patch that
can discard descriptor.

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Andrew James <andrew.james@hpe.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

(cherry picked from commit ce31746157)
[BR: BSC#947159 CVE-2015-7295]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 11:08:19 -07:00
Jason Wang
d92faac630 pcnet: fix rx buffer overflow(CVE-2015-7512)
Backends could provide a packet whose length is greater than buffer
size. Check for this and truncate the packet to avoid rx buffer
overflow in this case.

Cc: Prasad J Pandit <pjp@fedoraproject.org>
Cc: qemu-stable@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
[BR: BSC#957162]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 11:07:32 -07:00
Chunyan Liu
975f1b54a9 eepro100: Prevent two endless loops
http://lists.nongnu.org/archive/html/qemu-devel/2015-11/msg04592.html
shows an example how an endless loop in function action_command can
be achieved.

During my code review, I noticed a 2nd case which can result in an
endless loop.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 00837731d2)
(CYL: BSC#956829 CVE-2015-8345)
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 11:04:42 -07:00
John Snow
958aa25420 ide: fix ATAPI command permissions
We're a little too lenient with what we'll let an ATAPI drive handle.
Clamp down on the IDE command execution table to remove CD_OK permissions
from commands that are not and have never been ATAPI commands.

For ATAPI command validity, please see:
- ATA4 Section 6.5 ("PACKET Command feature set")
- ATA8/ACS Section 4.3 ("The PACKET feature set")
- ACS3 Section 4.3 ("The PACKET feature set")

ACS3 has a historical command validity table in Table B.4
("Historical Command Assignments") that can be referenced to find when
a command was introduced, deprecated, obsoleted, etc.

The only reference for ATAPI command validity is by checking that
version's PACKET feature set section.

ATAPI was introduced by T13 into ATA4, all commands retired prior to ATA4
therefore are assumed to have never been ATAPI commands.

Mandatory commands, as listed in ATA8-ACS3, are:

- DEVICE RESET
- EXECUTE DEVICE DIAGNOSTIC
- IDENTIFY DEVICE
- IDENTIFY PACKET DEVICE
- NOP
- PACKET
- READ SECTOR(S)
- SET FEATURES

Optional commands as listed in ATA8-ACS3, are:

- FLUSH CACHE
- READ LOG DMA EXT
- READ LOG EXT
- WRITE LOG DMA EXT
- WRITE LOG EXT

All other commands are illegal to send to an ATAPI device and should
be rejected by the device.

CD_OK removal justifications:

0x06 WIN_DSM              Defined in ACS2. Not valid for ATAPI.
0x21 WIN_READ_ONCE        Retired in ATA5. Not ATAPI in ATA4.
0x94 WIN_STANDBYNOW2      Retired in ATA4. Did not coexist with ATAPI.
0x95 WIN_IDLEIMMEDIATE2   Retired in ATA4. Did not coexist with ATAPI.
0x96 WIN_STANDBY2         Retired in ATA4. Did not coexist with ATAPI.
0x97 WIN_SETIDLE2         Retired in ATA4. Did not coexist with ATAPI.
0x98 WIN_CHECKPOWERMODE2  Retired in ATA4. Did not coexist with ATAPI.
0x99 WIN_SLEEPNOW2        Retired in ATA4. Did not coexist with ATAPI.
0xE0 WIN_STANDBYNOW1      Not part of ATAPI in ATA4, ACS or ACS3.
0xE1 WIN_IDLEIMMDIATE     Not part of ATAPI in ATA4, ACS or ACS3.
0xE2 WIN_STANDBY          Not part of ATAPI in ATA4, ACS or ACS3.
0xE3 WIN_SETIDLE1         Not part of ATAPI in ATA4, ACS or ACS3.
0xE4 WIN_CHECKPOWERMODE1  Not part of ATAPI in ATA4, ACS or ACS3.
0xE5 WIN_SLEEPNOW1        Not part of ATAPI in ATA4, ACS or ACS3.
0xF8 WIN_READ_NATIVE_MAX  Obsoleted in ACS3. Not ATAPI in ATA4 or ACS.

This patch fixes a divide by zero fault that can be caused by sending
the WIN_READ_NATIVE_MAX command to an ATAPI drive, which causes it to
attempt to use zeroed CHS values to perform sector arithmetic.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-id: 1441816082-21031-1-git-send-email-jsnow@redhat.com
CC: qemu-stable@nongnu.org
(cherry picked from commit d9033e1d3a)
[BR: CVE-2015-6855 BSC#945404]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 11:02:43 -07:00
P J P
a9c242bd96 net: add checks to validate ring buffer pointers(CVE-2015-5279)
Ne2000 NIC uses ring buffer of NE2000_MEM_SIZE(49152)
bytes to process network packets. While receiving packets
via ne2000_receive() routine, a local 'index' variable
could exceed the ring buffer size, which could lead to a
memory buffer overflow. Added other checks at initialisation.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: P J P <pjp@fedoraproject.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 9bbdbc66e5)
[BR: BSC#945987]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 11:02:07 -07:00
P J P
5dbcab1cc6 net: avoid infinite loop when receiving packets(CVE-2015-5278)
Ne2000 NIC uses ring buffer of NE2000_MEM_SIZE(49152)
bytes to process network packets. While receiving packets
via ne2000_receive() routine, a local 'index' variable
could exceed the ring buffer size, leading to an infinite
loop situation.

Reported-by: Qinghao Tang <luodalongde@gmail.com>
Signed-off-by: P J P <pjp@fedoraproject.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 737d2b3c41)
[BR: BSC#945989]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 11:01:37 -07:00
Petr Matousek
908f6370b6 vnc: sanitize bits_per_pixel from the client
bits_per_pixel that are less than 8 could result in accessing
non-initialized buffers later in the code due to the expectation
that bytes_per_pixel value that is used to initialize these buffers is
never zero.

To fix this check that bits_per_pixel from the client is one of the
values that the rfb protocol specification allows.

This is CVE-2014-7815.

Signed-off-by: Petr Matousek <pmatouse@redhat.com>

[ kraxel: apply codestyle fix ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit e6908bfe8e)
[AF: BSC#902737]
Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 10:59:43 -07:00
Kevin Wolf
3796e0fb10 ide: Clear DRQ after handling all expected accesses
This is additional hardening against an end_transfer_func that fails to
clear the DRQ status bit. The bit must be unset as soon as the PIO
transfer has completed, so it's better to do this in a central place
instead of duplicating the code in all commands (and forgetting it in
some).

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
[BR: BSC#938344]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 10:50:36 -07:00
Kevin Wolf
48e083a10b ide/atapi: Fix START STOP UNIT command completion
The command must be completed on all code paths. START STOP UNIT with
pwrcnd set should succeed without doing anything.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
[BR: BSC#938344]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 10:48:55 -07:00
Kevin Wolf
a305efbbaa ide: Check array bounds before writing to io_buffer (CVE-2015-5154)
If the end_transfer_func of a command is called because enough data has
been read or written for the current PIO transfer, and it fails to
correctly call the command completion functions, the DRQ bit in the
status register and s->end_transfer_func may remain set. This allows the
guest to access further bytes in s->io_buffer beyond s->data_end, and
eventually overflowing the io_buffer.

One case where this currently happens is emulation of the ATAPI command
START STOP UNIT.

This patch fixes the problem by adding explicit array bounds checks
before accessing the buffer instead of relying on end_transfer_func to
function correctly.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
[BR: BSC#938344]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 10:45:50 -07:00
Michael Tokarev
feb84f151d slirp: use less predictable directory name in /tmp for smb config (CVE-2015-4037)
In this version I used mkdtemp(3) which is:

        _BSD_SOURCE
        || /* Since glibc 2.10: */
            (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)

(POSIX.1-2008), so should be available on systems we care about.

While at it, reset the resulting directory name within smb structure
on error so cleanup function wont try to remove directory which we
failed to create.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit 8b8f1c7e9d)
[BR: BSC#932267]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 10:40:32 -07:00
Petr Matousek
3f937de067 pcnet: force the buffer access to be in bounds during tx
4096 is the maximum length per TMD and it is also currently the size of
the relay buffer pcnet driver uses for sending the packet data to QEMU
for further processing. With packet spanning multiple TMDs it can
happen that the overall packet size will be bigger than sizeof(buffer),
which results in memory corruption.

Fix this by only allowing to queue maximum sizeof(buffer) bytes.

This is CVE-2015-3209.

Signed-off-by: Petr Matousek <pmatouse@redhat.com>
Reported-by: Matt Tait <matttait@google.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[BR: BSC#932770]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 10:38:55 -07:00
Gonglei
1fdcf295c2 pcnet: fix Negative array index read
s->xmit_pos maybe assigned to a negative value (-1),
but in this branch variable s->xmit_pos as an index to
array s->buffer. Let's add a check for s->xmit_pos.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 7b50d00911)
[BR: BSC#932770]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 10:25:01 -07:00
Daniel P. Berrange
5876ceab64 CVE-2015-1779: limit size of HTTP headers from websockets clients
The VNC server websockets decoder will read and buffer data from
websockets clients until it sees the end of the HTTP headers,
as indicated by \r\n\r\n. In theory this allows a malicious to
trick QEMU into consuming an arbitrary amount of RAM. In practice,
because QEMU runs g_strstr_len() across the buffered header data,
it will spend increasingly long burning CPU time searching for
the substring match and less & less time reading data. So while
this does cause arbitrary memory growth, the bigger problem is
that QEMU will be burning 100% of available CPU time.

A novnc websockets client typically sends headers of around
512 bytes in length. As such it is reasonable to place a 4096
byte limit on the amount of data buffered while searching for
the end of HTTP headers.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 2cdb5e142f)
[AF: BSC#924018]
Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 10:24:07 -07:00
Daniel P. Berrange
13f3a70430 CVE-2015-1779: incrementally decode websocket frames
The logic for decoding websocket frames wants to fully
decode the frame header and payload, before allowing the
VNC server to see any of the payload data. There is no
size limit on websocket payloads, so this allows a
malicious network client to consume 2^64 bytes in memory
in QEMU. It can trigger this denial of service before
the VNC server even performs any authentication.

The fix is to decode the header, and then incrementally
decode the payload data as it is needed. With this fix
the websocket decoder will allow at most 4k of data to
be buffered before decoding and processing payload.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
[ kraxel: fix frequent spurious disconnects, suggested by Peter Maydell ]
[ kraxel: fix 32bit build ]
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit a2bebfd6e0)
[AF: BSC#924018]
Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Bruce Rogers <brogers@suse.com>
2016-03-03 10:21:46 -07:00
Petr Matousek
7c08e75ea8 fdc: force the fifo access to be in bounds of the allocated buffer
During processing of certain commands such as FD_CMD_READ_ID and
FD_CMD_DRIVE_SPECIFICATION_COMMAND the fifo memory access could
get out of bounds leading to memory corruption with values coming
from the guest.

Fix this by making sure that the index is always bounded by the
allocated memory.

This is CVE-2015-3456.

Signed-off-by: Petr Matousek <pmatouse@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit e907746266)
[AF: BOO#929339]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-14 19:11:21 +02:00
Alexander Graf
a12bee4196 linux-user: Convert blkpg to use a special subop handler
The blkpg ioctl can take different payloads depending on the opcode in
its payload structure. Create a new special ioctl handler that can only
deal with partition style ones for now.

Signed-off-by: Alexander Graf <agraf@suse.de>

---

Andreas, if you like feel free to squash this into your patch and submit
it upstream.
2015-05-14 18:45:44 +02:00
Alexander Graf
9d0eb9e687 linux-user: Cast validity checks on g_posix_timers range
We check whether the passed in counter value is negative on all calls
that involve g_posix_timers. However, we also check check for negativity
of that value after casting it - at which point it couldn't possibly be
negative anymore.

Cast the check to int16_t. Maybe this is correct. Maybe the check should
get removed completely.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-05-14 18:45:44 +02:00
Andreas Färber
4cb86557d5 qtest: Increase socket timeout
Change from 5 to 15 seconds.

Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-14 18:45:44 +02:00
Dinar Valeev
e00222a914 configure: Enable PIE for ppc and ppc64 hosts
Signed-off-by: Dinar Valeev <dvaleev@suse.com>
[AF: Rebased for v1.7]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-14 18:45:22 +02:00
Bruce Rogers
fc01ea235f virtfs-proxy-helper: Provide __u64 for broken sys/capability.h
Fixes the build on SLE 11 SP2.

[AF: Extend to ppc64]
2015-05-14 18:45:22 +02:00
Alexander Graf
2d9b6ce046 linux-user: lseek: explicitly cast non-set offsets to signed
When doing lseek, SEEK_SET indicates that the offset is an unsigned variable.
Other seek types have parameters that can be negative.

When converting from 32bit to 64bit parameters, we need to take this into
account and enable SEEK_END and SEEK_CUR to be negative, while SEEK_SET stays
absolute positioned which we need to maintain as unsigned.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-05-14 18:45:22 +02:00
Alexander Graf
0c1690a0da Make char muxer more robust wrt small FIFOs
Virtio-Console can only process one character at a time. Using it on S390
gave me strage "lags" where I got the character I pressed before when
pressing one. So I typed in "abc" and only received "a", then pressed "d"
but the guest received "b" and so on.

While the stdio driver calls a poll function that just processes on its
queue in case virtio-console can't take multiple characters at once, the
muxer does not have such callbacks, so it can't empty its queue.

To work around that limitation, I introduced a new timer that only gets
active when the guest can not receive any more characters. In that case
it polls again after a while to check if the guest is now receiving input.

This patch fixes input when using -nographic on s390 for me.
2015-05-14 18:45:22 +02:00
Alexander Graf
81460170a4 console: add question-mark escape operator
Some termcaps (found using SLES11SP1) use [? sequences. According to man
console_codes (http://linux.die.net/man/4/console_codes) the question mark
is a nop and should simply be ignored.

This patch does exactly that, rendering screen output readable when
outputting guest serial consoles to the graphical console emulator.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-05-14 18:45:22 +02:00
Alexander Graf
bafad6c118 Legacy Patch kvm-qemu-preXX-report-default-mac-used.patch 2015-05-14 18:45:22 +02:00
Alexander Graf
5bf559d81b Legacy Patch kvm-qemu-preXX-dictzip3.patch 2015-05-14 18:45:22 +02:00
Alexander Graf
6cf458a7de block: Add tar container format
Tar is a very widely used format to store data in. Sometimes people even put
virtual machine images in there.

So it makes sense for qemu to be able to read from tar files. I implemented a
written from scratch reader that also knows about the GNU sparse format, which
is what pigz creates.

This version checks for filenames that end on well-known extensions. The logic
could be changed to search for filenames given on the command line, but that
would require changes to more parts of qemu.

The tar reader in conjunctiuon with dzip gives us the chance to download
tar'ed up virtual machine images (even via http) and instantly make use of
them.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Bruce Rogers <brogers@novell.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
[TH: Use bdrv_open options instead of filename]
Signed-off-by: Tim Hardeck <thardeck@suse.de>
[AF: bdrv_file_open got an Error **errp argument, bdrv_delete -> brd_unref]
[AF: qemu_opts_create_nofail() -> qemu_opts_create(),
     bdrv_file_open() -> bdrv_open(), based on work by brogers]
[AF: error_is_set() dropped for v2.1.0-rc0]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-14 18:45:22 +02:00
Alexander Graf
6ee088c29a block: Add support for DictZip enabled gzip files
DictZip is an extension to the gzip format that allows random seeks in gzip
compressed files by cutting the file into pieces and storing the piece offsets
in the "extra" header of the gzip format.

Thanks to that extension, we can use gzip compressed files as block backend,
though only in read mode.

This makes a lot of sense when stacked with tar files that can then be shipped
to VM users. If a VM image is inside a tar file that is inside a DictZip
enabled gzip file, the user can run the tar.gz file as is without having to
extract the image first.

Tar patch follows.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Bruce Rogers <brogers@novell.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
[TH: Use bdrv_open options instead of filename]
Signed-off-by: Tim Hardeck <thardeck@suse.de>
[AF: Error **errp added for bdrv_file_open, bdrv_delete -> bdrv_unref]
[AF: qemu_opts_create_nofail() -> qemu_opts_create(),
     bdrv_file_open() -> bdrv_open(), based on work by brogers]
[AF: error_is_set() dropped for v2.1.0-rc0]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-14 18:45:22 +02:00
Alexander Graf
a57e04f9a7 linux-user: use target_ulong
Linux syscalls pass pointers or data length or other information of that sort
to the kernel. This is all stuff you don't want to have sign extended.
Otherwise a host 64bit variable parameter with a size parameter will extend
it to a negative number, breaking lseek for example.

Pass syscall arguments as ulong always.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-05-14 18:45:21 +02:00
Alexander Graf
553d073953 linux-user: add more blk ioctls
Implement a few more ioctls that operate on block devices.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-05-14 18:45:21 +02:00
Andreas Färber
34ca19a939 vnc: password-file= and incoming-connections=
TBD (from SUSE Studio team)
2015-05-14 18:45:21 +02:00
Andreas Färber
48e18465b5 slirp: -nooutgoing
TBD (from SUSE Studio team)
2015-05-14 18:45:21 +02:00
Alexander Graf
d60f7cc6d6 linux-user: XXX disable fiemap
agraf: fiemap breaks in libarchive. Disable it for now.
2015-05-14 18:45:21 +02:00
Alexander Graf
c7b3faed1f linux-user: implement FS_IOC_SETFLAGS ioctl
Signed-off-by: Alexander Graf <agraf@suse.de>

---

v1 -> v2

  - use TYPE_LONG instead of TYPE_INT
2015-05-14 18:45:21 +02:00
Alexander Graf
da82f4dfc7 linux-user: implement FS_IOC_GETFLAGS ioctl
Signed-off-by: Alexander Graf <agraf@suse.de>

---

v1 -> v2:

  - use TYPE_LONG instead of TYPE_INT
2015-05-14 18:45:21 +02:00
Alexander Graf
b353cd5c19 linux-user: Fake /proc/cpuinfo
Fedora 17 for ARM reads /proc/cpuinfo and fails if it doesn't contain
ARM related contents. This patch implements a quick hack to expose real
/proc/cpuinfo data taken from a real world machine.

The real fix would be to generate at least the flags automatically based
on the selected CPU. Please do not submit this patch upstream until this
has happened.

Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased for v1.6 and v1.7]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-14 18:45:21 +02:00
Alexander Graf
753800483d linux-user: lock tb flushing too
Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased onto exec.c/translate-all.c split for 1.4]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-14 18:45:21 +02:00
Alexander Graf
4a46dfb3e1 linux-user: Run multi-threaded code on a single core
Running multi-threaded code can easily expose some of the fundamental
breakages in QEMU's design. It's just not a well supported scenario.

So if we pin the whole process to a single host CPU, we guarantee that
we will never have concurrent memory access actually happen. We can still
get scheduled away at any time, so it's no complete guarantee, but apparently
it reduces the odds well enough to get my test cases to pass.

This gets Java 1.7 working for me again on my test box.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-05-14 18:45:20 +02:00
Alexander Graf
369b8fe953 linux-user: lock tcg
The tcg code generator is not thread safe. Lock its generation between
different threads.

Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased onto exec.c/translate-all.c split for 1.4]
[AF: Rebased for v2.1.0-rc0]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-14 18:45:20 +02:00
Alexander Graf
e1e02c2817 linux-user: Ignore broken loop ioctl
During invocations of losetup, we run into an ioctl that doesn't
exist. However, because of that we output an error, which then
screws up the kiwi logic around that call.

So let's silently ignore that bogus ioctl.

Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased for v2.1.0-rc0]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-14 18:45:20 +02:00
Alexander Graf
385bfd1d59 target-arm: linux-user: no tb_flush on reset
When running automoc4 as linux-user guest program, it segfaults right after
it creates a thread. Bisecting pointed to commit a84fac1426 which introduces
tb_flush on reset.

So something in our thread creation is broken. But for now, let's revert the
change to at least get a working build again.

[AF: Rebased, fixed typo]
2015-05-14 18:45:20 +02:00
Alexander Graf
2d79f44cf7 linux-user: binfmt: support host binaries
When we have a working host binary equivalent for the guest binary we're
trying to run, let's just use that instead as it will be a lot faster.

Signed-off-by: Alexander Graf <agraf@suse.de>
2015-05-14 18:45:20 +02:00
Alexander Graf
0cf98cdf19 linux-user: fix segfault deadlock
When entering the guest we take a lock to ensure that nobody else messes
with our TB chaining while we're doing it. If we get a segfault inside that
code, we manage to work on, but will not unlock the lock.

This patch forces unlocking of that lock in the segv handler. I'm not sure
this is the right approach though. Maybe we should rather make sure we don't
segfault in the code? I would greatly appreciate someone more intelligible
than me to look at this :).

Example code to trigger this is at: http://csgraf.de/tmp/conftest.c

Reported-by: Fabio Erculiani <lxnay@sabayon.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-14 18:45:20 +02:00
Alexander Graf
9c2c4ede3f PPC: KVM: Disable mmu notifier check
When using hugetlbfs (which is required for HV mode KVM on 970), we
check for MMU notifiers that on 970 can not be implemented properly.

So disable the check for mmu notifiers on PowerPC guests, making
KVM guests work there, even if possibly racy in some odd circumstances.
2015-05-14 18:45:20 +02:00
Alexander Graf
fba9a69b2d linux-user: add binfmt wrapper for argv[0] handling
When using qemu's linux-user binaries through binfmt, argv[0] gets lost
along the execution because qemu only gets passed in the full file name
to the executable while argv[0] can be something completely different.

This breaks in some subtile situations, such as the grep and make test
suites.

This patch adds a wrapper binary called qemu-$TARGET-binfmt that can be
used with binfmt's P flag which passes the full path _and_ argv[0] to
the binfmt handler.

The binary would be smart enough to be versatile and only exist in the
system once, creating the qemu binary path names from its own argv[0].
However, this seemed like it didn't fit the make system too well, so
we're currently creating a new binary for each target archictecture.

CC: Reinhard Max <max@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased onto new Makefile infrastructure, twice]
[AF: Updated for aarch64 for v2.0.0-rc1]
[AF: Rebased onto Makefile changes for v2.1.0-rc0]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-14 18:45:20 +02:00
Ulrich Hecht
03e6616f4e block/vmdk: Support creation of SCSI VMDK images in qemu-img
Signed-off-by: Ulrich Hecht <uli@suse.de>
[AF: Changed BLOCK_FLAG_SCSI from 8 to 16 for v1.2]
[AF: Rebased onto upstream VMDK SCSI support]
[AF: Rebased onto skipping of image creation in v1.7]
[AF: Simplified in preparation for v1.7.1/v2.0]
[AF: Rebased onto QemuOpts conversion for v2.1]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-14 18:45:20 +02:00
Alexander Graf
d5a7bad50d qemu-cvs-ioctl_nodirection
the direction given in the ioctl should be correct so we can assume the
communication is uni-directional. The alsa developers did not like this
concept though and declared ioctls IOC_R and IOC_W even though they were
IOC_RW.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2015-05-14 18:45:20 +02:00
Alexander Graf
f68411729f qemu-cvs-ioctl_debug
Extends unsupported ioctl debug output.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2015-05-14 18:45:19 +02:00
Ulrich Hecht
fdab3c0820 qemu-cvs-gettimeofday
No clue what this is for.
2015-05-14 18:45:19 +02:00
Alexander Graf
5b886ffe03 qemu-cvs-alsa_mmap
Hack to prevent ALSA from using mmap() interface to simplify emulation.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2015-05-14 18:45:19 +02:00
Alexander Graf
42ebc64ebe qemu-cvs-alsa_ioctl
Implements ALSA ioctls on PPC hosts.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2015-05-14 18:45:19 +02:00
Alexander Graf
f61d4e0f06 qemu-cvs-alsa_bitfield
Implements TYPE_INTBITFIELD partially. (required for ALSA support)

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2015-05-14 18:45:19 +02:00
Ulrich Hecht
614566635b qemu-0.9.0.cvs-binfmt
Fixes binfmt_misc setup script:
- x86_64 is i386-compatible
- m68k signature fixed
- path to QEMU

Signed-off-by: Ulrich Hecht <uli@suse.de>
[AF: Update path for qemu-aarch64 for v2.0.0-rc1]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-14 18:45:19 +02:00
Alexander Graf
f345dbe344 XXX work around SA_RESTART race with boehm-gc (ARM only)
[AF: CPUState -> CPUArchState, adapt to reindentation]
[AF: CPUArchState::opaque -> CPUState::opaque]
2015-05-14 18:45:19 +02:00
Alexander Graf
ae218e8182 XXX dont dump core on sigabort 2015-05-14 18:45:18 +02:00
Michael Roth
c2b0926634 Update version for v2.1.3 release
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-21 19:16:38 -06:00
Marcel Apfelbaum
b316937d38 vl.c: fix regression when reading machine type from config file
After 'Machine as QOM' series the machine type input triggers
the creation of the machine class.
If the machine type is set in the configuration file, the machine
class is not updated accordingly and remains the default.

Fixed that by querying the machine options after the configuration
file is loaded.

Cc: qemu-stable@nongnu.org
Reported-by: William Dauchy <william@gandi.net>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 364c3e6b8d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:44 -06:00
David Gibson
5b5c7bf8e5 PPC: Fix crash on spapr_tce_table_finalize()
spapr_tce_table_finalize() can SEGV if the object was not previously
realized.  In particular this can be triggered by running
         qemu-system-ppc -device spapr-tce-table,?

The basic problem is that we have mismatched initialization versus
finalization: spapr_tce_table_finalize() is attempting to undo things that
are done in spapr_tce_table_realize(), not an instance_init function.

Therefore, replace spapr_tce_table_finalize() with
spapr_tce_table_unrealize().

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Cc: qemu-stable@nongnu.org
Signed-off-by: Alexander Graf <agraf@suse.de>
(cherry picked from commit 5f9490de56)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:44 -06:00
Paolo Bonzini
6df8cd2e27 atomic: fix position of volatile qualifier
What needs to be volatile is not the pointer, but the pointed-to
value!

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 2cbcfb281a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:44 -06:00
Vladimir Sementsov-Ogievskiy
ff2fff6211 migration/block: fix pending() return value
Because of wrong return value of .save_live_pending() in
migration/block.c, migration finishes before the whole disk is
transferred. Such situation occurs when the migration process is fast
enough, for example when source and dest are on the same host.

If in the bulk phase we return something < max_size, we will skip
transferring the tail of the device. Currently we have "set pending to
BLOCK_SIZE if it is zero" for bulk phase, but there no guarantee, that
it will be < max_size.

True approach is to return, for example, max_size+1 when we are in the
bulk phase.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@parallels.com>
Message-id: 1419933856-4018-2-git-send-email-vsementsov@parallels.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 04636dc410)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:44 -06:00
Igor Mammedov
83a66746c0 pc: acpi: mark all possible CPUs as enabled in SRAT
If QEMU is started with  -numa ... Windows only notices that
CPU has been hot-added but it will not online such CPUs.

It's caused by the fact that possible CPUs are flagged as
not enabled in SRAT and Windows honoring that information
doesn't use corresponding CPU.

ACPI 5.0 Spec regarding to flag says:
"
Table 5-47 Local APIC Flags
...
Enabled: if zero, this processor is unusable, and the operating system
support will not attempt to use it.
"

Fix QEMU to adhere to spec and mark possible CPUs as enabled
in SRAT.

With that Windows onlines hot-added CPUs as expected.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit dd0247e09a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:43 -06:00
Max Filippov
39639d81e3 target-xtensa: test cross-page opcode
Alter cross-page TB test to also test cross-page opcode.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
(cherry picked from commit 85d36377e4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:43 -06:00
Max Filippov
6e64c4e6f1 target-xtensa: fix translation for opcodes crossing page boundary
If TB ends with an opcode that crosses page boundary and the following
page is not executable then EPC1 for the code fetch exception wrongly
points at the beginning of the TB. Always treat instruction that crosses
page boundary as a separate TB.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
(cherry picked from commit 01673a3401)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:43 -06:00
Peter Maydell
73c1527f96 audio: Don't free hw resources until after hw backend is stopped
When stopping an audio voice, call the audio backend's fini
method before calling audio_pcm_hw_free_resources_ rather than
afterwards. This allows backends which use helper threads (like
pulseaudio) to terminate those threads before the conv_buf or
mix_buf are freed and avoids race conditions where the helper
may access a NULL pointer or freed memory.

Cc: qemu-stable@nongnu.org
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1418406239-9838-1-git-send-email-peter.maydell@linaro.org
(cherry picked from commit b28fb27b5e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:43 -06:00
Paolo Bonzini
b466e1731b linuxboot: fix loading old kernels
Old kernels that used high memory only allowed the initrd to be in the
first 896MB of memory.  If you load the initrd above, they complain
that "initrd extends beyond end of memory".

In order to fix this, while not breaking machines with small amounts
of memory fixed by cdebec5 (linuxboot: compute initrd loading address,
2014-10-06), we need to distinguish two cases.  If pc.c placed the
initrd at end of memory, use the new algorithm based on the e801
memory map.  If instead pc.c placed the initrd at the maximum address
specified by the bzImage, leave it there.

The only interesting part is that the low-memory info block is now
loaded very early, in real mode, and thus the 32-bit address has
to be converted into a real mode segment.  The initrd address is
also patched in the info block before entering real mode, it is
simpler that way.

This fixes booting the RHEL4.8 32-bit installation image with 1GB
of RAM.

Cc: qemu-stable@nongnu.org
Cc: mst@redhat.com
Cc: jsnow@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 269e235849)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:43 -06:00
Paolo Bonzini
6a47ae2d41 linuxboot: compute initrd loading address
Even though hw/i386/pc.c tries to compute a valid loading address for the
initrd, close to the top of RAM, this does not take into account other
data that is malloced into that memory by SeaBIOS.

Luckily we can easily look at the memory map to find out how much memory is
used up there.  This patch places the initrd in the first four gigabytes,
below the first hole (as returned by INT 15h, AX=e801h).

Without this patch:
[    0.000000] init_memory_mapping: [mem 0x07000000-0x07fdffff]
[    0.000000] RAMDISK: [mem 0x0710a000-0x07fd7fff]

With this patch:
[    0.000000] init_memory_mapping: [mem 0x07000000-0x07fdffff]
[    0.000000] RAMDISK: [mem 0x07112000-0x07fdffff]

So linuxboot is able to use the 64k that were added as padding for
QEMU <= 2.1.

Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit cdebec5e40)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:43 -06:00
Kevin Wolf
5f0681e1c3 block: Don't probe for unknown backing file format
If a qcow2 image specifies a backing file format that doesn't correspond
to any format driver that qemu knows, we shouldn't fall back to probing,
but simply error out.

Not looking up the backing file driver in bdrv_open_backing_file(), but
just filling in the "driver" option if it isn't there moves us closer to
the goal of having everything in QDict options and gets us the error
handling of bdrv_open(), which correctly refuses unknown drivers.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 1416935562-7760-4-git-send-email-kwolf@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit c5f6e493bb)

Conflicts:
	tests/qemu-iotests/group

*removed context from upstream iotest groups

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:43 -06:00
Kevin Wolf
75eb0f5dbb qcow2.py: Add required padding for header extensions
The qcow2 specification requires that the header extension data be
padded to round up the extension size to the next multiple of 8 bytes.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 1416935562-7760-3-git-send-email-kwolf@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 8884dd1bbc)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
(cherry picked from commit a163ac3f57b5baa117158f7c0488d276ba3377e2)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:42 -06:00
Kevin Wolf
b495764ae8 qcow2: Fix header extension size check
After reading the extension header, offset is incremented, but not
checked against end_offset any more. This way an integer overflow could
happen when checking whether the extension end is within the allowed
range, effectively disabling the check.

This patch adds the missing check and a test case for it.

Cc: qemu-stable@nongnu.org
Reported-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 1416935562-7760-2-git-send-email-kwolf@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 2ebafc854d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:42 -06:00
Gary R Hook
21640bf6e0 block migration: fix return value
Modify block_save_iterate() to return positive/zero/negative
(success/not done/failure) return status. The computation of
the blocks transferred (an int64_t) exceeds the size of an
int return value.

Signed-off-by: Gary R Hook <gary.hook@nimboxx.com>
Reviewed-by: ChenLiang <chenliang88@huawei.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1416958202-15913-1-git-send-email-gary.hook@nimboxx.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit ebd9fbd7e1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:42 -06:00
Max Reitz
6bbb939a80 block/raw-posix: Fix ret in raw_open_common()
The return value must be negative on error; there is one place in
raw_open_common() where errp is set, but ret remains 0. Fix it.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 01212d4ed6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:42 -06:00
Max Reitz
178ed9aad3 qcow2: Respect bdrv_truncate() error
bdrv_truncate() may fail and qcow2_write_compressed() should return the
error code in that case.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 6a69b9620a)

Conflicts:
	block/qcow2.c

*removed context dependency on 75d3d21

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:42 -06:00
Max Reitz
0505d48c83 qcow2: Flushing the caches in qcow2_close may fail
qcow2_cache_flush() may fail; if one of the caches failed to be flushed
successfully to disk in qcow2_close() the image should not be marked
clean, and we should emit a warning.

This breaks the (qcow2-specific) iotests 026, 071 and 089; change their
output accordingly.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 3b5e14c76a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:42 -06:00
Paolo Bonzini
0073781fea blkdebug: report errors on flush too
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 9e52c53b8c)

*included to maintain parity with unit tests which inject errors
 via blkdebug. needed for:
 "qcow2: Flushing the caches in qcow2_close may fail"

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-14 17:08:42 -06:00
Max Reitz
175117c159 qcow2: Prevent numerical overflow
In qcow2_alloc_cluster_offset(), *num is limited to
INT_MAX >> BDRV_SECTOR_BITS by all callers. However, since remaining is
of type uint64_t, we might as well cast *num to that type before
performing the shift.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 11c89769dc)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 15:11:53 -06:00
Max Reitz
aa58eedb35 iotests: Add test for unsupported image creation
Add a test for creating and amending images (amendment uses the creation
options) with formats not supporting creation over protocols not
supporting creation.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 2247798d13)

Conflicts:
	tests/qemu-iotests/group

*removed context dependencies from upstream iotest groups

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 15:10:25 -06:00
Max Reitz
e6c172ad9e iotests: Only kill NBD server if it runs
There may be NBD tests which do not create a sample image and simply
test whether wrong usage of the protocol is rejected as expected. In
this case, there will be no NBD server and trying to kill it during
clean-up will fail.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit f798068c56)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 15:08:47 -06:00
Max Reitz
07ede68671 qemu-img: Check create_opts before image amendment
The image options which can be amended are described by the .create_opts
field for every driver. This field must therefore be non-NULL so that
anything can be amended in the first place. Check that this holds true
before going into qemu_opts_create() (because if .create_opts is NULL,
the create_opts pointer in img_amend() will be NULL after
qemu_opts_append()).

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit b2439d26f0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 15:08:35 -06:00
Max Reitz
2fbad1f944 qemu-img: Check create_opts before image creation
If a driver supports image creation, it needs to set the .create_opts
field. We can use that to make sure .create_opts for both drivers
involved is not NULL for the target image in qemu-img convert, which is
important so that the create_opts pointer in img_convert() is not NULL
after the qemu_opts_append() calls and when going into
qemu_opts_create().

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit f75613cf24)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 15:08:20 -06:00
Max Reitz
dee284885a block: Check create_opts before image creation
If a driver supports image creation, it needs to set the .create_opts
field. We can use that to make sure .create_opts for both drivers
involved is not NULL in bdrv_img_create(), which is important so that
the create_opts pointer in that function is not NULL after the
qemu_opts_append() calls and when going into qemu_opts_create().

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit c614972408)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 15:07:52 -06:00
Max Reitz
ad0983b5d1 block/nfs: Add create_opts
The nfs protocol driver is capable of creating images, but did not
specify any creation options. Fix it.

A way to test this issue is the following:

$ qemu-img create -f nfs nfs://127.0.0.1/foo.qcow2 64M

Without this patch, it segfaults. With this patch, it does not. However,
this is not something that should really work; qemu-img should check
whether the parameter for the -f option (and -O for convert) is indeed a
format, and error out if it is not. Therefore, I am not making it an
iotest.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit fd752801ae)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 15:07:43 -06:00
Max Reitz
b3729b2ec2 block/vvfat: qcow driver may not be found
Although virtually impossible right now, bdrv_find_format("qcow") may
fail. The vvfat block driver should heed that case.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 1bcb15cf77)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 15:07:33 -06:00
Max Reitz
1b9ea8961a block: Omit bdrv_find_format for essential drivers
We can always assume raw, file and qcow2 being available; so do not use
bdrv_find_format() to locate their BlockDriver objects but statically
reference the respective objects.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit ef8104378c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 15:07:22 -06:00
Max Reitz
cdeb85cf24 block: Make essential BlockDriver objects public
There are some block drivers which are essential to QEMU and may not be
removed: These are raw, file and qcow2 (as the default non-raw format).
Make their BlockDriver objects public so they can be directly referenced
throughout the block layer without needing to call bdrv_find_format()
and having to deal with an error at runtime, while the real problem
occurred during linking (where raw, file or qcow2 were not linked into
qemu).

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 5f535a941e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 15:07:12 -06:00
Jason Wang
b28d7b585a virtio-net: fix unmap leak
virtio_net_handle_ctrl() and other functions that process control vq
request call iov_discard_front() which will shorten the iov. This will
lead unmapping in virtqueue_push() leaks mapping.

Fixes this by keeping the original iov untouched and using a temp variable
in those functions.

Cc: Wen Congyang <wency@cn.fujitsu.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-id: 1417082643-23907-1-git-send-email-jasowang@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 771b6ed37e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 14:58:53 -06:00
Don Slutz
cd2f44cc3e hw/ide/core.c: Prevent SIGSEGV during migration
The other callers to blk_set_enable_write_cache() in this file
already check for s->blk == NULL.

Signed-off-by: Don Slutz <dslutz@verizon.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1416259239-13281-1-git-send-email-dslutz@verizon.com
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 6b896ab261)

Conflicts:
	hw/ide/core.c

*removed dependency on 4be746345

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 14:57:45 -06:00
Peter Maydell
844470158c exec: Handle multipage ranges in invalidate_and_set_dirty()
The code in invalidate_and_set_dirty() needs to handle addr/length
combinations which cross guest physical page boundaries. This can happen,
for example, when disk I/O reads large blocks into guest RAM which previously
held code that we have cached translations for. Unfortunately we were only
checking the clean/dirty status of the first page in the range, and then
were calling a tb_invalidate function which only handles ranges that don't
cross page boundaries. Fix the function to deal with multipage ranges.

The symptoms of this bug were that guest code would misbehave (eg segfault),
in particular after a guest reboot but potentially any time the guest
reused a page of its physical RAM for new code.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1416167061-13203-1-git-send-email-peter.maydell@linaro.org
(cherry picked from commit f874bf905f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 14:47:42 -06:00
zhanghailiang
05c5febf8c l2tpv3: fix possible double free
freeaddrinfo(result) does not assign result = NULL, after frees it.
There will be a double free when it goes error case.
It is reported by covertiy.

Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 77374582ab)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 14:45:28 -06:00
zhanghailiang
de98dc9539 libcacard: fix resource leak
In function connect_to_qemu(), getaddrinfo() will allocate memory
that is stored into server, it should be freed by using freeaddrinfo()
before connect_to_qemu() return.

Cc: qemu-stable@nongnu.org
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 5bbebf6228)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 14:45:17 -06:00
Paolo Bonzini
0c80570170 virtio-scsi: work around bug in old BIOSes
Old BIOSes left some padding by mistake after the req_size/resp_size.
New QEMU does not like it, thinking it is a bidirectional command.

As a workaround, we can check if the ANY_LAYOUT bit is set; if not, we
always consider the first buffer as the virtio-scsi request/response,
because, back when QEMU did not support ANY_LAYOUT, it expected the
payload to start at the second element of the iovec.

This can show up during migration.

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 55783a5521)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 14:43:28 -06:00
Alexander Graf
14b51b6718 kvm: Fix memory slot page alignment logic
Memory slots have to be page aligned to get entered into KVM. There
is existing logic that tries to ensure that we pad memory slots that
are not page aligned to the biggest region that would still fit in the
alignment requirements.

Unfortunately, that logic is broken. It tries to calculate the start
offset based on the region size.

Fix up the logic to do the thing it was intended to do and document it
properly in the comment above it.

With this patch applied, I can successfully run an e500 guest with more
than 3GB RAM (at which point RAM starts overlapping subpage memory regions).

Cc: qemu-stable@nongnu.org
Signed-off-by: Alexander Graf <agraf@suse.de>
(cherry picked from commit f2a64032a1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 14:42:04 -06:00
Max Filippov
ea227e222b target-xtensa: add missing window check for entry
Entry opcode needs to check if moving to new register frame would cause
register window overflow. Entry used in function prologue never
overflows because preceding windowed call* opcode writes return address
to the target register window frame, causing overflow exceptions at the
point of call. But when a sequence of entry opcodes is used for register
window spilling there may not be a call or other opcode that would cause
window check between entries and they would not raise overflow exception
themselves resulting in data corruption.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
(cherry picked from commit 1b3e71f8ee)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 14:31:19 -06:00
Hannes Reinecke
aae114b7ed esp-pci: fixup deadlock with linux
A linux guest will be issuing messages:

[   32.124042] DC390: Deadlock in DataIn_0: DMA aborted unfinished: 000000 bytes remain!!
[   32.126348] DC390: DataIn_0: DMA State: 0

and the HBA will fail to work properly.
Reason is the emulation is not setting the 'DMA transfer done'
status correctly.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit c3543fb5fe)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 14:27:24 -06:00
Peter Maydell
cfa86bcb7d hw/ppc/spapr_pci.c: Avoid functions not in glib 2.12 (g_hash_table_iter_*)
The g_hash_table_iter_* functions for iterating through a hash table
are not present in glib 2.12, which is our current minimum requirement.
Rewrite the code to use g_hash_table_foreach() instead.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
(cherry picked from commit f8833a37c0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-07 14:18:31 -06:00
Zhang Haoyu
b57b7ec340 snapshot: add bdrv_drain_all() to bdrv_snapshot_delete() to avoid concurrency problem
If there are still pending i/o while deleting snapshot,
because deleting snapshot is done in non-coroutine context, and
the pending i/o read/write (bdrv_co_do_rw) is done in coroutine context,
so it's possible to cause concurrency problem between above two operations.
Add bdrv_drain_all() to bdrv_snapshot_delete() to avoid this problem.

Signed-off-by: Zhang Haoyu <zhanghy@sangfor.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 201410211637596311287@sangfor.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 3432a1929e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 18:40:28 -06:00
Max Filippov
f8c61ebdd2 hw/xtensa/xtfpga: treat uImage load address as virtual
U-boot for xtensa always treats uImage load address as virtual address.
This is important when booting uImage on xtensa core with MMUv2, because
MMUv2 has fixed non-identity virtual-to-physical mapping after reset.

Always do virtual-to-physical translation of uImage load address and
load uImage at the translated address. This fixes booting uImage kernels
on dc232b and other MMUv2 cores.

Cc: qemu-stable@nongnu.org
Reported-by: Waldemar Brodkorb <mail@waldemar-brodkorb.de>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
(cherry picked from commit 6d2e453053)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 18:39:24 -06:00
Max Filippov
c448fb7651 hw/core/loader: implement address translation in uimage loader
Such address translation is needed when load address recorded in uImage
is a virtual address. When the actual load address is requested, return
untranslated address: user that needs the translated address can always
apply translation function to it and those that need it untranslated
don't need to do the inverse translation.

Add translation function pointer and its parameter to uimage_load
prototype. Update all existing users.

No user-visible functional changes.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Alexander Graf <agraf@suse.de>
(cherry picked from commit 25bda50a0c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 18:39:10 -06:00
Aurelien Jarno
8239a583c1 tcg/mips: fix store softmmu slow path
Commit 9d8bf2d1 moved the softmmu slow path out of line and introduce a
regression at the same time by always calling tcg_out_tlb_load with
is_load=1. This makes impossible to run any significant code under
qemu-system-mips*.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 0a2923f848)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 18:36:20 -06:00
Ting Wang
cb91dce13e virtio-scsi: sense in virtio_scsi_command_complete
If req->resp.cmd.status is not GOOD, the address of sense for
qemu_iovec_from_buf should be modified from &req->resp to sense.

Cc: qemu-stable@nongnu.org
Signed-off-by: Ting Wang <kathy.wangting@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit b7890c40e5)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 18:27:21 -06:00
Petr Matousek
b2f1d90530 vnc: sanitize bits_per_pixel from the client
bits_per_pixel that are less than 8 could result in accessing
non-initialized buffers later in the code due to the expectation
that bytes_per_pixel value that is used to initialize these buffers is
never zero.

To fix this check that bits_per_pixel from the client is one of the
values that the rfb protocol specification allows.

This is CVE-2014-7815.

Signed-off-by: Petr Matousek <pmatouse@redhat.com>

[ kraxel: apply codestyle fix ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit e6908bfe8e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 18:26:44 -06:00
Jan Kiszka
5a6af97243 Make qemu_shutdown_requested signal-safe
qemu_shutdown_requested may be interrupted by qemu_system_killed. If the
latter sets shutdown_requested after qemu_shutdown_requested has read it
but before it was cleared, the shutdown event is lost. Fix this by using
atomic_xchg.

This provides a different fix for the problem which commit 15124e142
attempts to deal with. That commit breaks use of ^C to drop into gdb,
and so this approach is better (and 15124e142 can be reverted).

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
[PMM: commit message tweak]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

(cherry picked from commit 817ef04db2)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 18:25:45 -06:00
Ray Strode
90de7a03bb libcacard: don't free sign buffer while sign op is pending
commit 57f97834ef cleaned up
the cac_applet_pki_process_apdu function to have a single
exit point. Unfortunately, that commit introduced a bug
where the sign buffer can get free'd and nullified while
it's still being used.

This commit corrects the bug by introducing a boolean to
track whether or not the sign buffer should be freed in
the function exit path.

Signed-off-by: Ray Strode <rstrode@redhat.com>
Reviewed-by: Alon Levy <alon@pobox.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 81b49e8f89)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 18:13:49 -06:00
Max Reitz
57248587af qcow2: Do not overflow when writing an L1 sector
While writing an L1 table sector, qcow2_write_l1_entry() copies the
respective range from s->l1_table to the local "buf" array. The size of
s->l1_table does not have to be a multiple of L1_ENTRIES_PER_SECTOR;
thus, limit the index which is used for copying all entries to the L1
size.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Peter Lieven <pl@kamp.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit a1391444fe)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 18:12:17 -06:00
Gerd Hoffmann
ff830f9d88 vmware-vga: use vmsvga_verify_rect in vmsvga_fill_rect
Add verification to vmsvga_fill_rect, re-enable HW_FILL_ACCEL.

Cc: qemu-stable@nongnu.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Don Koch <dkoch@verizon.com>
(cherry picked from commit bd9ccd8517)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 17:41:34 -06:00
Gerd Hoffmann
82e8913341 vmware-vga: use vmsvga_verify_rect in vmsvga_copy_rect
Add verification to vmsvga_copy_rect, re-enable HW_RECT_ACCEL.

Cc: qemu-stable@nongnu.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Don Koch <dkoch@verizon.com>
(cherry picked from commit 61b41b4c20)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 17:41:19 -06:00
Gerd Hoffmann
38e6e1c6a3 vmware-vga: use vmsvga_verify_rect in vmsvga_update_rect
Switch vmsvga_update_rect over to use vmsvga_verify_rect.  Slight change
in behavior:  We don't try to automatically fixup rectangles any more.
In case we find invalid update requests we'll do a full-screen update
instead.

Cc: qemu-stable@nongnu.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Don Koch <dkoch@verizon.com>
(cherry picked from commit 1735fe1edb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 17:39:22 -06:00
Gerd Hoffmann
4bcf40b288 vmware-vga: add vmsvga_verify_rect
Add verification function for rectangles, returning
true if verification passes and false otherwise.

Cc: qemu-stable@nongnu.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Don Koch <dkoch@verizon.com>
(cherry picked from commit 07258900fd)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 17:38:57 -06:00
Gerd Hoffmann
8bf7738ff2 vmware-vga: CVE-2014-3689: turn off hw accel
Quick & easy stopgap for CVE-2014-3689:  We just compile out the
hardware acceleration functions which lack sanity checks.  Thankfully
we have capability bits for them (SVGA_CAP_RECT_COPY and
SVGA_CAP_RECT_FILL), so guests should deal just fine, in theory.

Subsequent patches will add the missing checks and re-enable the
hardware acceleration emulation.

Cc: qemu-stable@nongnu.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Don Koch <dkoch@verizon.com>
(cherry picked from commit 83afa38eb2)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 17:38:01 -06:00
Jan Kiszka
8100812711 pc: Fix disabling of vapic for compat PC models
We used to be able to address both the QEMU and the KVM APIC via "apic".
This doesn't work anymore. So we need to use their parent class to turn
off the vapic on machines that should not expose them.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

(cherry picked from commit df1fd4b541)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 16:06:25 -06:00
Gonglei
cf0276b7c0 virtio-9p: fix virtio-9p child refcount in transports
object_initialize() leaves the object with a refcount of 1.
object_property_add_child() adds its own reference which is
dropped again when the property is deleted.

The upshot of this is that we always have a refcount >= 1. Upon
unplug the virtio-9p child is not finalized!

Drop our reference after the child property has been added to the
parent.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 8f3d60e568)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 16:03:37 -06:00
Gonglei
b5ad76a709 virtio-9p: use aliases instead of duplicate qdev properties
virtio-9p-pci all duplicate the qdev properties of their
V9fsState child. This approach does not work well with
string or pointer properties since we must be careful
about leaking or double-freeing them.

Use the QOM alias property to forward property accesses to the
V9fsState child.  This way no duplication is necessary.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 48833071d9)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 16:03:30 -06:00
Gonglei
20dc758b7f virtio-balloon: fix virtio-balloon child refcount in transports
object_initialize() leaves the object with a refcount of 1.
object_property_add_child() adds its own reference which is dropped
again when the property is deleted.

The upshot of this is that we always have a refcount >= 1.  Upon hot
unplug the virtio-balloon child is not finalized!

Drop our reference after the child property has been added to the
parent.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 91ba212088)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 16:03:19 -06:00
Gonglei
0077793a00 virtio-rng: fix virtio-rng child refcount in transports
object_initialize() leaves the object with a refcount of 1.
object_property_add_child() adds its own reference which is dropped
again when the property is deleted.

The upshot of this is that we always have a refcount >= 1.  Upon hot
unplug the virtio-rng child is not finalized!

Drop our reference after the child property has been added to the
parent.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 352fa88dfb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 16:02:58 -06:00
Gonglei
c4164eae39 virtio-rng: use aliases instead of duplicate qdev properties
virtio-rng-{pci, s390, ccw} all duplicate the
qdev properties of their VirtIORNG child.
This approach does not work well with string or pointer
properties since we must be careful about leaking or
double-freeing them.

Use the QOM alias property to forward property accesses to the
VirtIORNG child.  This way no duplication is necessary.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 8ee486ae33)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 16:02:50 -06:00
Gonglei
8c64b47eeb virtio-serial: fix virtio-serial child refcount in transports
object_initialize() leaves the object with a refcount of 1.
object_property_add_child() adds its own reference which is dropped
again when the property is deleted.

The upshot of this is that we always have a refcount >= 1.  Upon hot
unplug the virtio-serial child is not finalized!

Drop our reference after the child property has been added to the
parent.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e77ca8b92a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 16:02:35 -06:00
Gonglei
aa383e9a83 virtio-serial: use aliases instead of duplicate qdev properties
virtio-serial-{pci, s390, ccw} all duplicate the
qdev properties of their VirtIOSerial child.
This approach does not work well with string or pointer
properties since we must be careful about leaking or
double-freeing them.

Use the QOM alias property to forward property accesses to the
VirtIOSerial child.  This way no duplication is necessary.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 4f456d8025)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 16:02:28 -06:00
Gonglei
f06c87b119 virtio/vhost-scsi: fix virtio-scsi/vhost-scsi child refcount in transports
object_initialize() leaves the object with a refcount of 1.
object_property_add_child() adds its own reference which is dropped
again when the property is deleted.

The upshot of this is that we always have a refcount >= 1.  Upon hot
unplug the virtio-scsi/vhost-scsi child is not finalized!

Drop our reference after the child property has been added to the
parent.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 1312f12bcc)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 16:02:13 -06:00
Gonglei
eb5388e260 virtio/vhost-scsi: use aliases instead of duplicate qdev properties
{virtio, vhost}-scsi-{pci, s390, ccw} all duplicate the
qdev properties of their VirtIOSCSI/VHostSCSI child.
This approach does not work well with string or pointer
properties since we must be careful about leaking or
double-freeing them.

Use the QOM alias property to forward property accesses to the
VirtIOSCSI/VHostSCSI child. This way no duplication is necessary.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit c39343fd81)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 16:01:43 -06:00
Gonglei
83f81f344f virtio-net: fix virtio-net child refcount in transports
object_initialize() leaves the object with a refcount of 1.
object_property_add_child() adds its own reference which is dropped
again when the property is deleted.

The upshot of this is that we always have a refcount >= 1.  Upon hot
unplug the virtio-net child is not finalized!

Drop our reference after the child property has been added to the
parent.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 6a0c6b5978)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 16:01:03 -06:00
Gonglei
b6bd501d6a virtio-net: use aliases instead of duplicate qdev properties
virtio-net-pci, virtio-net-s390, and virtio-net-ccw all duplicate the
qdev properties of their VirtIONet child. This approach does not work
well with string or pointer properties since we must be careful about
leaking or double-freeing them.

Use the QOM alias property to forward property accesses to the
VirtIONet child.  This way no duplication is necessary.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 7779edfeb1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 16:00:47 -06:00
Paolo Bonzini
0369529b37 vhost-scsi: use virtio_ldl_p
This helps for cross-endian configurations.

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 7ce0425575)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 16:00:06 -06:00
Eduardo Habkost
c29bf825ee smbios: Fix assertion on socket count calculation
QEMU currently allows the number of VCPUs to not be a multiple of the
number of threads per socket, but the smbios socket count calculation
introduced by commit c97294ec1b doesn't
take that into account, triggering an assertion. e.g.:

  $ ./x86_64-softmmu/qemu-system-x86_64 -smp 4,sockets=2,cores=6,threads=1
  qemu-system-x86_64: /home/ehabkost/rh/proj/virt/qemu/hw/i386/smbios.c:825: smbios_get_tables: Assertion `smbios_smp_sockets >= 1' failed.
  Aborted (core dumped)

Socket count calculation doesn't belong to smbios.c and should
eventually be moved to the main SMP topology configuration code. But
while we don't move the code, at least make it correct by rounding up
the division.

Cc: Gabriel Somlo <somlo@cmu.edu>
Cc: qemu-stable@nongnu.org
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-By: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

(cherry picked from commit 7dfddd7f88)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 15:58:49 -06:00
Zhang Haoyu
e2d402d0a1 snapshot: fix referencing wrong variable in while loop in do_delvm
The while loop variabal is "bs1",
but "bs" is always passed to bdrv_snapshot_delete_by_id_or_name.
Broken in commit a89d89d, v1.7.0.

Signed-off-by: Zhang Haoyu <zhanghy@sangfor.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit af95738754)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 15:55:00 -06:00
Michael Roth
4d492e8909 tests: avoid running duplicate qom-tests
Since 3687d532 we've been unconditionally adding qom-test to our qtests
for every arch. However, some archs inherit their tests from Makefile
variables for other archs, such as i386/x86_64,
microblaze/microblazeel, and xtensa/xtensaeb. Since these are evaluated
in a lazy manner, we ultimately end up adding qom-test twice.

In the case x86_64, where we have a large number of machine types that
we rerun qom-test for, this has lead to a fairly noticeable increase
in the overall run-time of `make check` (78s vs. 42s on my machine).
Similar speed-ups are visible for other such archs, but not nearly as
significant.

Fix this by only adding qom-test to an arch's test list if it's not
already present.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Cc: qemu-stable@nongnu.org
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 2b8419cb49)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 15:52:23 -06:00
zhanghailiang
45c46f20c6 pc-dimm: Don't check dimm->node when there is non-NUMA config
It should not break memory hotplug feature if there is non-NUMA option.

This patch would also allow to use pc-dimm as replacement for initial memory
for non-NUMA configs.

Note: After this patch, the memory hotplug can work normally for Linux guest OS
when there is non-NUMA option and NUMA option. But not support Windows guest OS
to hotplug memory with no-NUMA config, actully, it's Windows limitation.

Reviewed-By: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit fc50ff0666)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 15:49:49 -06:00
Andreas Färber
c4379ce8ef ivshmem: Fix fd leak on error
Reported-by: Stefan Hajnoczi <stefanha@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 3a31cff112)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 15:43:56 -06:00
Sebastian Krahmer
a95569d24f ivshmem: Fix potential OOB r/w access
Fix OOB access via malformed incoming_posn parameters
and check that requested memory is actually alloc'ed.

Signed-off-by: Sebastian Krahmer <krahmer@suse.de>
[AF: Rebased, cleanups, avoid fd leak]
Cc: qemu-stable@nongnu.org
Signed-off-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

(cherry picked from commit 34bc07c528)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 15:43:42 -06:00
Stefan Hajnoczi
15905fde7b ivshmem: validate incoming_posn value from server
Check incoming_posn to avoid out-of-bounds array accesses if the ivshmem
server on the host sends invalid values.

Cc: Cam Macdonell <cam@cs.ualberta.ca>
Reported-by: Sebastian Krahmer <krahmer@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
[AF: Tighten upper bound check for posn in close_guest_eventfds()]
Cc: qemu-stable@nongnu.org
Signed-off-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

(cherry picked from commit 363ba1c72f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 15:43:21 -06:00
Stefan Hajnoczi
f1a842948a ivshmem: Check ivshmem_read() size argument
The third argument to the fd_read() callback implemented by
ivshmem_read() is the number of bytes, not a flags field.  Fix this and
check we received enough bytes before accessing the buffer pointer.

Cc: Cam Macdonell <cam@cs.ualberta.ca>
Reported-by: Sebastian Krahmer <krahmer@suse.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
[AF: Handle partial reads via FIFO]
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-stable@nongnu.org
Signed-off-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

(cherry picked from commit a2e9011b41)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-06 15:43:03 -06:00
Damjan Marion
09d552b40f vhost-user: fix VIRTIO_NET_F_MRG_RXBUF negotiation
Header length check should happen only if backend is kernel. For user
backend there is no reason to reset this bit.

vhost-user code does not define .has_vnet_hdr_len so
VIRTIO_NET_F_MRG_RXBUF cannot be negotiated even if both sides
support it.

Signed-off-by: Damjan Marion <damarion@cisco.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit d8e80ae37a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-05 20:22:59 -06:00
Luiz Capitulino
d754428b9b virtio-balloon: fix integer overflow in memory stats feature
When a QMP client changes the polling interval time by setting
the guest-stats-polling-interval property, the interval value
is stored and manipulated as an int64_t variable.

However, the balloon_stats_change_timer() function, which is
used to set the actual timer with the interval value, takes
an int instead, causing an overflow for big interval values.

This commit fix this bug by changing balloon_stats_change_timer()
to take an int64_t and also it limits the polling interval value
to UINT_MAX to avoid other kinds of overflow.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit 1f9296b51a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-05 20:18:58 -06:00
Stratos Psomadakis
5d350980f6 monitor: Reset HMP mon->rs in CHR_EVENT_OPEN
Commit cdaa86a54 ("Add G_IO_HUP handler for socket chardev") exposed a bug in
the way the HMP monitor handles its command buffer. When a client closes the
connection to the monitor, tcp_chr_read() will detect the G_IO_HUP condition
and call tcp_chr_disconnect() to close the server-side connection too. Due to
the fact that monitor reads 1 byte at a time (for each tcp_chr_read()), the
monitor readline state / buffers might contain junk (i.e. a half-finished
command). Thus, without calling readline_restart() on mon->rs in
CHR_EVENT_OPEN, future HMP commands will fail.

Signed-off-by: Stratos Psomadakis <psomas@grnet.gr>
Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
(cherry picked from commit e5554e2015)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-05 09:46:07 -06:00
Fam Zheng
ff1f973003 qemu-iotests: Test missing "driver" key for blockdev-add
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
(cherry picked from commit fe509ee237)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-04 13:44:49 -06:00
Michael Roth
0b2d2e094a tests: add QMP input visitor test for unions with no discriminator
This is more of an exercise of the dealloc visitor, where it may
erroneously use an uninitialized discriminator field as indication
that union fields corresponding to that discriminator field/type are
present, which can lead to attempts to free random chunks of heap
memory.

Cc: qemu-stable@nongnu.org
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
(cherry picked from commit cb55111b4e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-04 13:44:20 -06:00
Michael Roth
4a58f3c2d8 qapi: dealloc visitor, implement visit_start_union
If the .data field of a QAPI Union is NULL, we don't need to free
any of the union fields.

Make use of the new visit_start_union interface to access this
information and instruct the generated code to not visit these
fields when this occurs.

Cc: qemu-stable@nongnu.org
Reported-by: Fam Zheng <famz@redhat.com>
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
(cherry picked from commit 146db9f919)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-04 13:44:04 -06:00
Michael Roth
96c6cf6d30 qapi: add visit_start_union and visit_end_union
In some cases an input visitor might bail out on filling out a
struct for various reasons, such as missing fields when running
in strict mode. In the case of a QAPI Union type, this may lead
to cases where the .kind field which encodes the union type
is uninitialized. Subsequently, other visitors, such as the
dealloc visitor, may use this .kind value as if it were
initialized, leading to assumptions about the union type which
in this case may lead to segfaults. For example, freeing an
integer value.

However, we can generally rely on the fact that the always-present
.data void * field that we generate for these union types will
always be NULL in cases where .kind is uninitialized (at least,
there shouldn't be a reason where we'd do this purposefully).

So pass this information on to Visitor implementation via these
optional start_union/end_union interfaces so this information
can be used to guard against the situation above. We will make
use of this information in a subsequent patch for the dealloc
visitor.

Cc: qemu-stable@nongnu.org
Reported-by: Fam Zheng <famz@redhat.com>
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
(cherry picked from commit cee2dedb85)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-04 13:43:48 -06:00
Pavel Dovgalyuk
b5fc105016 gdbstub: init mon_chr through qemu_chr_alloc
This patch initializes monitor for gdbstub with the qemu_chr_alloc function
instead of just allocating the memory. Initialization function call
is required, because it also creates chr_write_lock mutex, which is used
when writing to this character device.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 462efe9e53)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2015-01-04 13:41:55 -06:00
Peter Maydell
e1cf5a23d1 hw/arm/virt: fix pl011 and pl031 irq flags
The pl011 and pl031 devices both use level triggered interrupts,
but the device tree we construct was incorrectly telling the
kernel to configure the GIC to treat them as edge triggered.
This meant that output from the pl011 would hang after a while.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1410274423-9461-1-git-send-email-peter.maydell@linaro.org
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Cc: qemu-stable@nongnu.org
(cherry picked from commit 0be969a2d9)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-12-24 16:10:19 -06:00
Greg Kurz
490a0f887e spapr_pci: map the MSI window in each PHB
On sPAPR, virtio devices are connected to the PCI bus and use MSI-X.
Commit cc943c36fa has modified MSI-X
so that writes are made using the bus master address space and follow
the IOMMU path.

Unfortunately, the IOMMU address space address space does not have an
MSI window: the notification is silently dropped in unassigned_mem_write
instead of reaching the guest... The most visible effect is that all
virtio devices are non-functional on sPAPR since then. :(

This patch does the following:
1) map the MSI window into the IOMMU address space for each PHB
   - since each PHB instantiates its own IOMMU address space, we
     can safely map the window at a fixed address (SPAPR_PCI_MSI_WINDOW)
   - no real need to keep the MSI window setup in a separate function,
     the spapr_pci_msi_init() code moves to spapr_phb_realize().

2) kill the global MSI window as it is not needed in the end

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
(cherry picked from commit 8c46f7ec85)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-12-24 16:08:16 -06:00
Michael S. Tsirkin
e4fb3debc3 virtio-pci: enable bus master for old guests
commit cc943c36fa
    pci: Use bus master address space for delivering MSI/MSI-X messages
breaks virtio-net for rhel6.[56] x86 guests because they don't
enable bus mastering for virtio PCI devices. For the same reason,
rhel6.[56] ppc64 guests cannot boot on a virtio-blk disk anymore.

Old guests forgot to enable bus mastering, enable it automatically on
DRIVER (guests use some devices before DRIVER_OK).

Reported-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Reviewed-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Tested-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit e43c0b2ea5)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-12-24 16:08:16 -06:00
Jan Kiszka
7fb768ea30 pci: Use bus master address space for delivering MSI/MSI-X messages
The spec says (and real HW confirms this) that, if the bus master bit
is 0, the device will not generate any PCI accesses. MSI and MSI-X
messages fall among these, so we should use the corresponding address
space to deliver them. This will prevent delivery if bus master support
is disabled.

Cc: qemu-stable@nongnu.org
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit cc943c36fa)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-12-24 16:08:15 -06:00
Eduardo Habkost
2151206778 kvmclock: Add comment explaining why we need cpu_clean_all_dirty()
Try to explain why commit 317b0a6d8b
needed a cpu_clean_all_dirty() call just after calling
cpu_synchronize_all_states().

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Cc: Andrey Korolyov <andrey@xdel.ru>
Cc: Marcin Gibuła <m.gibula@beyond.pl>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 1154d84dcc)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-12-24 16:08:15 -06:00
Alexander Graf
c35ba0d9e4 kvmclock: Ensure time in migration never goes backward
When we migrate we ask the kernel about its current belief on what the guest
time would be. However, I've seen cases where the kvmclock guest structure
indicates a time more recent than the kvm returned time.

To make sure we never go backwards, calculate what the guest would have seen as time at the point of migration and use that value instead of the kernel returned one when it's more recent.
This bases the view of the kvmclock after migration on the
same foundation in host as well as guest.

Signed-off-by: Alexander Graf <agraf@suse.de>
Cc: qemu-stable@nongnu.org
Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 9a48bcd1b8)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-12-24 15:59:11 -06:00
Marcelo Tosatti
61048e1942 kvmclock: Ensure proper env->tsc value for kvmclock_current_nsec calculation
Ensure proper env->tsc value for kvmclock_current_nsec calculation.

Reported-by: Marcin Gibuła <m.gibula@beyond.pl>
Analyzed-by: Marcin Gibuła <m.gibula@beyond.pl>
Cc: qemu-stable@nongnu.org
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 317b0a6d8b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-12-24 15:59:00 -06:00
Marcelo Tosatti
a9ed61533f Introduce cpu_clean_all_dirty
Introduce cpu_clean_all_dirty, to force subsequent cpu_synchronize_all_states
to read in-kernel register state.

Cc: qemu-stable@nongnu.org
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit de9d61e83d)
Conflicts:
	kvm-all.c

*removed context dependency on kvm_cpu_synchronize_post_init

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-12-24 15:56:18 -06:00
Dr. David Alan Gilbert
3807aeb1d4 xhci PCIe endpoint migration compatibility fix
Add back the PCIe config capabilities on XHCI cards in non-PCIe slots,
but only for machine types before 2.1.

This fixes a migration incompatibility in the XHCI PCI devices
caused by:
   058fdcf52c - xhci: add endpoint cap on express bus only

Note that in fixing it for compatibility with older QEMUs, it breaks
compatibility with existing QEMU 2.1's on older machine types.

The status before this patch was (if it used an XHCI adapter):
   machine type | source qemu
     any           pre-2.1     - FAIL
     any           2.1...      - PASS

With this patch:
   machine type | source qemu
     any           pre-2.1    - PASS
     pre-2.1       2.1...     - FAIL
     2.1           2.1...     - PASS

A test to trigger it is to add '-device nec-usb-xhci,id=xhci,addr=0x12'
to the command line.

Cc: qemu-stable@nongnu.org
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit e6043e92c2)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-12-24 15:45:02 -06:00
Luiz Capitulino
ff3bd5e4bb exec: file_ram_alloc(): print error when prealloc fails
If memory allocation fails when using the -mem-prealloc command-line
option, QEMU exits without printing any error information to
the user:

 # qemu [...] -m 1G -mem-prealloc -mem-path /dev/hugepages
 # echo $?
 1

This commit adds an error message, so that we print instead:

 # qemu [...] -m 1G -mem-prealloc -mem-path /dev/hugepages
 qemu: unable to map backing store for hugepages: Cannot allocate memory

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit e4d9df4fb1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-12-24 15:43:39 -06:00
Gonglei
d6af26d6ce qdev: Add cleanup logic in device_set_realized() to avoid resource leak
At present, this function doesn't have partial cleanup implemented,
which will cause resource leaks in some scenarios.

Example:

1. Assume that "dc->realize(dev, &local_err)" executes successful
   and local_err == NULL;
2. device hotplug in hotplug_handler_plug() executes but fails
   (it is prone to occur). Then local_err != NULL;
3. error_propagate(errp, local_err) and return. But the resources
   which have been allocated in dc->realize() will be leaked.
Simple backtrace:
  dc->realize()
   |->device_realize
            |->pci_qdev_init()
                |->do_pci_register_device()
                |->etc.

Add fuller cleanup logic which assures that function can
goto appropriate error label as local_err population is
detected at each relevant point.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Andreas Färber <afaerber@suse.de>
(cherry picked from commit 1d45a705fc)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-12-24 15:36:22 -06:00
Gonglei
8bb90ee80a qdev: Use NULL instead of local_err for qbus_child unrealize
Forcefully unrealize all children regardless of errors in earlier
iterations (if any). We should keep going with cleanup operation
rather than report an error immediately. Therefore store the first
child unrealization failure and propagate it at the end. We also
forcefully unregister vmsd and unrealize actual object, too.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Andreas Färber <afaerber@suse.de>
(cherry picked from commit cd4520adca)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-12-24 15:35:32 -06:00
Michael Roth
562d6b4f7f Update version for v2.1.2 release
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-09-25 14:52:04 -05:00
Petr Matousek
9a72433843 slirp: udp: fix NULL pointer dereference because of uninitialized socket
When guest sends udp packet with source port and source addr 0,
uninitialized socket is picked up when looking for matching and already
created udp sockets, and later passed to sosendto() where NULL pointer
dereference is hit during so->slirp->vnetwork_mask.s_addr access.

Fix this by checking that the socket is not just a socket stub.

This is CVE-2014-3640.

Signed-off-by: Petr Matousek <pmatouse@redhat.com>
Reported-by: Xavier Mehrenberger <xavier.mehrenberger@airbus.com>
Reported-by: Stephane Duverger <stephane.duverger@eads.net>
Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Message-id: 20140918063537.GX9321@dhcp-25-225.brq.redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 01f7cecf00)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-09-24 11:11:52 -05:00
Michael S. Tsirkin
00dd2b22f6 pc: leave more space for BIOS allocations
Since QEMU 2.1, we are allocating more space for ACPI tables, so no
space is left after initrd for the BIOS to allocate memory.

Besides ACPI tables, there are a few other uses of high memory in
SeaBIOS: SMBIOS tables and USB drivers use it in particular.  These uses
allocate a very small amount of memory.  Malloc metadata also lives
there.  So we need _some_ extra padding there to avoid initrd breakage,
but not much.

John Snow found a case where RHEL5 was broken by the recent change to
ACPI_TABLE_SIZE; in his case 4KB of extra padding are fine, but just to
be safe I am adding 32KB, which is roughly the same amount of padding
that was left by QEMU 2.0 and earlier.

Move initrd to leave some space for the BIOS.

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reported-by: John Snow <jsnow@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 438f92ee9f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-09-23 10:48:06 -05:00
Michael S. Tsirkin
80f4d021f0 Revert "virtio: don't call device on !vm_running"
This reverts commit a1bc7b827e422e1ff065640d8ec5347c4aadfcd8.
    virtio: don't call device on !vm_running
It turns out that virtio net assumes that vm_running
is updated before device status callback in many places,
so this change leads to asserts.
Previous commit fixes the root issue that motivated
a1bc7b827e422e1ff065640d8ec5347c4aadfcd8 differently,
so there's no longer a need for this change.

In the future, we might be able to drop checking vm_running
completely, and check vm state directly.

Reported-by: Dietmar Maurer <dietmar@proxmox.com>
Cc: qemu-stable@nongnu.org
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 9e8e8c4865)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-09-23 10:48:06 -05:00
Michael S. Tsirkin
074e347138 virtio-net: drop assert on vm stop
On vm stop, vm_running state set to stopped
before device is notified, so callbacks can get envoked with
vm_running = false; and this is not an error.

Cc: qemu-stable@nongnu.org
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 131c5221fe)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-09-23 10:48:06 -05:00
Eduardo Habkost
9e8d994111 Revert "rng-egd: remove redundant free"
This reverts commit 5e490b6a50.

Cc: qemu-stable@nongnu.org
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit abb4d5f2e2)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-09-23 10:48:06 -05:00
Eduardo Habkost
a56b9cfd86 hw/machine: Free old values of string properties
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel.a@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Amos Kong <akong@redhat.com>
Cc: qemu-stable@nongnu.org
(cherry picked from commit 556068eed0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-09-23 10:48:06 -05:00
Greg Kurz
07178559a9 Revert "spapr_pci: map the MSI window in each PHB"
This patch is predicated on cc943c, which was dropped from
stable tree for other reasons.

This reverts commit 0824ca6bd1.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-09-23 10:48:06 -05:00
169 changed files with 7195 additions and 635 deletions

View File

@@ -34,6 +34,10 @@ endif
PROGS=$(QEMU_PROG) $(QEMU_PROGW)
STPFILES=
ifdef CONFIG_LINUX_USER
PROGS+=$(QEMU_PROG)-binfmt
endif
config-target.h: config-target.h-timestamp
config-target.h-timestamp: config-target.mak
@@ -101,6 +105,8 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
obj-y += linux-user/
obj-y += gdbstub.o thunk.o user-exec.o
obj-binfmt-y += linux-user/
endif #CONFIG_LINUX_USER
#########################################################
@@ -149,7 +155,11 @@ endif # CONFIG_SOFTMMU
# Workaround for http://gcc.gnu.org/PR55489, see configure.
%/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS)
ifdef CONFIG_LINUX_USER
dummy := $(call unnest-vars,,obj-y obj-binfmt-y)
else
dummy := $(call unnest-vars,,obj-y)
endif
all-obj-y := $(obj-y)
block-obj-y :=
@@ -167,6 +177,9 @@ all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
$(QEMU_PROG_BUILD): $(all-obj-y) ../libqemuutil.a ../libqemustub.a
$(call LINK,$^)
$(QEMU_PROG)-binfmt: $(obj-binfmt-y)
$(call LINK,$^)
gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
$(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@")

View File

@@ -1 +1 @@
2.1.1
2.1.3

View File

@@ -191,9 +191,9 @@ static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
audio_detach_capture (hw);
#endif
QLIST_REMOVE (hw, entries);
glue (hw->pcm_ops->fini_, TYPE) (hw);
glue (s->nb_hw_voices_, TYPE) += 1;
glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
glue (hw->pcm_ops->fini_, TYPE) (hw);
g_free (hw);
*hwp = NULL;
}

View File

@@ -24,33 +24,12 @@ typedef struct RngEgd
CharDriverState *chr;
char *chr_name;
GSList *requests;
} RngEgd;
typedef struct RngRequest
{
EntropyReceiveFunc *receive_entropy;
uint8_t *data;
void *opaque;
size_t offset;
size_t size;
} RngRequest;
static void rng_egd_request_entropy(RngBackend *b, size_t size,
EntropyReceiveFunc *receive_entropy,
void *opaque)
static void rng_egd_request_entropy(RngBackend *b, RngRequest *req)
{
RngEgd *s = RNG_EGD(b);
RngRequest *req;
req = g_malloc(sizeof(*req));
req->offset = 0;
req->size = size;
req->receive_entropy = receive_entropy;
req->opaque = opaque;
req->data = g_malloc(req->size);
size_t size = req->size;
while (size > 0) {
uint8_t header[2];
@@ -64,14 +43,6 @@ static void rng_egd_request_entropy(RngBackend *b, size_t size,
size -= len;
}
s->requests = g_slist_append(s->requests, req);
}
static void rng_egd_free_request(RngRequest *req)
{
g_free(req->data);
g_free(req);
}
static int rng_egd_chr_can_read(void *opaque)
@@ -80,7 +51,7 @@ static int rng_egd_chr_can_read(void *opaque)
GSList *i;
int size = 0;
for (i = s->requests; i; i = i->next) {
for (i = s->parent.requests; i; i = i->next) {
RngRequest *req = i->data;
size += req->size - req->offset;
}
@@ -93,8 +64,8 @@ static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size)
RngEgd *s = RNG_EGD(opaque);
size_t buf_offset = 0;
while (size > 0 && s->requests) {
RngRequest *req = s->requests->data;
while (size > 0 && s->parent.requests) {
RngRequest *req = s->parent.requests->data;
int len = MIN(size, req->size - req->offset);
memcpy(req->data + req->offset, buf + buf_offset, len);
@@ -103,38 +74,13 @@ static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size)
size -= len;
if (req->offset == req->size) {
s->requests = g_slist_remove_link(s->requests, s->requests);
req->receive_entropy(req->opaque, req->data, req->size);
rng_egd_free_request(req);
rng_backend_finalize_request(&s->parent, req);
}
}
}
static void rng_egd_free_requests(RngEgd *s)
{
GSList *i;
for (i = s->requests; i; i = i->next) {
rng_egd_free_request(i->data);
}
g_slist_free(s->requests);
s->requests = NULL;
}
static void rng_egd_cancel_requests(RngBackend *b)
{
RngEgd *s = RNG_EGD(b);
/* We simply delete the list of pending requests. If there is data in the
* queue waiting to be read, this is okay, because there will always be
* more data than we requested originally
*/
rng_egd_free_requests(s);
}
static void rng_egd_opened(RngBackend *b, Error **errp)
{
RngEgd *s = RNG_EGD(b);
@@ -169,6 +115,7 @@ static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
if (b->opened) {
error_set(errp, QERR_PERMISSION_DENIED);
} else {
g_free(s->chr_name);
s->chr_name = g_strdup(value);
}
}
@@ -201,8 +148,6 @@ static void rng_egd_finalize(Object *obj)
}
g_free(s->chr_name);
rng_egd_free_requests(s);
}
static void rng_egd_class_init(ObjectClass *klass, void *data)
@@ -210,7 +155,6 @@ static void rng_egd_class_init(ObjectClass *klass, void *data)
RngBackendClass *rbc = RNG_BACKEND_CLASS(klass);
rbc->request_entropy = rng_egd_request_entropy;
rbc->cancel_requests = rng_egd_cancel_requests;
rbc->opened = rng_egd_opened;
}

View File

@@ -21,10 +21,6 @@ struct RndRandom
int fd;
char *filename;
EntropyReceiveFunc *receive_func;
void *opaque;
size_t size;
};
/**
@@ -37,36 +33,35 @@ struct RndRandom
static void entropy_available(void *opaque)
{
RndRandom *s = RNG_RANDOM(opaque);
uint8_t buffer[s->size];
ssize_t len;
len = read(s->fd, buffer, s->size);
if (len < 0 && errno == EAGAIN) {
return;
while (s->parent.requests != NULL) {
RngRequest *req = s->parent.requests->data;
ssize_t len;
len = read(s->fd, req->data, req->size);
if (len < 0 && errno == EAGAIN) {
return;
}
g_assert(len != -1);
req->receive_entropy(req->opaque, req->data, len);
rng_backend_finalize_request(&s->parent, req);
}
g_assert(len != -1);
s->receive_func(s->opaque, buffer, len);
s->receive_func = NULL;
/* We've drained all requests, the fd handler can be reset. */
qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
}
static void rng_random_request_entropy(RngBackend *b, size_t size,
EntropyReceiveFunc *receive_entropy,
void *opaque)
static void rng_random_request_entropy(RngBackend *b, RngRequest *req)
{
RndRandom *s = RNG_RANDOM(b);
if (s->receive_func) {
s->receive_func(s->opaque, NULL, 0);
if (s->parent.requests == NULL) {
/* If there are no pending requests yet, we need to
* install our fd handler. */
qemu_set_fd_handler(s->fd, entropy_available, NULL, s);
}
s->receive_func = receive_entropy;
s->opaque = opaque;
s->size = size;
qemu_set_fd_handler(s->fd, entropy_available, NULL, s);
}
static void rng_random_opened(RngBackend *b, Error **errp)

View File

@@ -19,18 +19,20 @@ void rng_backend_request_entropy(RngBackend *s, size_t size,
void *opaque)
{
RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
RngRequest *req;
if (k->request_entropy) {
k->request_entropy(s, size, receive_entropy, opaque);
}
}
req = g_malloc(sizeof(*req));
void rng_backend_cancel_requests(RngBackend *s)
{
RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
req->offset = 0;
req->size = size;
req->receive_entropy = receive_entropy;
req->opaque = opaque;
req->data = g_malloc(req->size);
if (k->cancel_requests) {
k->cancel_requests(s);
k->request_entropy(s, req);
s->requests = g_slist_append(s->requests, req);
}
}
@@ -72,6 +74,30 @@ static void rng_backend_prop_set_opened(Object *obj, bool value, Error **errp)
s->opened = true;
}
static void rng_backend_free_request(RngRequest *req)
{
g_free(req->data);
g_free(req);
}
static void rng_backend_free_requests(RngBackend *s)
{
GSList *i;
for (i = s->requests; i; i = i->next) {
rng_backend_free_request(i->data);
}
g_slist_free(s->requests);
s->requests = NULL;
}
void rng_backend_finalize_request(RngBackend *s, RngRequest *req)
{
s->requests = g_slist_remove(s->requests, req);
rng_backend_free_request(req);
}
static void rng_backend_init(Object *obj)
{
object_property_add_bool(obj, "opened",
@@ -80,6 +106,13 @@ static void rng_backend_init(Object *obj)
NULL);
}
static void rng_backend_finalize(Object *obj)
{
RngBackend *s = RNG_BACKEND(obj);
rng_backend_free_requests(s);
}
static void rng_backend_class_init(ObjectClass *oc, void *data)
{
UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
@@ -92,6 +125,7 @@ static const TypeInfo rng_backend_info = {
.parent = TYPE_OBJECT,
.instance_size = sizeof(RngBackend),
.instance_init = rng_backend_init,
.instance_finalize = rng_backend_finalize,
.class_size = sizeof(RngBackendClass),
.class_init = rng_backend_class_init,
.abstract = true,

View File

@@ -652,6 +652,7 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
{
int ret;
int64_t last_ftell = qemu_ftell(f);
int64_t delta_ftell;
DPRINTF("Enter save live iterate submitted %d transferred %d\n",
block_mig_state.submitted, block_mig_state.transferred);
@@ -701,7 +702,14 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
}
qemu_put_be64(f, BLK_MIG_FLAG_EOS);
return qemu_ftell(f) - last_ftell;
delta_ftell = qemu_ftell(f) - last_ftell;
if (delta_ftell > 0) {
return 1;
} else if (delta_ftell < 0) {
return -1;
} else {
return 0;
}
}
/* Called with iothread lock taken. */
@@ -756,8 +764,8 @@ static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size)
block_mig_state.read_done * BLOCK_SIZE;
/* Report at least one block pending during bulk phase */
if (pending == 0 && !block_mig_state.bulk_completed) {
pending = BLOCK_SIZE;
if (pending <= max_size && !block_mig_state.bulk_completed) {
pending = max_size + BLOCK_SIZE;
}
blk_mig_unlock();
qemu_mutex_unlock_iothread();

39
block.c
View File

@@ -633,7 +633,7 @@ BlockDriver *bdrv_find_protocol(const char *filename,
}
if (!path_has_protocol(filename) || !allow_protocol_prefix) {
return bdrv_find_format("file");
return &bdrv_file;
}
p = strchr(filename, ':');
@@ -662,12 +662,7 @@ static int find_image_format(BlockDriverState *bs, const char *filename,
/* Return the raw BlockDriver * to scsi-generic devices or empty drives */
if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) {
drv = bdrv_find_format("raw");
if (!drv) {
error_setg(errp, "Could not find raw image format");
ret = -ENOENT;
}
*pdrv = drv;
*pdrv = &bdrv_raw;
return ret;
}
@@ -1182,7 +1177,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
{
char *backing_filename = g_malloc0(PATH_MAX);
int ret = 0;
BlockDriver *back_drv = NULL;
BlockDriverState *backing_hd;
Error *local_err = NULL;
@@ -1215,14 +1209,14 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
backing_hd = bdrv_new("", errp);
if (bs->backing_format[0] != '\0') {
back_drv = bdrv_find_format(bs->backing_format);
if (bs->backing_format[0] != '\0' && !qdict_haskey(options, "driver")) {
qdict_put(options, "driver", qstring_from_str(bs->backing_format));
}
assert(bs->backing_hd == NULL);
ret = bdrv_open(&backing_hd,
*backing_filename ? backing_filename : NULL, NULL, options,
bdrv_backing_flags(bs->open_flags), back_drv, &local_err);
bdrv_backing_flags(bs->open_flags), NULL, &local_err);
if (ret < 0) {
bdrv_unref(backing_hd);
backing_hd = NULL;
@@ -1296,7 +1290,6 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
char *tmp_filename = g_malloc0(PATH_MAX + 1);
int64_t total_size;
BlockDriver *bdrv_qcow2;
QemuOpts *opts = NULL;
QDict *snapshot_options;
BlockDriverState *bs_snapshot;
@@ -1322,11 +1315,10 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
goto out;
}
bdrv_qcow2 = bdrv_find_format("qcow2");
opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0,
opts = qemu_opts_create(bdrv_qcow2.create_opts, NULL, 0,
&error_abort);
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
ret = bdrv_create(bdrv_qcow2, tmp_filename, opts, &local_err);
ret = bdrv_create(&bdrv_qcow2, tmp_filename, opts, &local_err);
qemu_opts_del(opts);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not create temporary overlay "
@@ -1346,7 +1338,7 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
bs_snapshot = bdrv_new("", &error_abort);
ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
flags, bdrv_qcow2, &local_err);
flags, &bdrv_qcow2, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
goto out;
@@ -5535,6 +5527,18 @@ void bdrv_img_create(const char *filename, const char *fmt,
return;
}
if (!drv->create_opts) {
error_setg(errp, "Format driver '%s' does not support image creation",
drv->format_name);
return;
}
if (!proto_drv->create_opts) {
error_setg(errp, "Protocol driver '%s' does not support image creation",
proto_drv->format_name);
return;
}
create_opts = qemu_opts_append(create_opts, drv->create_opts);
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
@@ -5624,6 +5628,9 @@ void bdrv_img_create(const char *filename, const char *fmt,
if (!quiet) {
printf("Formatting '%s', fmt=%s ", filename, fmt);
qemu_opts_print(opts);
if (qemu_opt_get_bool(opts, BLOCK_OPT_SCSI, false)) {
printf(", SCSI");
}
puts("");
}

View File

@@ -24,6 +24,8 @@ common-obj-y += stream.o
common-obj-y += commit.o
common-obj-y += mirror.o
common-obj-y += backup.o
common-obj-y += dictzip.o
common-obj-y += tar.o
iscsi.o-cflags := $(LIBISCSI_CFLAGS)
iscsi.o-libs := $(LIBISCSI_LIBS)

View File

@@ -526,6 +526,25 @@ static BlockDriverAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
}
static BlockDriverAIOCB *blkdebug_aio_flush(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque)
{
BDRVBlkdebugState *s = bs->opaque;
BlkdebugRule *rule = NULL;
QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
if (rule->options.inject.sector == -1) {
break;
}
}
if (rule && rule->options.inject.error) {
return inject_error(bs, cb, opaque, rule);
}
return bdrv_aio_flush(bs->file, cb, opaque);
}
static void blkdebug_close(BlockDriverState *bs)
{
@@ -703,6 +722,7 @@ static BlockDriver bdrv_blkdebug = {
.bdrv_aio_readv = blkdebug_aio_readv,
.bdrv_aio_writev = blkdebug_aio_writev,
.bdrv_aio_flush = blkdebug_aio_flush,
.bdrv_debug_event = blkdebug_debug_event,
.bdrv_debug_breakpoint = blkdebug_debug_breakpoint,

596
block/dictzip.c Normal file
View File

@@ -0,0 +1,596 @@
/*
* DictZip Block driver for dictzip enabled gzip files
*
* Use the "dictzip" tool from the "dictd" package to create gzip files that
* contain the extra DictZip headers.
*
* dictzip(1) is a compression program which creates compressed files in the
* gzip format (see RFC 1952). However, unlike gzip(1), dictzip(1) compresses
* the file in pieces and stores an index to the pieces in the gzip header.
* This allows random access to the file at the granularity of the compressed
* pieces (currently about 64kB) while maintaining good compression ratios
* (within 5% of the expected ratio for dictionary data).
* dictd(8) uses files stored in this format.
*
* For details on DictZip see http://dict.org/.
*
* Copyright (c) 2009 Alexander Graf <agraf@suse.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu-common.h"
#include "block/block_int.h"
#include <zlib.h>
// #define DEBUG
#ifdef DEBUG
#define dprintf(fmt, ...) do { printf("dzip: " fmt, ## __VA_ARGS__); } while (0)
#else
#define dprintf(fmt, ...) do { } while (0)
#endif
#define SECTOR_SIZE 512
#define Z_STREAM_COUNT 4
#define CACHE_COUNT 20
/* magic values */
#define GZ_MAGIC1 0x1f
#define GZ_MAGIC2 0x8b
#define DZ_MAGIC1 'R'
#define DZ_MAGIC2 'A'
#define GZ_FEXTRA 0x04 /* Optional field (random access index) */
#define GZ_FNAME 0x08 /* Original name */
#define GZ_COMMENT 0x10 /* Zero-terminated, human-readable comment */
#define GZ_FHCRC 0x02 /* Header CRC16 */
/* offsets */
#define GZ_ID 0 /* GZ_MAGIC (16bit) */
#define GZ_FLG 3 /* FLaGs (see above) */
#define GZ_XLEN 10 /* eXtra LENgth (16bit) */
#define GZ_SI 12 /* Subfield ID (16bit) */
#define GZ_VERSION 16 /* Version for subfield format */
#define GZ_CHUNKSIZE 18 /* Chunk size (16bit) */
#define GZ_CHUNKCNT 20 /* Number of chunks (16bit) */
#define GZ_RNDDATA 22 /* Random access data (16bit) */
#define GZ_99_CHUNKSIZE 18 /* Chunk size (32bit) */
#define GZ_99_CHUNKCNT 22 /* Number of chunks (32bit) */
#define GZ_99_FILESIZE 26 /* Size of unpacked file (64bit) */
#define GZ_99_RNDDATA 34 /* Random access data (32bit) */
struct BDRVDictZipState;
typedef struct DictZipAIOCB {
BlockDriverAIOCB common;
struct BDRVDictZipState *s;
QEMUIOVector *qiov; /* QIOV of the original request */
QEMUIOVector *qiov_gz; /* QIOV of the gz subrequest */
QEMUBH *bh; /* BH for cache */
z_stream *zStream; /* stream to use for decoding */
int zStream_id; /* stream id of the above pointer */
size_t start; /* offset into the uncompressed file */
size_t len; /* uncompressed bytes to read */
uint8_t *gzipped; /* the gzipped data */
uint8_t *buf; /* cached result */
size_t gz_len; /* amount of gzip data */
size_t gz_start; /* uncompressed starting point of gzip data */
uint64_t offset; /* offset for "start" into the uncompressed chunk */
int chunks_len; /* amount of uncompressed data in all gzip data */
} DictZipAIOCB;
typedef struct dict_cache {
size_t start;
size_t len;
uint8_t *buf;
} DictCache;
typedef struct BDRVDictZipState {
BlockDriverState *hd;
z_stream zStream[Z_STREAM_COUNT];
DictCache cache[CACHE_COUNT];
int cache_index;
uint8_t stream_in_use;
uint64_t chunk_len;
uint32_t chunk_cnt;
uint16_t *chunks;
uint32_t *chunks32;
uint64_t *offsets;
int64_t file_len;
} BDRVDictZipState;
static int dictzip_probe(const uint8_t *buf, int buf_size, const char *filename)
{
if (buf_size < 2)
return 0;
/* We match on every gzip file */
if ((buf[0] == GZ_MAGIC1) && (buf[1] == GZ_MAGIC2))
return 100;
return 0;
}
static int start_zStream(z_stream *zStream)
{
zStream->zalloc = NULL;
zStream->zfree = NULL;
zStream->opaque = NULL;
zStream->next_in = 0;
zStream->avail_in = 0;
zStream->next_out = NULL;
zStream->avail_out = 0;
return inflateInit2( zStream, -15 );
}
static QemuOptsList runtime_opts = {
.name = "dzip",
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
.desc = {
{
.name = "filename",
.type = QEMU_OPT_STRING,
.help = "URL to the dictzip file",
},
{ /* end of list */ }
},
};
static int dictzip_open(BlockDriverState *bs, QDict *options, int flags, Error **errp)
{
BDRVDictZipState *s = bs->opaque;
const char *err = "Unknown (read error?)";
uint8_t magic[2];
char buf[100];
uint8_t header_flags;
uint16_t chunk_len16;
uint16_t chunk_cnt16;
uint16_t header_ver;
uint16_t tmp_short;
uint64_t offset;
int chunks_len;
int headerLength = GZ_XLEN - 1;
int rnd_offs;
int ret;
int i;
QemuOpts *opts;
Error *local_err = NULL;
const char *filename;
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
}
filename = qemu_opt_get(opts, "filename");
if (!strncmp(filename, "dzip://", 7))
filename += 7;
else if (!strncmp(filename, "dzip:", 5))
filename += 5;
ret = bdrv_open(&s->hd, filename, NULL, NULL, flags | BDRV_O_PROTOCOL, NULL, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
qemu_opts_del(opts);
return ret;
}
/* initialize zlib streams */
for (i = 0; i < Z_STREAM_COUNT; i++) {
if (start_zStream( &s->zStream[i] ) != Z_OK) {
err = s->zStream[i].msg;
goto fail;
}
}
/* gzip header */
if (bdrv_pread(s->hd, GZ_ID, &magic, sizeof(magic)) != sizeof(magic))
goto fail;
if (!((magic[0] == GZ_MAGIC1) && (magic[1] == GZ_MAGIC2))) {
err = "No gzip file";
goto fail;
}
/* dzip header */
if (bdrv_pread(s->hd, GZ_FLG, &header_flags, 1) != 1)
goto fail;
if (!(header_flags & GZ_FEXTRA)) {
err = "Not a dictzip file (wrong flags)";
goto fail;
}
/* extra length */
if (bdrv_pread(s->hd, GZ_XLEN, &tmp_short, 2) != 2)
goto fail;
headerLength += le16_to_cpu(tmp_short) + 2;
/* DictZip magic */
if (bdrv_pread(s->hd, GZ_SI, &magic, 2) != 2)
goto fail;
if (magic[0] != DZ_MAGIC1 || magic[1] != DZ_MAGIC2) {
err = "Not a dictzip file (missing extra magic)";
goto fail;
}
/* DictZip version */
if (bdrv_pread(s->hd, GZ_VERSION, &header_ver, 2) != 2)
goto fail;
header_ver = le16_to_cpu(header_ver);
switch (header_ver) {
case 1: /* Normal DictZip */
/* number of chunks */
if (bdrv_pread(s->hd, GZ_CHUNKSIZE, &chunk_len16, 2) != 2)
goto fail;
s->chunk_len = le16_to_cpu(chunk_len16);
/* chunk count */
if (bdrv_pread(s->hd, GZ_CHUNKCNT, &chunk_cnt16, 2) != 2)
goto fail;
s->chunk_cnt = le16_to_cpu(chunk_cnt16);
chunks_len = sizeof(short) * s->chunk_cnt;
rnd_offs = GZ_RNDDATA;
break;
case 99: /* Special Alex pigz version */
/* number of chunks */
if (bdrv_pread(s->hd, GZ_99_CHUNKSIZE, &s->chunk_len, 4) != 4)
goto fail;
dprintf("chunk len [%#x] = %d\n", GZ_99_CHUNKSIZE, s->chunk_len);
s->chunk_len = le32_to_cpu(s->chunk_len);
/* chunk count */
if (bdrv_pread(s->hd, GZ_99_CHUNKCNT, &s->chunk_cnt, 4) != 4)
goto fail;
s->chunk_cnt = le32_to_cpu(s->chunk_cnt);
dprintf("chunk len | count = %d | %d\n", s->chunk_len, s->chunk_cnt);
/* file size */
if (bdrv_pread(s->hd, GZ_99_FILESIZE, &s->file_len, 8) != 8)
goto fail;
s->file_len = le64_to_cpu(s->file_len);
chunks_len = sizeof(int) * s->chunk_cnt;
rnd_offs = GZ_99_RNDDATA;
break;
default:
err = "Invalid DictZip version";
goto fail;
}
/* random access data */
s->chunks = g_malloc(chunks_len);
if (header_ver == 99)
s->chunks32 = (uint32_t *)s->chunks;
if (bdrv_pread(s->hd, rnd_offs, s->chunks, chunks_len) != chunks_len)
goto fail;
/* orig filename */
if (header_flags & GZ_FNAME) {
if (bdrv_pread(s->hd, headerLength + 1, buf, sizeof(buf)) != sizeof(buf))
goto fail;
buf[sizeof(buf) - 1] = '\0';
headerLength += strlen(buf) + 1;
if (strlen(buf) == sizeof(buf))
goto fail;
dprintf("filename: %s\n", buf);
}
/* comment field */
if (header_flags & GZ_COMMENT) {
if (bdrv_pread(s->hd, headerLength, buf, sizeof(buf)) != sizeof(buf))
goto fail;
buf[sizeof(buf) - 1] = '\0';
headerLength += strlen(buf) + 1;
if (strlen(buf) == sizeof(buf))
goto fail;
dprintf("comment: %s\n", buf);
}
if (header_flags & GZ_FHCRC)
headerLength += 2;
/* uncompressed file length*/
if (!s->file_len) {
uint32_t file_len;
if (bdrv_pread(s->hd, bdrv_getlength(s->hd) - 4, &file_len, 4) != 4)
goto fail;
s->file_len = le32_to_cpu(file_len);
}
/* compute offsets */
s->offsets = g_malloc(sizeof( *s->offsets ) * s->chunk_cnt);
for (offset = headerLength + 1, i = 0; i < s->chunk_cnt; i++) {
s->offsets[i] = offset;
switch (header_ver) {
case 1:
offset += s->chunks[i];
break;
case 99:
offset += s->chunks32[i];
break;
}
dprintf("chunk %#x - %#x = offset %#x -> %#x\n", i * s->chunk_len, (i+1) * s->chunk_len, s->offsets[i], offset);
}
qemu_opts_del(opts);
return 0;
fail:
fprintf(stderr, "DictZip: Error opening file: %s\n", err);
bdrv_unref(s->hd);
if (s->chunks)
g_free(s->chunks);
qemu_opts_del(opts);
return -EINVAL;
}
/* This callback gets invoked when we have the result in cache already */
static void dictzip_cache_cb(void *opaque)
{
DictZipAIOCB *acb = (DictZipAIOCB *)opaque;
qemu_iovec_from_buf(acb->qiov, 0, acb->buf, acb->len);
acb->common.cb(acb->common.opaque, 0);
qemu_bh_delete(acb->bh);
qemu_aio_release(acb);
}
/* This callback gets invoked by the underlying block reader when we have
* all compressed data. We uncompress in here. */
static void dictzip_read_cb(void *opaque, int ret)
{
DictZipAIOCB *acb = (DictZipAIOCB *)opaque;
struct BDRVDictZipState *s = acb->s;
uint8_t *buf;
DictCache *cache;
int r;
buf = g_malloc(acb->chunks_len);
/* uncompress the chunk */
acb->zStream->next_in = acb->gzipped;
acb->zStream->avail_in = acb->gz_len;
acb->zStream->next_out = buf;
acb->zStream->avail_out = acb->chunks_len;
r = inflate( acb->zStream, Z_PARTIAL_FLUSH );
if ( (r != Z_OK) && (r != Z_STREAM_END) )
fprintf(stderr, "Error inflating: [%d] %s\n", r, acb->zStream->msg);
if ( r == Z_STREAM_END )
inflateReset(acb->zStream);
dprintf("inflating [%d] left: %d | %d bytes\n", r, acb->zStream->avail_in, acb->zStream->avail_out);
s->stream_in_use &= ~(1 << acb->zStream_id);
/* nofity the caller */
qemu_iovec_from_buf(acb->qiov, 0, buf + acb->offset, acb->len);
acb->common.cb(acb->common.opaque, 0);
/* fill the cache */
cache = &s->cache[s->cache_index];
s->cache_index++;
if (s->cache_index == CACHE_COUNT)
s->cache_index = 0;
cache->len = 0;
if (cache->buf)
g_free(cache->buf);
cache->start = acb->gz_start;
cache->buf = buf;
cache->len = acb->chunks_len;
/* free occupied ressources */
g_free(acb->qiov_gz);
qemu_aio_release(acb);
}
static void dictzip_aio_cancel(BlockDriverAIOCB *blockacb)
{
}
static const AIOCBInfo dictzip_aiocb_info = {
.aiocb_size = sizeof(DictZipAIOCB),
.cancel = dictzip_aio_cancel,
};
/* This is where we get a request from a caller to read something */
static BlockDriverAIOCB *dictzip_aio_readv(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque)
{
BDRVDictZipState *s = bs->opaque;
DictZipAIOCB *acb;
QEMUIOVector *qiov_gz;
struct iovec *iov;
uint8_t *buf;
size_t start = sector_num * SECTOR_SIZE;
size_t len = nb_sectors * SECTOR_SIZE;
size_t end = start + len;
size_t gz_start;
size_t gz_len;
int64_t gz_sector_num;
int gz_nb_sectors;
int first_chunk, last_chunk;
int first_offset;
int i;
acb = qemu_aio_get(&dictzip_aiocb_info, bs, cb, opaque);
if (!acb)
return NULL;
/* Search Cache */
for (i = 0; i < CACHE_COUNT; i++) {
if (!s->cache[i].len)
continue;
if ((start >= s->cache[i].start) &&
(end <= (s->cache[i].start + s->cache[i].len))) {
acb->buf = s->cache[i].buf + (start - s->cache[i].start);
acb->len = len;
acb->qiov = qiov;
acb->bh = qemu_bh_new(dictzip_cache_cb, acb);
qemu_bh_schedule(acb->bh);
return &acb->common;
}
}
/* No cache, so let's decode */
do {
for (i = 0; i < Z_STREAM_COUNT; i++) {
if (!(s->stream_in_use & (1 << i))) {
s->stream_in_use |= (1 << i);
acb->zStream_id = i;
acb->zStream = &s->zStream[i];
break;
}
}
} while(!acb->zStream);
/* We need to read these chunks */
first_chunk = start / s->chunk_len;
first_offset = start - first_chunk * s->chunk_len;
last_chunk = end / s->chunk_len;
gz_start = s->offsets[first_chunk];
gz_len = 0;
for (i = first_chunk; i <= last_chunk; i++) {
if (s->chunks32)
gz_len += s->chunks32[i];
else
gz_len += s->chunks[i];
}
gz_sector_num = gz_start / SECTOR_SIZE;
gz_nb_sectors = (gz_len / SECTOR_SIZE);
/* account for tail and heads */
while ((gz_start + gz_len) > ((gz_sector_num + gz_nb_sectors) * SECTOR_SIZE))
gz_nb_sectors++;
/* Allocate qiov, iov and buf in one chunk so we only need to free qiov */
qiov_gz = g_malloc0(sizeof(QEMUIOVector) + sizeof(struct iovec) +
(gz_nb_sectors * SECTOR_SIZE));
iov = (struct iovec *)(((char *)qiov_gz) + sizeof(QEMUIOVector));
buf = ((uint8_t *)iov) + sizeof(struct iovec *);
/* Kick off the read by the backing file, so we can start decompressing */
iov->iov_base = (void *)buf;
iov->iov_len = gz_nb_sectors * 512;
qemu_iovec_init_external(qiov_gz, iov, 1);
dprintf("read %d - %d => %d - %d\n", start, end, gz_start, gz_start + gz_len);
acb->s = s;
acb->qiov = qiov;
acb->qiov_gz = qiov_gz;
acb->start = start;
acb->len = len;
acb->gzipped = buf + (gz_start % SECTOR_SIZE);
acb->gz_len = gz_len;
acb->gz_start = first_chunk * s->chunk_len;
acb->offset = first_offset;
acb->chunks_len = (last_chunk - first_chunk + 1) * s->chunk_len;
return bdrv_aio_readv(s->hd, gz_sector_num, qiov_gz, gz_nb_sectors,
dictzip_read_cb, acb);
}
static void dictzip_close(BlockDriverState *bs)
{
BDRVDictZipState *s = bs->opaque;
int i;
for (i = 0; i < CACHE_COUNT; i++) {
if (!s->cache[i].len)
continue;
g_free(s->cache[i].buf);
}
for (i = 0; i < Z_STREAM_COUNT; i++) {
inflateEnd(&s->zStream[i]);
}
if (s->chunks)
g_free(s->chunks);
if (s->offsets)
g_free(s->offsets);
dprintf("Close\n");
}
static int64_t dictzip_getlength(BlockDriverState *bs)
{
BDRVDictZipState *s = bs->opaque;
dprintf("getlength -> %ld\n", s->file_len);
return s->file_len;
}
static BlockDriver bdrv_dictzip = {
.format_name = "dzip",
.protocol_name = "dzip",
.instance_size = sizeof(BDRVDictZipState),
.bdrv_file_open = dictzip_open,
.bdrv_close = dictzip_close,
.bdrv_getlength = dictzip_getlength,
.bdrv_probe = dictzip_probe,
.bdrv_aio_readv = dictzip_aio_readv,
};
static void dictzip_block_init(void)
{
bdrv_register(&bdrv_dictzip);
}
block_init(dictzip_block_init);

View File

@@ -401,6 +401,19 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags,
return 0;
}
static QemuOptsList nfs_create_opts = {
.name = "nfs-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(nfs_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{ /* end of list */ }
}
};
static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp)
{
int ret = 0;
@@ -461,6 +474,8 @@ static BlockDriver bdrv_nfs = {
.instance_size = sizeof(NFSClient),
.bdrv_needs_filename = true,
.create_opts = &nfs_create_opts,
.bdrv_has_zero_init = nfs_has_zero_init,
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
.bdrv_truncate = nfs_file_truncate,

View File

@@ -158,12 +158,14 @@ static int l2_load(BlockDriverState *bs, uint64_t l2_offset,
int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
{
BDRVQcowState *s = bs->opaque;
uint64_t buf[L1_ENTRIES_PER_SECTOR];
uint64_t buf[L1_ENTRIES_PER_SECTOR] = { 0 };
int l1_start_index;
int i, ret;
l1_start_index = l1_index & ~(L1_ENTRIES_PER_SECTOR - 1);
for (i = 0; i < L1_ENTRIES_PER_SECTOR; i++) {
for (i = 0; i < L1_ENTRIES_PER_SECTOR && l1_start_index + i < s->l1_size;
i++)
{
buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]);
}
@@ -1200,7 +1202,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
again:
start = offset;
remaining = *num << BDRV_SECTOR_BITS;
remaining = (uint64_t)*num << BDRV_SECTOR_BITS;
cluster_offset = 0;
*host_offset = 0;
cur_bytes = 0;

View File

@@ -114,7 +114,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
#ifdef DEBUG_EXT
printf("ext.magic = 0x%x\n", ext.magic);
#endif
if (ext.len > end_offset - offset) {
if (offset > end_offset || ext.len > end_offset - offset) {
error_setg(errp, "Header extension too large");
return -EINVAL;
}
@@ -1275,10 +1275,23 @@ static void qcow2_close(BlockDriverState *bs)
s->l1_table = NULL;
if (!(bs->open_flags & BDRV_O_INCOMING)) {
qcow2_cache_flush(bs, s->l2_table_cache);
qcow2_cache_flush(bs, s->refcount_block_cache);
int ret1, ret2;
qcow2_mark_clean(bs);
ret1 = qcow2_cache_flush(bs, s->l2_table_cache);
ret2 = qcow2_cache_flush(bs, s->refcount_block_cache);
if (ret1) {
error_report("Failed to flush the L2 table cache: %s",
strerror(-ret1));
}
if (ret2) {
error_report("Failed to flush the refcount block cache: %s",
strerror(-ret2));
}
if (!ret1 && !ret2) {
qcow2_mark_clean(bs);
}
}
qcow2_cache_destroy(bs, s->l2_table_cache);
@@ -1712,10 +1725,9 @@ static int qcow2_create2(const char *filename, int64_t total_size,
* refcount of the cluster that is occupied by the header and the refcount
* table)
*/
BlockDriver* drv = bdrv_find_format("qcow2");
assert(drv != NULL);
ret = bdrv_open(&bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv, &local_err);
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH,
&bdrv_qcow2, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
goto out;
@@ -1767,7 +1779,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
/* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning */
ret = bdrv_open(&bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_BACKING,
drv, &local_err);
&bdrv_qcow2, &local_err);
if (local_err) {
error_propagate(errp, local_err);
goto out;
@@ -1948,8 +1960,7 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
sector based I/Os */
cluster_offset = bdrv_getlength(bs->file);
cluster_offset = (cluster_offset + 511) & ~511;
bdrv_truncate(bs->file, cluster_offset);
return 0;
return bdrv_truncate(bs->file, cluster_offset);
}
if (nb_sectors != s->cluster_sectors) {
@@ -2404,7 +2415,7 @@ static QemuOptsList qcow2_create_opts = {
}
};
static BlockDriver bdrv_qcow2 = {
BlockDriver bdrv_qcow2 = {
.format_name = "qcow2",
.instance_size = sizeof(BDRVQcowState),
.bdrv_probe = qcow2_probe,

View File

@@ -447,6 +447,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
s->has_write_zeroes = true;
if (fstat(s->fd, &st) < 0) {
ret = -errno;
error_setg_errno(errp, errno, "Could not stat file");
goto fail;
}
@@ -1585,7 +1586,7 @@ static QemuOptsList raw_create_opts = {
}
};
static BlockDriver bdrv_file = {
BlockDriver bdrv_file = {
.format_name = "file",
.protocol_name = "file",
.instance_size = sizeof(BDRVRawState),

View File

@@ -540,7 +540,7 @@ static QemuOptsList raw_create_opts = {
}
};
static BlockDriver bdrv_file = {
BlockDriver bdrv_file = {
.format_name = "file",
.protocol_name = "file",
.instance_size = sizeof(BDRVRawState),

View File

@@ -173,7 +173,7 @@ static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
return 1;
}
static BlockDriver bdrv_raw = {
BlockDriver bdrv_raw = {
.format_name = "raw",
.bdrv_probe = &raw_probe,
.bdrv_reopen_prepare = &raw_reopen_prepare,

View File

@@ -236,6 +236,10 @@ int bdrv_snapshot_delete(BlockDriverState *bs,
error_setg(errp, "snapshot_id and name are both NULL");
return -EINVAL;
}
/* drain all pending i/o before deleting snapshot */
bdrv_drain_all();
if (drv->bdrv_snapshot_delete) {
return drv->bdrv_snapshot_delete(bs, snapshot_id, name, errp);
}

395
block/tar.c Normal file
View File

@@ -0,0 +1,395 @@
/*
* Tar block driver
*
* Copyright (c) 2009 Alexander Graf <agraf@suse.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu-common.h"
#include "block/block_int.h"
// #define DEBUG
#ifdef DEBUG
#define dprintf(fmt, ...) do { printf("tar: " fmt, ## __VA_ARGS__); } while (0)
#else
#define dprintf(fmt, ...) do { } while (0)
#endif
#define SECTOR_SIZE 512
#define POSIX_TAR_MAGIC "ustar"
#define OFFS_LENGTH 0x7c
#define OFFS_TYPE 0x9c
#define OFFS_MAGIC 0x101
#define OFFS_S_SP 0x182
#define OFFS_S_EXT 0x1e2
#define OFFS_S_LENGTH 0x1e3
#define OFFS_SX_EXT 0x1f8
typedef struct SparseCache {
uint64_t start;
uint64_t end;
} SparseCache;
typedef struct BDRVTarState {
BlockDriverState *hd;
size_t file_sec;
uint64_t file_len;
SparseCache *sparse;
int sparse_num;
uint64_t last_end;
char longfile[2048];
} BDRVTarState;
static int tar_probe(const uint8_t *buf, int buf_size, const char *filename)
{
if (buf_size < OFFS_MAGIC + 5)
return 0;
/* we only support newer tar */
if (!strncmp((char*)buf + OFFS_MAGIC, POSIX_TAR_MAGIC, 5))
return 100;
return 0;
}
static int str_ends(char *str, const char *end)
{
int end_len = strlen(end);
int str_len = strlen(str);
if (str_len < end_len)
return 0;
return !strncmp(str + str_len - end_len, end, end_len);
}
static int is_target_file(BlockDriverState *bs, char *filename,
char *header)
{
int retval = 0;
if (str_ends(filename, ".raw"))
retval = 1;
if (str_ends(filename, ".qcow"))
retval = 1;
if (str_ends(filename, ".qcow2"))
retval = 1;
if (str_ends(filename, ".vmdk"))
retval = 1;
if (retval &&
(header[OFFS_TYPE] != '0') &&
(header[OFFS_TYPE] != 'S')) {
retval = 0;
}
dprintf("does filename %s match? %s\n", filename, retval ? "yes" : "no");
/* make sure we're not using this name again */
filename[0] = '\0';
return retval;
}
static uint64_t tar2u64(char *ptr)
{
uint64_t retval;
char oldend = ptr[12];
ptr[12] = '\0';
if (*ptr & 0x80) {
/* XXX we only support files up to 64 bit length */
retval = be64_to_cpu(*(uint64_t *)(ptr+4));
dprintf("Convert %lx -> %#lx\n", *(uint64_t*)(ptr+4), retval);
} else {
retval = strtol(ptr, NULL, 8);
dprintf("Convert %s -> %#lx\n", ptr, retval);
}
ptr[12] = oldend;
return retval;
}
static void tar_sparse(BDRVTarState *s, uint64_t offs, uint64_t len)
{
SparseCache *sparse;
if (!len)
return;
if (!(offs - s->last_end)) {
s->last_end += len;
return;
}
if (s->last_end > offs)
return;
dprintf("Last chunk until %lx new chunk at %lx\n", s->last_end, offs);
s->sparse = g_realloc(s->sparse, (s->sparse_num + 1) * sizeof(SparseCache));
sparse = &s->sparse[s->sparse_num];
sparse->start = s->last_end;
sparse->end = offs;
s->last_end = offs + len;
s->sparse_num++;
dprintf("Sparse at %lx end=%lx\n", sparse->start,
sparse->end);
}
static QemuOptsList runtime_opts = {
.name = "tar",
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
.desc = {
{
.name = "filename",
.type = QEMU_OPT_STRING,
.help = "URL to the tar file",
},
{ /* end of list */ }
},
};
static int tar_open(BlockDriverState *bs, QDict *options, int flags, Error **errp)
{
BDRVTarState *s = bs->opaque;
char header[SECTOR_SIZE];
char *real_file = header;
char *magic;
size_t header_offs = 0;
int ret;
QemuOpts *opts;
Error *local_err = NULL;
const char *filename;
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
}
filename = qemu_opt_get(opts, "filename");
if (!strncmp(filename, "tar://", 6))
filename += 6;
else if (!strncmp(filename, "tar:", 4))
filename += 4;
ret = bdrv_open(&s->hd, filename, NULL, NULL, flags | BDRV_O_PROTOCOL, NULL, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
qemu_opts_del(opts);
return ret;
}
/* Search the file for an image */
do {
/* tar header */
if (bdrv_pread(s->hd, header_offs, header, SECTOR_SIZE) != SECTOR_SIZE)
goto fail;
if ((header_offs > 1) && !header[0]) {
fprintf(stderr, "Tar: No image file found in archive\n");
goto fail;
}
magic = &header[OFFS_MAGIC];
if (strncmp(magic, POSIX_TAR_MAGIC, 5)) {
fprintf(stderr, "Tar: Invalid magic: %s\n", magic);
goto fail;
}
dprintf("file type: %c\n", header[OFFS_TYPE]);
/* file length*/
s->file_len = (tar2u64(&header[OFFS_LENGTH]) + (SECTOR_SIZE - 1)) &
~(SECTOR_SIZE - 1);
s->file_sec = (header_offs / SECTOR_SIZE) + 1;
header_offs += s->file_len + SECTOR_SIZE;
if (header[OFFS_TYPE] == 'L') {
bdrv_pread(s->hd, header_offs - s->file_len, s->longfile,
sizeof(s->longfile));
s->longfile[sizeof(s->longfile)-1] = '\0';
real_file = header;
} else if (s->longfile[0]) {
real_file = s->longfile;
} else {
real_file = header;
}
} while(!is_target_file(bs, real_file, header));
/* We found an image! */
if (header[OFFS_TYPE] == 'S') {
uint8_t isextended;
int i;
for (i = OFFS_S_SP; i < (OFFS_S_SP + (4 * 24)); i += 24)
tar_sparse(s, tar2u64(&header[i]), tar2u64(&header[i+12]));
s->file_len = tar2u64(&header[OFFS_S_LENGTH]);
isextended = header[OFFS_S_EXT];
while (isextended) {
if (bdrv_pread(s->hd, s->file_sec * SECTOR_SIZE, header,
SECTOR_SIZE) != SECTOR_SIZE)
goto fail;
for (i = 0; i < (21 * 24); i += 24)
tar_sparse(s, tar2u64(&header[i]), tar2u64(&header[i+12]));
isextended = header[OFFS_SX_EXT];
s->file_sec++;
}
tar_sparse(s, s->file_len, 1);
}
qemu_opts_del(opts);
return 0;
fail:
fprintf(stderr, "Tar: Error opening file\n");
bdrv_unref(s->hd);
qemu_opts_del(opts);
return -EINVAL;
}
typedef struct TarAIOCB {
BlockDriverAIOCB common;
QEMUBH *bh;
} TarAIOCB;
/* This callback gets invoked when we have pure sparseness */
static void tar_sparse_cb(void *opaque)
{
TarAIOCB *acb = (TarAIOCB *)opaque;
acb->common.cb(acb->common.opaque, 0);
qemu_bh_delete(acb->bh);
qemu_aio_release(acb);
}
static void tar_aio_cancel(BlockDriverAIOCB *blockacb)
{
}
static AIOCBInfo tar_aiocb_info = {
.aiocb_size = sizeof(TarAIOCB),
.cancel = tar_aio_cancel,
};
/* This is where we get a request from a caller to read something */
static BlockDriverAIOCB *tar_aio_readv(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque)
{
BDRVTarState *s = bs->opaque;
SparseCache *sparse;
int64_t sec_file = sector_num + s->file_sec;
int64_t start = sector_num * SECTOR_SIZE;
int64_t end = start + (nb_sectors * SECTOR_SIZE);
int i;
TarAIOCB *acb;
for (i = 0; i < s->sparse_num; i++) {
sparse = &s->sparse[i];
if (sparse->start > end) {
/* We expect the cache to be start increasing */
break;
} else if ((sparse->start < start) && (sparse->end <= start)) {
/* sparse before our offset */
sec_file -= (sparse->end - sparse->start) / SECTOR_SIZE;
} else if ((sparse->start <= start) && (sparse->end >= end)) {
/* all our sectors are sparse */
char *buf = g_malloc0(nb_sectors * SECTOR_SIZE);
acb = qemu_aio_get(&tar_aiocb_info, bs, cb, opaque);
qemu_iovec_from_buf(qiov, 0, buf, nb_sectors * SECTOR_SIZE);
g_free(buf);
acb->bh = qemu_bh_new(tar_sparse_cb, acb);
qemu_bh_schedule(acb->bh);
return &acb->common;
} else if (((sparse->start >= start) && (sparse->start < end)) ||
((sparse->end >= start) && (sparse->end < end))) {
/* we're semi-sparse (worst case) */
/* let's go synchronous and read all sectors individually */
char *buf = g_malloc(nb_sectors * SECTOR_SIZE);
uint64_t offs;
for (offs = 0; offs < (nb_sectors * SECTOR_SIZE);
offs += SECTOR_SIZE) {
bdrv_pread(bs, (sector_num * SECTOR_SIZE) + offs,
buf + offs, SECTOR_SIZE);
}
qemu_iovec_from_buf(qiov, 0, buf, nb_sectors * SECTOR_SIZE);
acb = qemu_aio_get(&tar_aiocb_info, bs, cb, opaque);
acb->bh = qemu_bh_new(tar_sparse_cb, acb);
qemu_bh_schedule(acb->bh);
return &acb->common;
}
}
return bdrv_aio_readv(s->hd, sec_file, qiov, nb_sectors,
cb, opaque);
}
static void tar_close(BlockDriverState *bs)
{
dprintf("Close\n");
}
static int64_t tar_getlength(BlockDriverState *bs)
{
BDRVTarState *s = bs->opaque;
dprintf("getlength -> %ld\n", s->file_len);
return s->file_len;
}
static BlockDriver bdrv_tar = {
.format_name = "tar",
.protocol_name = "tar",
.instance_size = sizeof(BDRVTarState),
.bdrv_file_open = tar_open,
.bdrv_close = tar_close,
.bdrv_getlength = tar_getlength,
.bdrv_probe = tar_probe,
.bdrv_aio_readv = tar_aio_readv,
};
static void tar_block_init(void)
{
bdrv_register(&bdrv_tar);
}
block_init(tar_block_init);

View File

@@ -1752,9 +1752,12 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false)) {
zeroed_grain = true;
}
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_SCSI, false)) {
flags |= BLOCK_FLAG_SCSI;
}
if (!adapter_type) {
adapter_type = g_strdup("ide");
adapter_type = g_strdup(flags & BLOCK_FLAG_SCSI ? "lsilogic" : "ide");
} else if (strcmp(adapter_type, "ide") &&
strcmp(adapter_type, "buslogic") &&
strcmp(adapter_type, "lsilogic") &&
@@ -2151,6 +2154,11 @@ static QemuOptsList vmdk_create_opts = {
.help = "Enable efficient zero writes "
"using the zeroed-grain GTE feature"
},
{
.name = BLOCK_OPT_SCSI,
.type = QEMU_OPT_BOOL,
.help = "SCSI image"
},
{ /* end of list */ }
}
};

View File

@@ -2926,6 +2926,12 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp)
}
bdrv_qcow = bdrv_find_format("qcow");
if (!bdrv_qcow) {
error_setg(errp, "Failed to locate qcow driver");
ret = -ENOENT;
goto err;
}
opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort);
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512);
qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:");

2
configure vendored
View File

@@ -1538,7 +1538,7 @@ fi
if test "$pie" = ""; then
case "$cpu-$targetos" in
i386-Linux|x86_64-Linux|x32-Linux|i386-OpenBSD|x86_64-OpenBSD)
i386-Linux|x86_64-Linux|x32-Linux|ppc*-Linux|i386-OpenBSD|x86_64-OpenBSD)
;;
*)
pie="no"

9
cpus.c
View File

@@ -523,6 +523,15 @@ void cpu_synchronize_all_post_init(void)
}
}
void cpu_clean_all_dirty(void)
{
CPUState *cpu;
CPU_FOREACH(cpu) {
cpu_clean_state(cpu);
}
}
static int do_vm_stop(RunState state)
{
int ret = 0;

37
exec.c
View File

@@ -330,6 +330,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
hwaddr *plen, bool resolve_subpage)
{
MemoryRegionSection *section;
MemoryRegion *mr;
Int128 diff;
section = address_space_lookup_region(d, addr, resolve_subpage);
@@ -339,8 +340,23 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
/* Compute offset within MemoryRegion */
*xlat = addr + section->offset_within_region;
diff = int128_sub(section->mr->size, int128_make64(addr));
*plen = int128_get64(int128_min(diff, int128_make64(*plen)));
mr = section->mr;
/* MMIO registers can be expected to perform full-width accesses based only
* on their address, without considering adjacent registers that could
* decode to completely different MemoryRegions. When such registers
* exist (e.g. I/O ports 0xcf8 and 0xcf9 on most PC chipsets), MMIO
* regions overlap wildly. For this reason we cannot clamp the accesses
* here.
*
* If the length is small (as is the case for address_space_ldl/stl),
* everything works fine. If the incoming length is large, however,
* the caller really has to do the clamping through memory_access_size.
*/
if (memory_region_is_ram(mr)) {
diff = int128_sub(mr->size, int128_make64(addr));
*plen = int128_get64(int128_min(diff, int128_make64(*plen)));
}
return section;
}
@@ -363,7 +379,6 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
IOMMUTLBEntry iotlb;
MemoryRegionSection *section;
MemoryRegion *mr;
hwaddr len = *plen;
for (;;) {
section = address_space_translate_internal(as->dispatch, addr, &addr, plen, true);
@@ -376,7 +391,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
iotlb = mr->iommu_ops->translate(mr, addr);
addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
| (addr & iotlb.addr_mask));
len = MIN(len, (addr | iotlb.addr_mask) - addr + 1);
*plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1);
if (!(iotlb.perm & (1 << is_write))) {
mr = &io_mem_unassigned;
break;
@@ -387,10 +402,9 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
len = MIN(page, len);
*plen = MIN(page, *plen);
}
*plen = len;
*xlat = addr;
return mr;
}
@@ -1072,11 +1086,13 @@ static void *file_ram_alloc(RAMBlock *block,
return NULL;
}
#ifndef TARGET_PPC
if (kvm_enabled() && !kvm_has_sync_mmu()) {
error_setg(errp,
"host lacks kvm mmu notifiers, -mem-path unsupported");
goto error;
}
#endif
/* Make name safe to use with mkstemp by replacing '/' with '_'. */
sanitized_name = g_strdup(block->mr->name);
@@ -1130,6 +1146,7 @@ static void *file_ram_alloc(RAMBlock *block,
error:
if (mem_prealloc) {
error_report("%s\n", error_get_pretty(*errp));
exit(1);
}
return NULL;
@@ -2008,10 +2025,8 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
static void invalidate_and_set_dirty(hwaddr addr,
hwaddr length)
{
if (cpu_physical_memory_is_clean(addr)) {
/* invalidate code */
tb_invalidate_phys_page_range(addr, addr + length, 0);
/* set dirty bit */
if (cpu_physical_memory_range_includes_clean(addr, length)) {
tb_invalidate_phys_range(addr, addr + length, 0);
cpu_physical_memory_set_dirty_range_nocode(addr, length);
}
xen_modified_memory(addr, length);
@@ -2175,7 +2190,7 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
if (!(memory_region_is_ram(mr) ||
memory_region_is_romd(mr))) {
/* do nothing */
l = memory_access_size(mr, l, addr1);
} else {
addr1 += memory_region_get_ram_addr(mr);
/* ROM/RAM case */

View File

@@ -9,6 +9,13 @@
* the COPYING file in the top-level directory.
*/
/* work around a broken sys/capability.h */
#if defined(__i386__)
typedef unsigned long long __u64;
#endif
#if defined(__powerpc64__)
#include <asm/types.h>
#endif
#include <sys/resource.h>
#include <getopt.h>
#include <syslog.h>

View File

@@ -1707,7 +1707,7 @@ int gdbserver_start(const char *device)
qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
/* Initialize a monitor terminal for gdb */
mon_chr = g_malloc0(sizeof(*mon_chr));
mon_chr = qemu_chr_alloc();
mon_chr->chr_write = gdb_monitor_write;
monitor_init(mon_chr, 0);
} else {

18
hmp.c
View File

@@ -1476,21 +1476,18 @@ void hmp_send_key(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));
@@ -1503,16 +1500,17 @@ void hmp_send_key(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->kind = KEY_VALUE_KIND_NUMBER;
keylist->value->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;
}
@@ -1534,7 +1532,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

@@ -508,7 +508,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(info->kernel_filename, &entry, NULL,
&is_linux);
&is_linux, NULL, NULL);
}
if (kernel_size < 0) {
entry = info->loader_start + kernel_load_offset;

View File

@@ -371,7 +371,7 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
2, base, 2, size);
qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
GIC_FDT_IRQ_TYPE_SPI, irq,
GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
qemu_fdt_setprop_cells(vbi->fdt, nodename, "clocks",
vbi->clock_phandle, vbi->clock_phandle);
qemu_fdt_setprop(vbi->fdt, nodename, "clock-names",
@@ -396,7 +396,7 @@ static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic)
2, base, 2, size);
qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
GIC_FDT_IRQ_TYPE_SPI, irq,
GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
qemu_fdt_setprop_cell(vbi->fdt, nodename, "clocks", vbi->clock_phandle);
qemu_fdt_setprop_string(vbi->fdt, nodename, "clock-names", "apb_pclk");
g_free(nodename);

View File

@@ -1436,7 +1436,7 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
{
FDrive *cur_drv;
uint32_t retval = 0;
int pos;
uint32_t pos;
cur_drv = get_cur_drv(fdctrl);
fdctrl->dsr &= ~FD_DSR_PWRDOWN;
@@ -1445,8 +1445,8 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
return 0;
}
pos = fdctrl->data_pos;
pos %= FD_SECTOR_LEN;
if (fdctrl->msr & FD_MSR_NONDMA) {
pos %= FD_SECTOR_LEN;
if (pos == 0) {
if (fdctrl->data_pos != 0)
if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
@@ -1790,10 +1790,13 @@ static void fdctrl_handle_option(FDCtrl *fdctrl, int direction)
static void fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direction)
{
FDrive *cur_drv = get_cur_drv(fdctrl);
uint32_t pos;
if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) {
pos = fdctrl->data_pos - 1;
pos %= FD_SECTOR_LEN;
if (fdctrl->fifo[pos] & 0x80) {
/* Command parameters done */
if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) {
if (fdctrl->fifo[pos] & 0x40) {
fdctrl->fifo[0] = fdctrl->fifo[1];
fdctrl->fifo[2] = 0;
fdctrl->fifo[3] = 0;
@@ -1893,7 +1896,7 @@ static uint8_t command_to_handler[256];
static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
{
FDrive *cur_drv;
int pos;
uint32_t pos;
/* Reset mode */
if (!(fdctrl->dor & FD_DOR_nRESET)) {
@@ -1941,7 +1944,9 @@ static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
}
FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
fdctrl->fifo[fdctrl->data_pos++] = value;
pos = fdctrl->data_pos++;
pos %= FD_SECTOR_LEN;
fdctrl->fifo[pos] = value;
if (fdctrl->data_pos == fdctrl->data_len) {
/* We now have all parameters
* and will be able to treat the command

View File

@@ -174,7 +174,8 @@ static size_t send_control_msg(VirtIOSerial *vser, void *buf, size_t len)
return 0;
}
memcpy(elem.in_sg[0].iov_base, buf, len);
/* TODO: detect a buffer that's too short, set NEEDS_RESET */
iov_from_buf(elem.in_sg, elem.in_num, 0, buf, len);
virtqueue_push(vq, &elem, len);
virtio_notify(VIRTIO_DEVICE(vser), vq);

View File

@@ -456,7 +456,9 @@ static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
/* Load a U-Boot image. */
static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
int *is_linux, uint8_t image_type)
int *is_linux, uint8_t image_type,
uint64_t (*translate_fn)(void *, uint64_t),
void *translate_opaque)
{
int fd;
int size;
@@ -490,6 +492,9 @@ static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
switch (hdr->ih_type) {
case IH_TYPE_KERNEL:
address = hdr->ih_load;
if (translate_fn) {
address = translate_fn(translate_opaque, address);
}
if (loadaddr) {
*loadaddr = hdr->ih_load;
}
@@ -566,15 +571,19 @@ out:
}
int load_uimage(const char *filename, hwaddr *ep, hwaddr *loadaddr,
int *is_linux)
int *is_linux,
uint64_t (*translate_fn)(void *, uint64_t),
void *translate_opaque)
{
return load_uboot_image(filename, ep, loadaddr, is_linux, IH_TYPE_KERNEL);
return load_uboot_image(filename, ep, loadaddr, is_linux, IH_TYPE_KERNEL,
translate_fn, translate_opaque);
}
/* Load a ramdisk. */
int load_ramdisk(const char *filename, hwaddr addr, uint64_t max_sz)
{
return load_uboot_image(filename, NULL, &addr, NULL, IH_TYPE_RAMDISK);
return load_uboot_image(filename, NULL, &addr, NULL, IH_TYPE_RAMDISK,
NULL, NULL);
}
/*

View File

@@ -24,6 +24,7 @@ static void machine_set_accel(Object *obj, const char *value, Error **errp)
{
MachineState *ms = MACHINE(obj);
g_free(ms->accel);
ms->accel = g_strdup(value);
}
@@ -79,6 +80,7 @@ static void machine_set_kernel(Object *obj, const char *value, Error **errp)
{
MachineState *ms = MACHINE(obj);
g_free(ms->kernel_filename);
ms->kernel_filename = g_strdup(value);
}
@@ -93,6 +95,7 @@ static void machine_set_initrd(Object *obj, const char *value, Error **errp)
{
MachineState *ms = MACHINE(obj);
g_free(ms->initrd_filename);
ms->initrd_filename = g_strdup(value);
}
@@ -107,6 +110,7 @@ static void machine_set_append(Object *obj, const char *value, Error **errp)
{
MachineState *ms = MACHINE(obj);
g_free(ms->kernel_cmdline);
ms->kernel_cmdline = g_strdup(value);
}
@@ -121,6 +125,7 @@ static void machine_set_dtb(Object *obj, const char *value, Error **errp)
{
MachineState *ms = MACHINE(obj);
g_free(ms->dtb);
ms->dtb = g_strdup(value);
}
@@ -135,6 +140,7 @@ static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
{
MachineState *ms = MACHINE(obj);
g_free(ms->dumpdtb);
ms->dumpdtb = g_strdup(value);
}
@@ -176,6 +182,7 @@ static void machine_set_dt_compatible(Object *obj, const char *value, Error **er
{
MachineState *ms = MACHINE(obj);
g_free(ms->dt_compatible);
ms->dt_compatible = g_strdup(value);
}
@@ -232,6 +239,7 @@ static void machine_set_firmware(Object *obj, const char *value, Error **errp)
{
MachineState *ms = MACHINE(obj);
g_free(ms->firmware);
ms->firmware = g_strdup(value);
}

View File

@@ -834,12 +834,14 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
dc->realize(dev, &local_err);
}
if (dev->parent_bus && dev->parent_bus->hotplug_handler &&
local_err == NULL) {
if (local_err != NULL) {
goto fail;
}
if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
hotplug_handler_plug(dev->parent_bus->hotplug_handler,
dev, &local_err);
} else if (local_err == NULL &&
object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
} else if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
HotplugHandler *hotplug_ctrl;
MachineState *machine = MACHINE(qdev_get_machine());
MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -852,47 +854,69 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
}
}
if (qdev_get_vmsd(dev) && local_err == NULL) {
if (local_err != NULL) {
goto post_realize_fail;
}
if (qdev_get_vmsd(dev)) {
vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
dev->instance_id_alias,
dev->alias_required_for_version);
}
if (local_err == NULL) {
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
object_property_set_bool(OBJECT(bus), true, "realized",
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
object_property_set_bool(OBJECT(bus), true, "realized",
&local_err);
if (local_err != NULL) {
break;
}
if (local_err != NULL) {
goto child_realize_fail;
}
}
if (dev->hotplugged && local_err == NULL) {
if (dev->hotplugged) {
device_reset(dev);
}
dev->pending_deleted_event = false;
} else if (!value && dev->realized) {
Error **local_errp = NULL;
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
local_errp = local_err ? NULL : &local_err;
object_property_set_bool(OBJECT(bus), false, "realized",
&local_err);
if (local_err != NULL) {
break;
}
local_errp);
}
if (qdev_get_vmsd(dev) && local_err == NULL) {
if (qdev_get_vmsd(dev)) {
vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
}
if (dc->unrealize && local_err == NULL) {
dc->unrealize(dev, &local_err);
if (dc->unrealize) {
local_errp = local_err ? NULL : &local_err;
dc->unrealize(dev, local_errp);
}
dev->pending_deleted_event = true;
}
if (local_err != NULL) {
error_propagate(errp, local_err);
return;
goto fail;
}
dev->realized = value;
return;
child_realize_fail:
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
object_property_set_bool(OBJECT(bus), false, "realized",
NULL);
}
if (qdev_get_vmsd(dev)) {
vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
}
post_realize_fail:
if (dc->unrealize) {
dc->unrealize(dev, NULL);
}
fail:
error_propagate(errp, local_err);
return;
}
static bool device_get_hotpluggable(Object *obj, Error **errp)

View File

@@ -166,6 +166,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)
{
MemoryRegion *region, *old_region = s->chain4_alias;
@@ -202,6 +209,7 @@ static void vga_update_memory_access(VGACommonState *s)
}
base += isa_mem_base;
region = g_malloc(sizeof(*region));
assert(offset + size <= s->vram_size);
memory_region_init_alias(region, memory_region_owner(&s->vram),
"vga.chain4", &s->vram, offset, size);
memory_region_add_subregion_overlap(s->legacy_address_space, base,
@@ -507,6 +515,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);
}
@@ -538,6 +547,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:
@@ -556,10 +566,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:
@@ -592,7 +604,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;
}
@@ -667,6 +679,50 @@ 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;
@@ -743,13 +799,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);
@@ -757,53 +810,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 (should be done in BIOS) */
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 (should be done
in BIOS) */
/* 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 {
/* XXX: the bios should do that */
s->bank_offset = 0;
@@ -850,13 +869,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)) {
@@ -913,6 +940,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);
@@ -926,6 +954,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);
@@ -999,6 +1030,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);
@@ -1162,7 +1196,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;
@@ -1615,7 +1649,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;
@@ -1627,7 +1661,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

@@ -292,8 +292,59 @@ enum {
SVGA_CURSOR_ON_RESTORE_TO_FB = 3,
};
static inline bool vmsvga_verify_rect(DisplaySurface *surface,
const char *name,
int x, int y, int w, int h)
{
if (x < 0) {
fprintf(stderr, "%s: x was < 0 (%d)\n", name, x);
return false;
}
if (x > SVGA_MAX_WIDTH) {
fprintf(stderr, "%s: x was > %d (%d)\n", name, SVGA_MAX_WIDTH, x);
return false;
}
if (w < 0) {
fprintf(stderr, "%s: w was < 0 (%d)\n", name, w);
return false;
}
if (w > SVGA_MAX_WIDTH) {
fprintf(stderr, "%s: w was > %d (%d)\n", name, SVGA_MAX_WIDTH, w);
return false;
}
if (x + w > surface_width(surface)) {
fprintf(stderr, "%s: width was > %d (x: %d, w: %d)\n",
name, surface_width(surface), x, w);
return false;
}
if (y < 0) {
fprintf(stderr, "%s: y was < 0 (%d)\n", name, y);
return false;
}
if (y > SVGA_MAX_HEIGHT) {
fprintf(stderr, "%s: y was > %d (%d)\n", name, SVGA_MAX_HEIGHT, y);
return false;
}
if (h < 0) {
fprintf(stderr, "%s: h was < 0 (%d)\n", name, h);
return false;
}
if (h > SVGA_MAX_HEIGHT) {
fprintf(stderr, "%s: h was > %d (%d)\n", name, SVGA_MAX_HEIGHT, h);
return false;
}
if (y + h > surface_height(surface)) {
fprintf(stderr, "%s: update height > %d (y: %d, h: %d)\n",
name, surface_height(surface), y, h);
return false;
}
return true;
}
static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
int x, int y, int w, int h)
int x, int y, int w, int h)
{
DisplaySurface *surface = qemu_console_surface(s->vga.con);
int line;
@@ -303,36 +354,12 @@ static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
uint8_t *src;
uint8_t *dst;
if (x < 0) {
fprintf(stderr, "%s: update x was < 0 (%d)\n", __func__, x);
w += x;
if (!vmsvga_verify_rect(surface, __func__, x, y, w, h)) {
/* go for a fullscreen update as fallback */
x = 0;
}
if (w < 0) {
fprintf(stderr, "%s: update w was < 0 (%d)\n", __func__, w);
w = 0;
}
if (x + w > surface_width(surface)) {
fprintf(stderr, "%s: update width too large x: %d, w: %d\n",
__func__, x, w);
x = MIN(x, surface_width(surface));
w = surface_width(surface) - x;
}
if (y < 0) {
fprintf(stderr, "%s: update y was < 0 (%d)\n", __func__, y);
h += y;
y = 0;
}
if (h < 0) {
fprintf(stderr, "%s: update h was < 0 (%d)\n", __func__, h);
h = 0;
}
if (y + h > surface_height(surface)) {
fprintf(stderr, "%s: update height too large y: %d, h: %d\n",
__func__, y, h);
y = MIN(y, surface_height(surface));
h = surface_height(surface) - y;
w = surface_width(surface);
h = surface_height(surface);
}
bypl = surface_stride(surface);
@@ -377,7 +404,7 @@ static inline void vmsvga_update_rect_flush(struct vmsvga_state_s *s)
}
#ifdef HW_RECT_ACCEL
static inline void vmsvga_copy_rect(struct vmsvga_state_s *s,
static inline int vmsvga_copy_rect(struct vmsvga_state_s *s,
int x0, int y0, int x1, int y1, int w, int h)
{
DisplaySurface *surface = qemu_console_surface(s->vga.con);
@@ -388,6 +415,13 @@ static inline void vmsvga_copy_rect(struct vmsvga_state_s *s,
int line = h;
uint8_t *ptr[2];
if (!vmsvga_verify_rect(surface, "vmsvga_copy_rect/src", x0, y0, w, h)) {
return -1;
}
if (!vmsvga_verify_rect(surface, "vmsvga_copy_rect/dst", x1, y1, w, h)) {
return -1;
}
if (y1 > y0) {
ptr[0] = vram + bypp * x0 + bypl * (y0 + h - 1);
ptr[1] = vram + bypp * x1 + bypl * (y1 + h - 1);
@@ -403,11 +437,12 @@ static inline void vmsvga_copy_rect(struct vmsvga_state_s *s,
}
vmsvga_update_rect_delayed(s, x1, y1, w, h);
return 0;
}
#endif
#ifdef HW_FILL_ACCEL
static inline void vmsvga_fill_rect(struct vmsvga_state_s *s,
static inline int vmsvga_fill_rect(struct vmsvga_state_s *s,
uint32_t c, int x, int y, int w, int h)
{
DisplaySurface *surface = qemu_console_surface(s->vga.con);
@@ -420,6 +455,10 @@ static inline void vmsvga_fill_rect(struct vmsvga_state_s *s,
uint8_t *src;
uint8_t col[4];
if (!vmsvga_verify_rect(surface, __func__, x, y, w, h)) {
return -1;
}
col[0] = c;
col[1] = c >> 8;
col[2] = c >> 16;
@@ -444,6 +483,7 @@ static inline void vmsvga_fill_rect(struct vmsvga_state_s *s,
}
vmsvga_update_rect_delayed(s, x, y, w, h);
return 0;
}
#endif
@@ -576,12 +616,12 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
width = vmsvga_fifo_read(s);
height = vmsvga_fifo_read(s);
#ifdef HW_FILL_ACCEL
vmsvga_fill_rect(s, colour, x, y, width, height);
break;
#else
if (vmsvga_fill_rect(s, colour, x, y, width, height) == 0) {
break;
}
#endif
args = 0;
goto badcmd;
#endif
case SVGA_CMD_RECT_COPY:
len -= 7;
@@ -596,12 +636,12 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
width = vmsvga_fifo_read(s);
height = vmsvga_fifo_read(s);
#ifdef HW_RECT_ACCEL
vmsvga_copy_rect(s, x, y, dx, dy, width, height);
break;
#else
if (vmsvga_copy_rect(s, x, y, dx, dy, width, height) == 0) {
break;
}
#endif
args = 0;
goto badcmd;
#endif
case SVGA_CMD_DEFINE_CURSOR:
len -= 8;

View File

@@ -1228,8 +1228,7 @@ acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
}
static void
build_srat(GArray *table_data, GArray *linker,
AcpiCpuInfo *cpu, PcGuestInfo *guest_info)
build_srat(GArray *table_data, GArray *linker, PcGuestInfo *guest_info)
{
AcpiSystemResourceAffinityTable *srat;
AcpiSratProcessorAffinity *core;
@@ -1259,11 +1258,7 @@ build_srat(GArray *table_data, GArray *linker,
core->proximity_lo = curnode;
memset(core->proximity_hi, 0, 3);
core->local_sapic_eid = 0;
if (test_bit(i, cpu->found_cpus)) {
core->flags = cpu_to_le32(1);
} else {
core->flags = cpu_to_le32(0);
}
core->flags = cpu_to_le32(1);
}
@@ -1539,7 +1534,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
}
if (guest_info->numa_nodes) {
acpi_add_table(table_offsets, tables->table_data);
build_srat(tables->table_data, tables->linker, &cpu, guest_info);
build_srat(tables->table_data, tables->linker, guest_info);
}
if (acpi_get_mcfg(&mcfg)) {
acpi_add_table(table_offsets, tables->table_data);

View File

@@ -14,8 +14,10 @@
*/
#include "qemu-common.h"
#include "qemu/host-utils.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "sysemu/cpus.h"
#include "hw/sysbus.h"
#include "hw/kvm/clock.h"
@@ -34,6 +36,48 @@ typedef struct KVMClockState {
bool clock_valid;
} KVMClockState;
struct pvclock_vcpu_time_info {
uint32_t version;
uint32_t pad0;
uint64_t tsc_timestamp;
uint64_t system_time;
uint32_t tsc_to_system_mul;
int8_t tsc_shift;
uint8_t flags;
uint8_t pad[2];
} __attribute__((__packed__)); /* 32 bytes */
static uint64_t kvmclock_current_nsec(KVMClockState *s)
{
CPUState *cpu = first_cpu;
CPUX86State *env = cpu->env_ptr;
hwaddr kvmclock_struct_pa = env->system_time_msr & ~1ULL;
uint64_t migration_tsc = env->tsc;
struct pvclock_vcpu_time_info time;
uint64_t delta;
uint64_t nsec_lo;
uint64_t nsec_hi;
uint64_t nsec;
if (!(env->system_time_msr & 1ULL)) {
/* KVM clock not active */
return 0;
}
cpu_physical_memory_read(kvmclock_struct_pa, &time, sizeof(time));
assert(time.tsc_timestamp <= migration_tsc);
delta = migration_tsc - time.tsc_timestamp;
if (time.tsc_shift < 0) {
delta >>= -time.tsc_shift;
} else {
delta <<= time.tsc_shift;
}
mulu64(&nsec_lo, &nsec_hi, delta, time.tsc_to_system_mul);
nsec = (nsec_lo >> 32) | (nsec_hi << 32);
return nsec + time.system_time;
}
static void kvmclock_vm_state_change(void *opaque, int running,
RunState state)
@@ -45,9 +89,15 @@ static void kvmclock_vm_state_change(void *opaque, int running,
if (running) {
struct kvm_clock_data data;
uint64_t time_at_migration = kvmclock_current_nsec(s);
s->clock_valid = false;
/* We can't rely on the migrated clock value, just discard it */
if (time_at_migration) {
s->clock = time_at_migration;
}
data.clock = s->clock;
data.flags = 0;
ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data);
@@ -75,6 +125,23 @@ static void kvmclock_vm_state_change(void *opaque, int running,
if (s->clock_valid) {
return;
}
cpu_synchronize_all_states();
/* In theory, the cpu_synchronize_all_states() call above wouldn't
* affect the rest of the code, as the VCPU state inside CPUState
* is supposed to always match the VCPU state on the kernel side.
*
* In practice, calling cpu_synchronize_state() too soon will load the
* kernel-side APIC state into X86CPU.apic_state too early, APIC state
* won't be reloaded later because CPUState.vcpu_dirty==true, and
* outdated APIC state may be migrated to another host.
*
* The real fix would be to make sure outdated APIC state is read
* from the kernel again when necessary. While this is not fixed, we
* need the cpu_clean_all_dirty() call below.
*/
cpu_clean_all_dirty();
ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
if (ret < 0) {
fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));

View File

@@ -392,7 +392,7 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
CPUX86State *env = &cpu->env;
VAPICHandlers *handlers;
uint8_t opcode[2];
uint32_t imm32;
uint32_t imm32 = 0;
target_ulong current_pc = 0;
target_ulong current_cs_base = 0;
int current_flags = 0;
@@ -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

@@ -72,8 +72,10 @@
#define DPRINTF(fmt, ...)
#endif
/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */
unsigned acpi_data_size = 0x20000;
/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables
* (128K) and other BIOS datastructures (less than 4K reported to be used at
* the moment, 32K should be enough for a while). */
unsigned acpi_data_size = 0x20000 + 0x8000;
void pc_set_legacy_acpi_data_size(void)
{
acpi_data_size = 0x10000;

View File

@@ -646,7 +646,7 @@ static QEMUMachine pc_machine_v1_1 = {
.property = "class",\
.value = stringify(PCI_CLASS_MEMORY_RAM),\
},{\
.driver = "apic",\
.driver = "apic-common",\
.property = "vapic",\
.value = "off",\
},{\

View File

@@ -821,7 +821,7 @@ void smbios_get_tables(uint8_t **tables, size_t *tables_len,
smbios_build_type_2_table();
smbios_build_type_3_table();
smbios_smp_sockets = smp_cpus / (smp_cores * smp_threads);
smbios_smp_sockets = DIV_ROUND_UP(smp_cpus, smp_cores * smp_threads);
assert(smbios_smp_sockets >= 1);
for (i = 0; i < smbios_smp_sockets; i++) {

View File

@@ -721,6 +721,16 @@ out:
return r;
}
static void ncq_err(NCQTransferState *ncq_tfs)
{
IDEState *ide_state = &ncq_tfs->drive->port.ifs[0];
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_cb(void *opaque, int ret)
{
NCQTransferState *ncq_tfs = (NCQTransferState *)opaque;
@@ -730,10 +740,7 @@ static void ncq_cb(void *opaque, int ret)
ncq_tfs->drive->port_regs.scr_act &= ~(1 << ncq_tfs->tag);
if (ret < 0) {
/* error */
ide_state->error = ABRT_ERR;
ide_state->status = READY_STAT | ERR_STAT;
ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag);
ncq_err(ncq_tfs);
} else {
ide_state->status = READY_STAT | SEEK_STAT;
}

View File

@@ -879,6 +879,7 @@ static void cmd_start_stop_unit(IDEState *s, uint8_t* buf)
if (pwrcnd) {
/* eject/load only happens for power condition == 0 */
ide_atapi_cmd_ok(s);
return;
}

View File

@@ -1667,11 +1667,11 @@ static const struct {
} ide_cmd_table[0x100] = {
/* NOP not implemented, mandatory for CD */
[CFA_REQ_EXT_ERROR_CODE] = { cmd_cfa_req_ext_error_code, CFA_OK },
[WIN_DSM] = { cmd_data_set_management, ALL_OK },
[WIN_DSM] = { cmd_data_set_management, HD_CFA_OK },
[WIN_DEVICE_RESET] = { cmd_device_reset, CD_OK },
[WIN_RECAL] = { cmd_nop, HD_CFA_OK | SET_DSC},
[WIN_READ] = { cmd_read_pio, ALL_OK },
[WIN_READ_ONCE] = { cmd_read_pio, ALL_OK },
[WIN_READ_ONCE] = { cmd_read_pio, HD_CFA_OK },
[WIN_READ_EXT] = { cmd_read_pio, HD_CFA_OK },
[WIN_READDMA_EXT] = { cmd_read_dma, HD_CFA_OK },
[WIN_READ_NATIVE_MAX_EXT] = { cmd_read_native_max, HD_CFA_OK | SET_DSC },
@@ -1690,12 +1690,12 @@ static const struct {
[CFA_TRANSLATE_SECTOR] = { cmd_cfa_translate_sector, CFA_OK },
[WIN_DIAGNOSE] = { cmd_exec_dev_diagnostic, ALL_OK },
[WIN_SPECIFY] = { cmd_nop, HD_CFA_OK | SET_DSC },
[WIN_STANDBYNOW2] = { cmd_nop, ALL_OK },
[WIN_IDLEIMMEDIATE2] = { cmd_nop, ALL_OK },
[WIN_STANDBY2] = { cmd_nop, ALL_OK },
[WIN_SETIDLE2] = { cmd_nop, ALL_OK },
[WIN_CHECKPOWERMODE2] = { cmd_check_power_mode, ALL_OK | SET_DSC },
[WIN_SLEEPNOW2] = { cmd_nop, ALL_OK },
[WIN_STANDBYNOW2] = { cmd_nop, HD_CFA_OK },
[WIN_IDLEIMMEDIATE2] = { cmd_nop, HD_CFA_OK },
[WIN_STANDBY2] = { cmd_nop, HD_CFA_OK },
[WIN_SETIDLE2] = { cmd_nop, HD_CFA_OK },
[WIN_CHECKPOWERMODE2] = { cmd_check_power_mode, HD_CFA_OK | SET_DSC },
[WIN_SLEEPNOW2] = { cmd_nop, HD_CFA_OK },
[WIN_PACKETCMD] = { cmd_packet, CD_OK },
[WIN_PIDENTIFY] = { cmd_identify_packet, CD_OK },
[WIN_SMART] = { cmd_smart, HD_CFA_OK | SET_DSC },
@@ -1709,19 +1709,19 @@ static const struct {
[WIN_WRITEDMA] = { cmd_write_dma, HD_CFA_OK },
[WIN_WRITEDMA_ONCE] = { cmd_write_dma, HD_CFA_OK },
[CFA_WRITE_MULTI_WO_ERASE] = { cmd_write_multiple, CFA_OK },
[WIN_STANDBYNOW1] = { cmd_nop, ALL_OK },
[WIN_IDLEIMMEDIATE] = { cmd_nop, ALL_OK },
[WIN_STANDBY] = { cmd_nop, ALL_OK },
[WIN_SETIDLE1] = { cmd_nop, ALL_OK },
[WIN_CHECKPOWERMODE1] = { cmd_check_power_mode, ALL_OK | SET_DSC },
[WIN_SLEEPNOW1] = { cmd_nop, ALL_OK },
[WIN_STANDBYNOW1] = { cmd_nop, HD_CFA_OK },
[WIN_IDLEIMMEDIATE] = { cmd_nop, HD_CFA_OK },
[WIN_STANDBY] = { cmd_nop, HD_CFA_OK },
[WIN_SETIDLE1] = { cmd_nop, HD_CFA_OK },
[WIN_CHECKPOWERMODE1] = { cmd_check_power_mode, HD_CFA_OK | SET_DSC },
[WIN_SLEEPNOW1] = { cmd_nop, HD_CFA_OK },
[WIN_FLUSH_CACHE] = { cmd_flush_cache, ALL_OK },
[WIN_FLUSH_CACHE_EXT] = { cmd_flush_cache, HD_CFA_OK },
[WIN_IDENTIFY] = { cmd_identify, ALL_OK },
[WIN_SETFEATURES] = { cmd_set_features, ALL_OK | SET_DSC },
[IBM_SENSE_CONDITION] = { cmd_ibm_sense_condition, CFA_OK | SET_DSC },
[CFA_WEAR_LEVEL] = { cmd_cfa_erase_sectors, HD_CFA_OK | SET_DSC },
[WIN_READ_NATIVE_MAX] = { cmd_read_native_max, ALL_OK | SET_DSC },
[WIN_READ_NATIVE_MAX] = { cmd_read_native_max, HD_CFA_OK | SET_DSC },
};
static bool ide_cmd_permitted(IDEState *s, uint32_t cmd)
@@ -1930,11 +1930,17 @@ void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
}
p = s->data_ptr;
if (p + 2 > s->data_end) {
return;
}
*(uint16_t *)p = le16_to_cpu(val);
p += 2;
s->data_ptr = p;
if (p >= s->data_end)
if (p >= s->data_end) {
s->status &= ~DRQ_STAT;
s->end_transfer_func(s);
}
}
uint32_t ide_data_readw(void *opaque, uint32_t addr)
@@ -1951,11 +1957,17 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr)
}
p = s->data_ptr;
if (p + 2 > s->data_end) {
return 0;
}
ret = cpu_to_le16(*(uint16_t *)p);
p += 2;
s->data_ptr = p;
if (p >= s->data_end)
if (p >= s->data_end) {
s->status &= ~DRQ_STAT;
s->end_transfer_func(s);
}
return ret;
}
@@ -1972,11 +1984,17 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
}
p = s->data_ptr;
if (p + 4 > s->data_end) {
return;
}
*(uint32_t *)p = le32_to_cpu(val);
p += 4;
s->data_ptr = p;
if (p >= s->data_end)
if (p >= s->data_end) {
s->status &= ~DRQ_STAT;
s->end_transfer_func(s);
}
}
uint32_t ide_data_readl(void *opaque, uint32_t addr)
@@ -1993,11 +2011,17 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr)
}
p = s->data_ptr;
if (p + 4 > s->data_end) {
return 0;
}
ret = cpu_to_le32(*(uint32_t *)p);
p += 4;
s->data_ptr = p;
if (p >= s->data_end)
if (p >= s->data_end) {
s->status &= ~DRQ_STAT;
s->end_transfer_func(s);
}
return ret;
}
@@ -2299,7 +2323,7 @@ static int ide_drive_post_load(void *opaque, int version_id)
{
IDEState *s = opaque;
if (s->identify_set) {
if (s->bs && s->identify_set) {
bdrv_set_enable_write_cache(s->bs, !!(s->identify_data[85] & (1 << 5)));
}
return 0;

View File

@@ -74,7 +74,8 @@ static void an5206_init(MachineState *machine)
NULL, NULL, 1, ELF_MACHINE, 0);
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL,
NULL, NULL);
}
if (kernel_size < 0) {
kernel_size = load_image_targphys(kernel_filename, KERNEL_LOAD_ADDR,

View File

@@ -50,7 +50,8 @@ static void dummy_m68k_init(MachineState *machine)
NULL, NULL, 1, ELF_MACHINE, 0);
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL,
NULL, NULL);
}
if (kernel_size < 0) {
kernel_size = load_image_targphys(kernel_filename,

View File

@@ -279,7 +279,8 @@ static void mcf5208evb_init(MachineState *machine)
NULL, NULL, 1, ELF_MACHINE, 0);
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL,
NULL, NULL);
}
if (kernel_size < 0) {
kernel_size = load_image_targphys(kernel_filename, 0x40000000,

View File

@@ -252,7 +252,7 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp)
error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property is not set");
return;
}
if (dimm->node >= nb_numa_nodes) {
if ((nb_numa_nodes > 0) && (dimm->node >= nb_numa_nodes)) {
error_setg(errp, "'DIMM property " PC_DIMM_NODE_PROP " has value %"
PRIu32 "' which exceeds the number of numa nodes: %d",
dimm->node, nb_numa_nodes);

View File

@@ -154,7 +154,8 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
if (kernel_size < 0) {
hwaddr uentry, loadaddr;
kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0);
kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0,
NULL, NULL);
boot_info.bootstrap_pc = uentry;
high = (loadaddr + kernel_size + 3) & ~3;
}

View File

@@ -24,10 +24,12 @@
#include "migration/migration.h"
#include "qapi/qmp/qerror.h"
#include "qemu/event_notifier.h"
#include "qemu/fifo8.h"
#include "sysemu/char.h"
#include <sys/mman.h>
#include <sys/types.h>
#include <limits.h>
#define PCI_VENDOR_ID_IVSHMEM PCI_VENDOR_ID_REDHAT_QUMRANET
#define PCI_DEVICE_ID_IVSHMEM 0x1110
@@ -73,6 +75,7 @@ typedef struct IVShmemState {
CharDriverState **eventfd_chr;
CharDriverState *server_chr;
Fifo8 incoming_fifo;
MemoryRegion ivshmem_mmio;
/* We might need to register the BAR before we actually have the memory.
@@ -383,6 +386,9 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
if (!ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
return;
}
if (posn < 0 || posn >= s->nb_peers) {
return;
}
guest_curr_max = s->peers[posn].nb_eventfds;
@@ -401,14 +407,24 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
/* this function increase the dynamic storage need to store data about other
* guests */
static void increase_dynamic_storage(IVShmemState *s, int new_min_size) {
static int increase_dynamic_storage(IVShmemState *s, int new_min_size)
{
int j, old_nb_alloc;
/* check for integer overflow */
if (new_min_size >= INT_MAX / sizeof(Peer) - 1 || new_min_size <= 0) {
return -1;
}
old_nb_alloc = s->nb_peers;
while (new_min_size >= s->nb_peers)
s->nb_peers = s->nb_peers * 2;
if (new_min_size >= s->nb_peers) {
/* +1 because #new_min_size is used as last array index */
s->nb_peers = new_min_size + 1;
} else {
return 0;
}
IVSHMEM_DPRINTF("bumping storage to %d guests\n", s->nb_peers);
s->peers = g_realloc(s->peers, s->nb_peers * sizeof(Peer));
@@ -418,23 +434,57 @@ static void increase_dynamic_storage(IVShmemState *s, int new_min_size) {
s->peers[j].eventfds = NULL;
s->peers[j].nb_eventfds = 0;
}
return 0;
}
static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
static void ivshmem_read(void *opaque, const uint8_t *buf, int size)
{
IVShmemState *s = opaque;
int incoming_fd, tmp_fd;
int guest_max_eventfd;
long incoming_posn;
memcpy(&incoming_posn, buf, sizeof(long));
if (fifo8_is_empty(&s->incoming_fifo) && size == sizeof(incoming_posn)) {
memcpy(&incoming_posn, buf, size);
} else {
const uint8_t *p;
uint32_t num;
IVSHMEM_DPRINTF("short read of %d bytes\n", size);
num = MAX(size, sizeof(long) - fifo8_num_used(&s->incoming_fifo));
fifo8_push_all(&s->incoming_fifo, buf, num);
if (fifo8_num_used(&s->incoming_fifo) < sizeof(incoming_posn)) {
return;
}
size -= num;
buf += num;
p = fifo8_pop_buf(&s->incoming_fifo, sizeof(incoming_posn), &num);
g_assert(num == sizeof(incoming_posn));
memcpy(&incoming_posn, p, sizeof(incoming_posn));
if (size > 0) {
fifo8_push_all(&s->incoming_fifo, buf, size);
}
}
if (incoming_posn < -1) {
IVSHMEM_DPRINTF("invalid incoming_posn %ld\n", incoming_posn);
return;
}
/* pick off s->server_chr->msgfd and store it, posn should accompany msg */
tmp_fd = qemu_chr_fe_get_msgfd(s->server_chr);
IVSHMEM_DPRINTF("posn is %ld, fd is %d\n", incoming_posn, tmp_fd);
/* make sure we have enough space for this guest */
if (incoming_posn >= s->nb_peers) {
increase_dynamic_storage(s, incoming_posn);
if (increase_dynamic_storage(s, incoming_posn) < 0) {
error_report("increase_dynamic_storage() failed");
if (tmp_fd != -1) {
close(tmp_fd);
}
return;
}
}
if (tmp_fd == -1) {
@@ -458,6 +508,7 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
if (incoming_fd == -1) {
fprintf(stderr, "could not allocate file descriptor %s\n",
strerror(errno));
close(tmp_fd);
return;
}
@@ -659,6 +710,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
s->ivshmem_size = ivshmem_get_size(s);
}
fifo8_create(&s->incoming_fifo, sizeof(long));
register_savevm(DEVICE(dev), "ivshmem", 0, 0, ivshmem_save, ivshmem_load,
dev);
@@ -795,6 +848,7 @@ static void pci_ivshmem_uninit(PCIDevice *dev)
memory_region_destroy(&s->ivshmem);
memory_region_destroy(&s->bar);
unregister_savevm(DEVICE(dev), "ivshmem", s);
fifo8_destroy(&s->incoming_fifo);
}
static Property ivshmem_properties[] = {

View File

@@ -786,7 +786,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;
@@ -1038,7 +1039,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

@@ -774,6 +774,11 @@ static void tx_command(EEPRO100State *s)
#if 0
uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, tbd_address + 6);
#endif
if (tx_buffer_size == 0) {
/* Prevent an endless loop. */
logout("loop in %s:%u\n", __FILE__, __LINE__);
break;
}
tbd_address += 8;
TRACE(RXTX, logout
("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n",
@@ -855,6 +860,10 @@ static void set_multicast_list(EEPRO100State *s)
static void action_command(EEPRO100State *s)
{
/* The loop below won't stop if it gets special handcrafted data.
Therefore we limit the number of iterations. */
unsigned max_loop_count = 16;
for (;;) {
bool bit_el;
bool bit_s;
@@ -870,6 +879,13 @@ static void action_command(EEPRO100State *s)
#if 0
bool bit_sf = ((s->tx.command & COMMAND_SF) != 0);
#endif
if (max_loop_count-- == 0) {
/* Prevent an endless loop. */
logout("loop in %s:%u\n", __FILE__, __LINE__);
break;
}
s->cu_offset = s->tx.link;
TRACE(OTHER,
logout("val=(cu start), status=0x%04x, command=0x%04x, link=0x%08x\n",

View File

@@ -82,6 +82,9 @@ static ssize_t mipsnet_receive(NetClientState *nc, const uint8_t *buf, size_t si
if (!mipsnet_can_receive(nc))
return -1;
if (size >= sizeof(s->rx_buffer)) {
return 0;
}
s->busy = 1;
/* Just accept everything. */

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)
@@ -230,6 +234,9 @@ ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
}
index = s->curpag << 8;
if (index >= NE2000_PMEM_END) {
index = s->start;
}
/* 4 bytes for header */
total_len = size + 4;
/* address for next packet (4 bytes for CRC) */
@@ -253,7 +260,7 @@ ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
if (index <= s->stop)
avail = s->stop - index;
else
avail = 0;
break;
len = size;
if (len > avail)
len = avail;
@@ -315,13 +322,19 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
offset = addr | (page << 4);
switch(offset) {
case EN0_STARTPG:
s->start = val << 8;
if (val << 8 <= NE2000_PMEM_END) {
s->start = val << 8;
}
break;
case EN0_STOPPG:
s->stop = val << 8;
if (val << 8 <= NE2000_PMEM_END) {
s->stop = val << 8;
}
break;
case EN0_BOUNDARY:
s->boundary = val;
if (val << 8 < NE2000_PMEM_END) {
s->boundary = val;
}
break;
case EN0_IMR:
s->imr = val;
@@ -362,7 +375,9 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
s->phys[offset - EN1_PHYS] = val;
break;
case EN1_CURPAG:
s->curpag = val;
if (val << 8 < NE2000_PMEM_END) {
s->curpag = val;
}
break;
case EN1_MULT ... EN1_MULT + 7:
s->mult[offset - EN1_MULT] = val;
@@ -465,8 +480,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);
}
}
@@ -495,8 +511,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

@@ -1086,6 +1086,12 @@ ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
int pktcount = 0;
if (!s->looptest) {
if (size > 4092) {
#ifdef PCNET_DEBUG_RMD
fprintf(stderr, "pcnet: truncates rx packet.\n");
#endif
size = 4092;
}
memcpy(src, buf, size);
/* no need to compute the CRC */
src[size] = 0;
@@ -1212,7 +1218,7 @@ static void pcnet_transmit(PCNetState *s)
hwaddr xmit_cxda = 0;
int count = CSR_XMTRL(s)-1;
int add_crc = 0;
int bcnt;
s->xmit_pos = -1;
if (!CSR_TXON(s)) {
@@ -1247,35 +1253,48 @@ static void pcnet_transmit(PCNetState *s)
s->xmit_pos = -1;
goto txdone;
}
if (!GET_FIELD(tmd.status, TMDS, ENP)) {
int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
s->xmit_pos += bcnt;
} else if (s->xmit_pos >= 0) {
int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
s->xmit_pos += bcnt;
#ifdef PCNET_DEBUG
printf("pcnet_transmit size=%d\n", s->xmit_pos);
#endif
if (CSR_LOOP(s)) {
if (BCR_SWSTYLE(s) == 1)
add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos);
s->looptest = 0;
} else
if (s->nic)
qemu_send_packet(qemu_get_queue(s->nic), s->buffer,
s->xmit_pos);
s->csr[0] &= ~0x0008; /* clear TDMD */
s->csr[4] |= 0x0004; /* set TXSTRT */
s->xmit_pos = -1;
if (s->xmit_pos < 0) {
goto txdone;
}
bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
/* if multi-tmd packet outsizes s->buffer then skip it silently.
Note: this is not what real hw does */
if (s->xmit_pos + bcnt > sizeof(s->buffer)) {
s->xmit_pos = -1;
goto txdone;
}
s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
s->xmit_pos += bcnt;
if (!GET_FIELD(tmd.status, TMDS, ENP)) {
goto txdone;
}
#ifdef PCNET_DEBUG
printf("pcnet_transmit size=%d\n", s->xmit_pos);
#endif
if (CSR_LOOP(s)) {
if (BCR_SWSTYLE(s) == 1)
add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos);
s->looptest = 0;
} else {
if (s->nic) {
qemu_send_packet(qemu_get_queue(s->nic), s->buffer,
s->xmit_pos);
}
}
s->csr[0] &= ~0x0008; /* clear TDMD */
s->csr[4] |= 0x0004; /* set TXSTRT */
s->xmit_pos = -1;
txdone:
SET_FIELD(&tmd.status, TMDS, OWN, 0);
TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));

View File

@@ -236,8 +236,18 @@ static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf, si
n = s->next_packet + s->np;
if (n >= 31)
n -= 31;
s->np++;
if (size >= sizeof(s->rx[n].data) - 6) {
/* If the packet won't fit into the
* emulated 2K RAM, this is reported
* as a FIFO overrun error.
*/
s->ris |= SE_INT_FOV;
stellaris_enet_update(s);
return -1;
}
s->np++;
s->rx[n].len = size + 6;
p = s->rx[n].data;
*(p++) = (size + 6);

View File

@@ -163,11 +163,11 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
if (r < 0) {
goto fail;
}
if (!qemu_has_vnet_hdr_len(options->net_backend,
sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
}
if (backend_kernel) {
if (!qemu_has_vnet_hdr_len(options->net_backend,
sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
}
if (~net->dev.features & net->dev.backend_features) {
fprintf(stderr, "vhost lacks feature mask %" PRIu64
" for backend\n",

View File

@@ -798,7 +798,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
VirtQueueElement elem;
size_t s;
struct iovec *iov;
struct iovec *iov, *iov2;
unsigned int iov_cnt;
while (virtqueue_pop(vq, &elem)) {
@@ -808,8 +808,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
exit(1);
}
iov = elem.out_sg;
iov_cnt = elem.out_num;
iov2 = iov = g_memdup(elem.out_sg, sizeof(struct iovec) * elem.out_num);
s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
iov_discard_front(&iov, &iov_cnt, sizeof(ctrl));
if (s != sizeof(ctrl)) {
@@ -833,6 +833,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
virtqueue_push(vq, &elem, sizeof(status));
virtio_notify(vdev, vq);
g_free(iov2);
}
}
@@ -1069,13 +1070,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
* must have consumed the complete packet.
* Otherwise, drop it. */
if (!n->mergeable_rx_bufs && offset < size) {
#if 0
error_report("virtio-net truncated non-mergeable packet: "
"i %zd mergeable %d offset %zd, size %zd, "
"guest hdr len %zd, host hdr len %zd",
i, n->mergeable_rx_bufs,
offset, size, n->guest_hdr_len, n->host_hdr_len);
#endif
virtqueue_discard(q->rx_vq, &elem, total);
return size;
}
@@ -1125,8 +1120,6 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
return num_packets;
}
assert(vdev->vm_running);
if (q->async_tx.elem.out_num) {
virtio_queue_set_notification(q->tx_vq, 0);
return num_packets;

View File

@@ -729,9 +729,7 @@ static void vmxnet3_process_tx_queue(VMXNET3State *s, int qidx)
}
if (txd.eop) {
if (!s->skip_current_tx_pkt) {
vmxnet_tx_pkt_parse(s->tx_pkt);
if (!s->skip_current_tx_pkt && vmxnet_tx_pkt_parse(s->tx_pkt)) {
if (s->needs_vlan) {
vmxnet_tx_pkt_setup_vlan_header(s->tx_pkt, s->tci);
}
@@ -1108,9 +1106,13 @@ vmxnet3_io_bar0_write(void *opaque, hwaddr addr,
static uint64_t
vmxnet3_io_bar0_read(void *opaque, hwaddr addr, unsigned size)
{
VMXNET3State *s = opaque;
if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_IMR,
VMXNET3_MAX_INTRS, VMXNET3_REG_ALIGN)) {
g_assert_not_reached();
int l = VMW_MULTIREG_IDX_BY_ADDR(addr, VMXNET3_REG_IMR,
VMXNET3_REG_ALIGN);
return s->interrupt_states[l].is_masked;
}
VMW_CBPRN("BAR0 unknown read [%" PRIx64 "], size %d", addr, size);
@@ -1135,8 +1137,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)
@@ -1145,7 +1152,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;
@@ -1368,6 +1374,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);
@@ -1564,7 +1576,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;
@@ -1668,8 +1680,8 @@ vmxnet3_io_bar1_write(void *opaque,
* memory address. We save it to temp variable and set the
* shared address only after we get the high part
*/
if (0 == val) {
s->device_active = false;
if (val == 0) {
vmxnet3_deactivate_device(s);
}
s->temp_shared_guest_driver_memory = val;
s->drv_shmem = 0;
@@ -1956,9 +1968,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

@@ -142,11 +142,24 @@ static bool vmxnet_tx_pkt_parse_headers(struct VmxnetTxPkt *pkt)
bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags, 0, l2_hdr->iov_base,
ETH_MAX_L2_HDR_LEN);
if (bytes_read < ETH_MAX_L2_HDR_LEN) {
if (bytes_read < sizeof(struct eth_header)) {
l2_hdr->iov_len = 0;
return false;
}
l2_hdr->iov_len = sizeof(struct eth_header);
switch (be16_to_cpu(PKT_GET_ETH_HDR(l2_hdr->iov_base)->h_proto)) {
case ETH_P_VLAN:
l2_hdr->iov_len += sizeof(struct vlan_header);
break;
case ETH_P_DVLAN:
l2_hdr->iov_len += 2 * sizeof(struct vlan_header);
break;
}
if (bytes_read < l2_hdr->iov_len) {
l2_hdr->iov_len = 0;
return false;
} else {
l2_hdr->iov_len = eth_get_l2_hdr_length(l2_hdr->iov_base);
}
l3_proto = eth_get_l3_proto(l2_hdr->iov_base, l2_hdr->iov_len);

View File

@@ -211,12 +211,15 @@ static void fw_cfg_reboot(FWCfgState *s)
static void fw_cfg_write(FWCfgState *s, uint8_t value)
{
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];
trace_fw_cfg_write(s, value);
if (s->cur_entry & FW_CFG_WRITE_CHANNEL && e->callback &&
s->cur_offset < e->len) {
if (s->cur_entry & FW_CFG_WRITE_CHANNEL
&& e != NULL
&& e->callback
&& s->cur_offset < e->len) {
e->data[s->cur_offset++] = value;
if (s->cur_offset == e->len) {
e->callback(e->callback_opaque, e->data);
@@ -245,7 +248,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)

View File

@@ -72,7 +72,7 @@ static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
entry = elf_entry;
if (kernel_size < 0) {
kernel_size = load_uimage(kernel_filename,
&entry, NULL, NULL);
&entry, NULL, NULL, NULL, NULL);
}
if (kernel_size < 0) {
kernel_size = load_image_targphys(kernel_filename,

View File

@@ -291,7 +291,7 @@ void msi_notify(PCIDevice *dev, unsigned int vector)
"notify vector 0x%x"
" address: 0x%"PRIx64" data: 0x%"PRIx32"\n",
vector, msg.address, msg.data);
stl_le_phys(&address_space_memory, msg.address, msg.data);
stl_le_phys(&dev->bus_master_as, msg.address, msg.data);
}
/* Normally called by pci_default_write_config(). */

View File

@@ -200,8 +200,14 @@ static uint64_t msix_pba_mmio_read(void *opaque, hwaddr addr,
return pci_get_long(dev->msix_pba + addr);
}
static void msix_pba_mmio_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
}
static const MemoryRegionOps msix_pba_mmio_ops = {
.read = msix_pba_mmio_read,
.write = msix_pba_mmio_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4,
@@ -439,7 +445,7 @@ void msix_notify(PCIDevice *dev, unsigned vector)
msg = msix_get_message(dev, vector);
stl_le_phys(&address_space_memory, msg.address, msg.data);
stl_le_phys(&dev->bus_master_as, msg.address, msg.data);
}
void msix_reset(PCIDevice *dev)

View File

@@ -830,7 +830,8 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
* Hrm. No ELF image? Try a uImage, maybe someone is giving us an
* ePAPR compliant kernel
*/
kernel_size = load_uimage(filename, &bios_entry, &loadaddr, NULL);
kernel_size = load_uimage(filename, &bios_entry, &loadaddr, NULL,
NULL, NULL);
if (kernel_size < 0) {
fprintf(stderr, "qemu: could not load firmware '%s'\n", filename);
exit(1);

View File

@@ -253,7 +253,8 @@ static void bamboo_init(MachineState *machine)
/* Load kernel. */
if (kernel_filename) {
success = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
success = load_uimage(kernel_filename, &entry, &loadaddr, NULL,
NULL, NULL);
if (success < 0) {
success = load_elf(kernel_filename, NULL, NULL, &elf_entry,
&elf_lowaddr, NULL, 1, ELF_MACHINE, 0);

View File

@@ -172,9 +172,9 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn,
return tcet;
}
static void spapr_tce_table_finalize(Object *obj)
static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp)
{
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(obj);
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
QLIST_REMOVE(tcet, list);
@@ -419,6 +419,7 @@ static void spapr_tce_table_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->init = spapr_tce_table_realize;
dc->reset = spapr_tce_reset;
dc->unrealize = spapr_tce_table_unrealize;
QLIST_INIT(&spapr_tce_tables);
@@ -434,7 +435,6 @@ static TypeInfo spapr_tce_table_info = {
.parent = TYPE_DEVICE,
.instance_size = sizeof(sPAPRTCETable),
.class_init = spapr_tce_table_class_init,
.instance_finalize = spapr_tce_table_finalize,
};
static void register_types(void)

View File

@@ -700,28 +700,34 @@ static const VMStateDescription vmstate_spapr_pci_msi = {
},
};
static void spapr_pci_fill_msi_devs(gpointer key, gpointer value,
gpointer opaque)
{
sPAPRPHBState *sphb = opaque;
sphb->msi_devs[sphb->msi_devs_num].key = *(uint32_t *)key;
sphb->msi_devs[sphb->msi_devs_num].value = *(spapr_pci_msi *)value;
sphb->msi_devs_num++;
}
static void spapr_pci_pre_save(void *opaque)
{
sPAPRPHBState *sphb = opaque;
GHashTableIter iter;
gpointer key, value;
int i;
int msi_devs_num;
if (sphb->msi_devs) {
g_free(sphb->msi_devs);
sphb->msi_devs = NULL;
}
sphb->msi_devs_num = g_hash_table_size(sphb->msi);
if (!sphb->msi_devs_num) {
sphb->msi_devs_num = 0;
msi_devs_num = g_hash_table_size(sphb->msi);
if (!msi_devs_num) {
return;
}
sphb->msi_devs = g_malloc(sphb->msi_devs_num * sizeof(spapr_pci_msi_mig));
sphb->msi_devs = g_malloc(msi_devs_num * sizeof(spapr_pci_msi_mig));
g_hash_table_iter_init(&iter, sphb->msi);
for (i = 0; g_hash_table_iter_next(&iter, &key, &value); ++i) {
sphb->msi_devs[i].key = *(uint32_t *) key;
sphb->msi_devs[i].value = *(spapr_pci_msi *) value;
}
g_hash_table_foreach(sphb->msi, spapr_pci_fill_msi_devs, sphb);
assert(sphb->msi_devs_num == msi_devs_num);
}
static int spapr_pci_post_load(void *opaque, int version_id)

View File

@@ -161,6 +161,8 @@ static void s390_virtio_net_instance_init(Object *obj)
VirtIONetS390 *dev = VIRTIO_NET_S390(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
}
static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
@@ -224,6 +226,8 @@ static void s390_virtio_serial_instance_init(Object *obj)
VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
object_unref(OBJECT(&dev->vdev));
}
static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev)
@@ -256,6 +260,8 @@ static void s390_virtio_scsi_instance_init(Object *obj)
VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
}
#ifdef CONFIG_VHOST_SCSI
@@ -277,6 +283,8 @@ static void s390_vhost_scsi_instance_init(Object *obj)
VHostSCSIS390 *dev = VHOST_SCSI_S390(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
}
#endif
@@ -303,6 +311,8 @@ static void s390_virtio_rng_instance_init(Object *obj)
VirtIORNGS390 *dev = VIRTIO_RNG_S390(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
object_unref(OBJECT(&dev->vdev));
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
(Object **)&dev->vdev.conf.rng,
qdev_prop_allow_set_link_before_realize,
@@ -493,10 +503,8 @@ static unsigned virtio_s390_get_features(DeviceState *d)
/**************** S390 Virtio Bus Device Descriptions *******************/
static Property s390_virtio_net_properties[] = {
DEFINE_NIC_PROPERTIES(VirtIONetS390, vdev.nic_conf),
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
DEFINE_VIRTIO_NET_FEATURES(VirtIOS390Device, host_features),
DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetS390, vdev.net_conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -533,7 +541,6 @@ static const TypeInfo s390_virtio_blk = {
};
static Property s390_virtio_serial_properties[] = {
DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtIOSerialS390, vdev.serial),
DEFINE_PROP_END_OF_LIST(),
};
@@ -556,7 +563,6 @@ static const TypeInfo s390_virtio_serial = {
static Property s390_virtio_rng_properties[] = {
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGS390, vdev.conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -614,7 +620,6 @@ static const TypeInfo virtio_s390_device_info = {
};
static Property s390_virtio_scsi_properties[] = {
DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIS390, vdev.parent_obj.conf),
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
DEFINE_VIRTIO_SCSI_FEATURES(VirtIOS390Device, host_features),
DEFINE_PROP_END_OF_LIST(),
@@ -640,7 +645,6 @@ static const TypeInfo s390_virtio_scsi = {
#ifdef CONFIG_VHOST_SCSI
static Property s390_vhost_scsi_properties[] = {
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
DEFINE_VHOST_SCSI_PROPERTIES(VHostSCSIS390, vdev.parent_obj.conf),
DEFINE_PROP_END_OF_LIST(),
};

View File

@@ -794,6 +794,8 @@ static void virtio_ccw_net_instance_init(Object *obj)
VirtIONetCcw *dev = VIRTIO_NET_CCW(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
}
static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
@@ -850,6 +852,8 @@ static void virtio_ccw_serial_instance_init(Object *obj)
VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
object_unref(OBJECT(&dev->vdev));
}
static int virtio_ccw_balloon_init(VirtioCcwDevice *ccw_dev)
@@ -896,7 +900,7 @@ static void virtio_ccw_balloon_instance_init(Object *obj)
VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
object_property_add(obj, "guest-stats", "guest statistics",
balloon_ccw_stats_get_all, NULL, NULL, dev, NULL);
@@ -936,6 +940,8 @@ static void virtio_ccw_scsi_instance_init(Object *obj)
VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
}
#ifdef CONFIG_VHOST_SCSI
@@ -957,6 +963,8 @@ static void vhost_ccw_scsi_instance_init(Object *obj)
VHostSCSICcw *dev = VHOST_SCSI_CCW(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
}
#endif
@@ -1374,8 +1382,6 @@ static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f)
static Property virtio_ccw_net_properties[] = {
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features[0]),
DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetCcw, vdev.net_conf),
DEFINE_NIC_PROPERTIES(VirtIONetCcw, vdev.nic_conf),
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_END_OF_LIST(),
@@ -1428,7 +1434,6 @@ static const TypeInfo virtio_ccw_blk = {
static Property virtio_ccw_serial_properties[] = {
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtioSerialCcw, vdev.serial),
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_END_OF_LIST(),
@@ -1481,7 +1486,6 @@ static const TypeInfo virtio_ccw_balloon = {
static Property virtio_ccw_scsi_properties[] = {
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features[0]),
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
@@ -1510,7 +1514,6 @@ static const TypeInfo virtio_ccw_scsi = {
#ifdef CONFIG_VHOST_SCSI
static Property vhost_ccw_scsi_properties[] = {
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
DEFINE_VHOST_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1539,6 +1542,8 @@ static void virtio_ccw_rng_instance_init(Object *obj)
VirtIORNGCcw *dev = VIRTIO_RNG_CCW(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
object_unref(OBJECT(&dev->vdev));
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
(Object **)&dev->vdev.conf.rng,
qdev_prop_allow_set_link_before_realize,
@@ -1547,7 +1552,6 @@ static void virtio_ccw_rng_instance_init(Object *obj)
static Property virtio_ccw_rng_properties[] = {
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGCcw, vdev.conf),
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_END_OF_LIST(),

View File

@@ -268,6 +268,8 @@ static void esp_pci_dma_memory_rw(PCIESPState *pci, uint8_t *buf, int len,
/* update status registers */
pci->dma_regs[DMA_WBC] -= len;
pci->dma_regs[DMA_WAC] += len;
if (pci->dma_regs[DMA_WBC] == 0)
pci->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
}
static void esp_pci_dma_memory_read(void *opaque, uint8_t *buf, int len)

View File

@@ -691,7 +691,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
int num_ld_disks = 0;
uint16_t sdev_id;
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

@@ -23,6 +23,7 @@
#include "hw/virtio/vhost.h"
#include "hw/virtio/virtio-scsi.h"
#include "hw/virtio/virtio-bus.h"
#include "hw/virtio/virtio-access.h"
/* Features supported by host kernel. */
static const int kernel_feature_bits[] = {
@@ -163,8 +164,8 @@ static void vhost_scsi_set_config(VirtIODevice *vdev,
VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config;
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
if ((uint32_t) ldl_p(&scsiconf->sense_size) != vs->sense_size ||
(uint32_t) ldl_p(&scsiconf->cdb_size) != vs->cdb_size) {
if ((uint32_t) virtio_ldl_p(vdev, &scsiconf->sense_size) != vs->sense_size ||
(uint32_t) virtio_ldl_p(vdev, &scsiconf->cdb_size) != vs->cdb_size) {
error_report("vhost-scsi does not support changing the sense data and CDB sizes");
exit(1);
}

View File

@@ -135,6 +135,7 @@ static size_t qemu_sgl_concat(VirtIOSCSIReq *req, struct iovec *iov,
static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
unsigned req_size, unsigned resp_size)
{
VirtIODevice *vdev = (VirtIODevice *) req->dev;
size_t in_size, out_size;
if (iov_to_buf(req->elem.out_sg, req->elem.out_num, 0,
@@ -147,8 +148,24 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
resp_size) < resp_size) {
return -EINVAL;
}
req->resp_size = resp_size;
/* Old BIOSes left some padding by mistake after the req_size/resp_size.
* As a workaround, always consider the first buffer as the virtio-scsi
* request/response, making the payload start at the second element
* of the iovec.
*
* The actual length of the response header, stored in req->resp_size,
* does not change.
*
* TODO: always disable this workaround for virtio 1.0 devices.
*/
if ((vdev->guest_features & VIRTIO_F_ANY_LAYOUT) == 0) {
req_size = req->elem.out_sg[0].iov_len;
resp_size = req->elem.in_sg[0].iov_len;
}
out_size = qemu_sgl_concat(req, req->elem.out_sg,
&req->elem.out_addr[0], req->elem.out_num,
req_size);
@@ -400,7 +417,7 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
sense_len = scsi_req_get_sense(r, sense, sizeof(sense));
sense_len = MIN(sense_len, req->resp_iov.size - sizeof(req->resp.cmd));
qemu_iovec_from_buf(&req->resp_iov, sizeof(req->resp.cmd),
&req->resp, sense_len);
sense, sense_len);
req->resp.cmd.sense_len = virtio_tswap32(vdev, sense_len);
}
virtio_scsi_complete_cmd_req(req);

View File

@@ -911,8 +911,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,
@@ -957,8 +958,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);
@@ -1208,8 +1210,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

@@ -899,6 +899,11 @@ static uint64_t ehci_caps_read(void *ptr, hwaddr addr,
return s->caps[addr];
}
static void ehci_caps_write(void *ptr, hwaddr addr,
uint64_t val, unsigned size)
{
}
static uint64_t ehci_opreg_read(void *ptr, hwaddr addr,
unsigned size)
{
@@ -2006,6 +2011,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 {
@@ -2030,10 +2036,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:
@@ -2082,7 +2090,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;
@@ -2316,6 +2325,7 @@ static void ehci_frame_timer(void *opaque)
static const MemoryRegionOps ehci_mmio_caps_ops = {
.read = ehci_caps_read,
.write = ehci_caps_write,
.valid.min_access_size = 1,
.valid.max_access_size = 4,
.impl.min_access_size = 1,

View File

@@ -499,6 +499,7 @@ enum xhci_flags {
XHCI_FLAG_USE_MSI = 1,
XHCI_FLAG_USE_MSI_X,
XHCI_FLAG_SS_FIRST,
XHCI_FLAG_FORCE_PCIE_ENDCAP,
};
static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
@@ -3626,7 +3627,8 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,
&xhci->mem);
if (pci_bus_is_express(dev->bus)) {
if (pci_bus_is_express(dev->bus) ||
xhci_get_flag(xhci, XHCI_FLAG_FORCE_PCIE_ENDCAP)) {
ret = pcie_endpoint_cap_init(dev, 0xa0);
assert(ret >= 0);
}
@@ -3818,6 +3820,8 @@ static Property xhci_properties[] = {
DEFINE_PROP_BIT("msix", XHCIState, flags, XHCI_FLAG_USE_MSI_X, true),
DEFINE_PROP_BIT("superspeed-ports-first",
XHCIState, flags, XHCI_FLAG_SS_FIRST, true),
DEFINE_PROP_BIT("force-pcie-endcap", XHCIState, flags,
XHCI_FLAG_FORCE_PCIE_ENDCAP, false),
DEFINE_PROP_UINT32("intrs", XHCIState, numintrs, MAXINTRS),
DEFINE_PROP_UINT32("slots", XHCIState, numslots, MAXSLOTS),
DEFINE_PROP_UINT32("p2", XHCIState, numports_2, 4),

View File

@@ -87,7 +87,7 @@ static void balloon_stats_destroy_timer(VirtIOBalloon *s)
}
}
static void balloon_stats_change_timer(VirtIOBalloon *s, int secs)
static void balloon_stats_change_timer(VirtIOBalloon *s, int64_t secs)
{
timer_mod(s->stats_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + secs * 1000);
}
@@ -170,6 +170,11 @@ static void balloon_stats_set_poll_interval(Object *obj, struct Visitor *v,
return;
}
if (value > UINT_MAX) {
error_setg(errp, "timer value is too big");
return;
}
if (value == s->stats_poll_interval) {
return;
}

View File

@@ -314,6 +314,16 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
msix_unuse_all_vectors(&proxy->pci_dev);
}
/* Linux before 2.6.34 drives the device without enabling
the PCI device bus master bit. Enable it automatically
for the guest. This is a PCI spec violation but so is
initiating DMA with bus master bit clear. */
if (val == (VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER)) {
pci_default_write_config(&proxy->pci_dev, PCI_COMMAND,
proxy->pci_dev.config[PCI_COMMAND] |
PCI_COMMAND_MASTER, 1);
}
/* Linux before 2.6.34 sets the device as OK without enabling
the PCI device bus master bit. In this case we need to disable
some safety checks. */
@@ -914,7 +924,6 @@ static Property virtio_9p_pci_properties[] = {
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
DEFINE_VIRTIO_9P_PROPERTIES(V9fsPCIState, vdev.fsconf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -938,6 +947,8 @@ static void virtio_9p_pci_instance_init(Object *obj)
V9fsPCIState *dev = VIRTIO_9P_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_9P);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
object_unref(OBJECT(&dev->vdev));
}
static const TypeInfo virtio_9p_pci_info = {
@@ -1127,7 +1138,6 @@ static Property virtio_scsi_pci_properties[] = {
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
DEV_NVECTORS_UNSPECIFIED),
DEFINE_VIRTIO_SCSI_FEATURES(VirtIOPCIProxy, host_features),
DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIPCI, vdev.parent_obj.conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1179,6 +1189,8 @@ static void virtio_scsi_pci_instance_init(Object *obj)
VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
}
static const TypeInfo virtio_scsi_pci_info = {
@@ -1195,7 +1207,6 @@ static const TypeInfo virtio_scsi_pci_info = {
static Property vhost_scsi_pci_properties[] = {
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
DEV_NVECTORS_UNSPECIFIED),
DEFINE_VHOST_SCSI_PROPERTIES(VHostSCSIPCI, vdev.parent_obj.conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1235,6 +1246,8 @@ static void vhost_scsi_pci_instance_init(Object *obj)
VHostSCSIPCI *dev = VHOST_SCSI_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
}
static const TypeInfo vhost_scsi_pci_info = {
@@ -1315,7 +1328,7 @@ static void virtio_balloon_pci_instance_init(Object *obj)
VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
object_property_add(obj, "guest-stats", "guest statistics",
balloon_pci_stats_get_all, NULL, NULL, dev,
NULL);
@@ -1377,7 +1390,6 @@ static Property virtio_serial_pci_properties[] = {
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtIOSerialPCI, vdev.serial),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1400,6 +1412,8 @@ static void virtio_serial_pci_instance_init(Object *obj)
VirtIOSerialPCI *dev = VIRTIO_SERIAL_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
object_unref(OBJECT(&dev->vdev));
}
static const TypeInfo virtio_serial_pci_info = {
@@ -1417,8 +1431,6 @@ static Property virtio_net_properties[] = {
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
DEFINE_NIC_PROPERTIES(VirtIONetPCI, vdev.nic_conf),
DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetPCI, vdev.net_conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1459,6 +1471,8 @@ static void virtio_net_pci_instance_init(Object *obj)
VirtIONetPCI *dev = VIRTIO_NET_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
}
static const TypeInfo virtio_net_pci_info = {
@@ -1472,7 +1486,6 @@ static const TypeInfo virtio_net_pci_info = {
/* virtio-rng-pci */
static Property virtio_rng_pci_properties[] = {
DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORngPCI, vdev.conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1514,6 +1527,8 @@ static void virtio_rng_initfn(Object *obj)
VirtIORngPCI *dev = VIRTIO_RNG_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
object_unref(OBJECT(&dev->vdev));
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
(Object **)&dev->vdev.conf.rng,
qdev_prop_allow_set_link_before_realize,

View File

@@ -240,14 +240,12 @@ int virtio_queue_empty(VirtQueue *vq)
return vring_avail_idx(vq) == vq->last_avail_idx;
}
void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
unsigned int len, unsigned int idx)
static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
unsigned int len)
{
unsigned int offset;
int i;
trace_virtqueue_fill(vq, elem, len, idx);
offset = 0;
for (i = 0; i < elem->in_num; i++) {
size_t size = MIN(len - offset, elem->in_sg[i].iov_len);
@@ -263,6 +261,21 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
cpu_physical_memory_unmap(elem->out_sg[i].iov_base,
elem->out_sg[i].iov_len,
0, elem->out_sg[i].iov_len);
}
void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
unsigned int len)
{
vq->last_avail_idx--;
virtqueue_unmap_sg(vq, elem, len);
}
void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
unsigned int len, unsigned int idx)
{
trace_virtqueue_fill(vq, elem, len, idx);
virtqueue_unmap_sg(vq, elem, len);
idx = (idx + vring_used_idx(vq)) % vq->vring.num;
@@ -1108,10 +1121,7 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
if (running) {
vdev->vm_running = running;
}
vdev->vm_running = running;
if (backend_run) {
virtio_set_status(vdev, vdev->status);
@@ -1124,10 +1134,6 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
if (!backend_run) {
virtio_set_status(vdev, vdev->status);
}
if (!running) {
vdev->vm_running = running;
}
}
void virtio_init(VirtIODevice *vdev, const char *name,

View File

@@ -325,7 +325,8 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
} else {
hwaddr ep;
int is_linux;
success = load_uimage(kernel_filename, &ep, NULL, &is_linux);
success = load_uimage(kernel_filename, &ep, NULL, &is_linux,
translate_phys_addr, cpu);
if (success > 0 && is_linux) {
entry_point = ep;
} else {

View File

@@ -40,10 +40,12 @@
#define BLOCK_FLAG_ENCRYPT 1
#define BLOCK_FLAG_COMPAT6 4
#define BLOCK_FLAG_LAZY_REFCOUNTS 8
#define BLOCK_FLAG_SCSI 16
#define BLOCK_OPT_SIZE "size"
#define BLOCK_OPT_ENCRYPT "encryption"
#define BLOCK_OPT_COMPAT6 "compat6"
#define BLOCK_OPT_SCSI "scsi"
#define BLOCK_OPT_BACKING_FILE "backing_file"
#define BLOCK_OPT_BACKING_FMT "backing_fmt"
#define BLOCK_OPT_CLUSTER_SIZE "cluster_size"
@@ -395,6 +397,14 @@ struct BlockDriverState {
Error *backing_blocker;
};
/* Essential block drivers which must always be statically linked into qemu, and
* which therefore can be accessed without using bdrv_find_format() */
extern BlockDriver bdrv_file;
extern BlockDriver bdrv_raw;
extern BlockDriver bdrv_qcow2;
int get_tmp_filename(char *filename, int size);
void bdrv_set_io_limits(BlockDriverState *bs,

View File

@@ -49,6 +49,21 @@ static inline bool cpu_physical_memory_get_dirty(ram_addr_t start,
return next < end;
}
static inline bool cpu_physical_memory_get_clean(ram_addr_t start,
ram_addr_t length,
unsigned client)
{
unsigned long end, page, next;
assert(client < DIRTY_MEMORY_NUM);
end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS;
page = start >> TARGET_PAGE_BITS;
next = find_next_zero_bit(ram_list.dirty_memory[client], end, page);
return next < end;
}
static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr,
unsigned client)
{
@@ -64,6 +79,16 @@ static inline bool cpu_physical_memory_is_clean(ram_addr_t addr)
return !(vga && code && migration);
}
static inline bool cpu_physical_memory_range_includes_clean(ram_addr_t start,
ram_addr_t length)
{
bool vga = cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_VGA);
bool code = cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_CODE);
bool migration =
cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_MIGRATION);
return vga || code || migration;
}
static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr,
unsigned client)
{

View File

@@ -24,6 +24,12 @@
#include <pthread.h>
#define spin_lock pthread_mutex_lock
#define spin_unlock pthread_mutex_unlock
static inline void spin_unlock_safe(pthread_mutex_t *lock)
{
/* unlocking an unlocked mutex results in undefined behavior */
pthread_mutex_trylock(lock);
pthread_mutex_unlock(lock);
}
#define spinlock_t pthread_mutex_t
#define SPIN_LOCK_UNLOCKED PTHREAD_MUTEX_INITIALIZER
@@ -46,4 +52,8 @@ static inline void spin_unlock(spinlock_t *lock)
{
}
static inline void spin_unlock_safe(spinlock_t *lock)
{
}
#endif

View File

@@ -38,6 +38,7 @@ typedef enum argtype {
TYPE_ARRAY,
TYPE_STRUCT,
TYPE_OLDDEVT,
TYPE_INTBITFIELD,
} argtype;
#define MK_PTR(type) TYPE_PTR, type
@@ -91,6 +92,7 @@ static inline int thunk_type_size(const argtype *type_ptr, int is_host)
case TYPE_SHORT:
return 2;
case TYPE_INT:
case TYPE_INTBITFIELD:
return 4;
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
@@ -153,6 +155,7 @@ static inline int thunk_type_align(const argtype *type_ptr, int is_host)
case TYPE_SHORT:
return 2;
case TYPE_INT:
case TYPE_INTBITFIELD:
return 4;
case TYPE_LONGLONG:
case TYPE_ULONGLONG:

View File

@@ -317,6 +317,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
.property = "superspeed-ports-first",\
.value = "off",\
},\
{\
.driver = "nec-usb-xhci",\
.property = "force-pcie-endcap",\
.value = "on",\
},\
{\
.driver = "pci-serial",\
.property = "prog_if",\

View File

@@ -28,7 +28,9 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
int load_aout(const char *filename, hwaddr addr, int max_sz,
int bswap_needed, hwaddr target_page_size);
int load_uimage(const char *filename, hwaddr *ep,
hwaddr *loadaddr, int *is_linux);
hwaddr *loadaddr, int *is_linux,
uint64_t (*translate_fn)(void *, uint64_t),
void *translate_opaque);
/**
* load_ramdisk:

View File

@@ -177,6 +177,8 @@ void virtio_del_queue(VirtIODevice *vdev, int n);
void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
unsigned int len);
void virtqueue_flush(VirtQueue *vq, unsigned int count);
void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
unsigned int len);
void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
unsigned int len, unsigned int idx);

View File

@@ -55,6 +55,8 @@ struct Visitor
void (*type_int64)(Visitor *v, int64_t *obj, const char *name, Error **errp);
/* visit_type_size() falls back to (*type_uint64)() if type_size is unset */
void (*type_size)(Visitor *v, uint64_t *obj, const char *name, Error **errp);
bool (*start_union)(Visitor *v, bool data_present, Error **errp);
void (*end_union)(Visitor *v, bool data_present, Error **errp);
};
void input_type_enum(Visitor *v, int *obj, const char *strings[],

View File

@@ -58,5 +58,7 @@ void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp);
void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp);
void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp);
void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp);
bool visit_start_union(Visitor *v, bool data_present, Error **errp);
void visit_end_union(Visitor *v, bool data_present, Error **errp);
#endif

View File

@@ -122,11 +122,11 @@
#endif
#ifndef atomic_read
#define atomic_read(ptr) (*(__typeof__(*ptr) *volatile) (ptr))
#define atomic_read(ptr) (*(__typeof__(*ptr) volatile*) (ptr))
#endif
#ifndef atomic_set
#define atomic_set(ptr, i) ((*(__typeof__(*ptr) *volatile) (ptr)) = (i))
#define atomic_set(ptr, i) ((*(__typeof__(*ptr) volatile*) (ptr)) = (i))
#endif
/* These have the same semantics as Java volatile variables.

View File

@@ -10,6 +10,7 @@ void cpu_stop_current(void);
void cpu_synchronize_all_states(void);
void cpu_synchronize_all_post_reset(void);
void cpu_synchronize_all_post_init(void);
void cpu_clean_all_dirty(void);
void qtest_clock_warp(int64_t dest);

View File

@@ -348,6 +348,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
void kvm_cpu_synchronize_state(CPUState *cpu);
void kvm_cpu_synchronize_post_reset(CPUState *cpu);
void kvm_cpu_synchronize_post_init(CPUState *cpu);
void kvm_cpu_clean_state(CPUState *cpu);
/* generic hooks - to be moved/refactored once there are more users */
@@ -372,6 +373,13 @@ static inline void cpu_synchronize_post_init(CPUState *cpu)
}
}
static inline void cpu_clean_state(CPUState *cpu)
{
if (kvm_enabled()) {
kvm_cpu_clean_state(cpu);
}
}
int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg);
void kvm_irqchip_release_virq(KVMState *s, int virq);

View File

@@ -25,6 +25,7 @@
#define RNG_BACKEND_CLASS(klass) \
OBJECT_CLASS_CHECK(RngBackendClass, (klass), TYPE_RNG_BACKEND)
typedef struct RngRequest RngRequest;
typedef struct RngBackendClass RngBackendClass;
typedef struct RngBackend RngBackend;
@@ -32,13 +33,20 @@ typedef void (EntropyReceiveFunc)(void *opaque,
const void *data,
size_t size);
struct RngRequest
{
EntropyReceiveFunc *receive_entropy;
uint8_t *data;
void *opaque;
size_t offset;
size_t size;
};
struct RngBackendClass
{
ObjectClass parent_class;
void (*request_entropy)(RngBackend *s, size_t size,
EntropyReceiveFunc *receive_entropy, void *opaque);
void (*cancel_requests)(RngBackend *s);
void (*request_entropy)(RngBackend *s, RngRequest *req);
void (*opened)(RngBackend *s, Error **errp);
};
@@ -49,8 +57,10 @@ struct RngBackend
/*< protected >*/
bool opened;
GSList *requests;
};
/**
* rng_backend_request_entropy:
* @s: the backend to request entropy from
@@ -71,12 +81,13 @@ void rng_backend_request_entropy(RngBackend *s, size_t size,
void *opaque);
/**
* rng_backend_cancel_requests:
* @s: the backend to cancel all pending requests in
* rng_backend_free_request:
* @s: the backend that created the request
* @req: the request to finalize
*
* Cancels all pending requests submitted by @rng_backend_request_entropy. This
* should be used by a device during reset or in preparation for live migration
* to stop tracking any request.
* Used by child rng backend classes to finalize requests once they've been
* processed. The request is removed from the list of active requests and
* deleted.
*/
void rng_backend_cancel_requests(RngBackend *s);
void rng_backend_finalize_request(RngBackend *s, RngRequest *req);
#endif

View File

@@ -339,7 +339,7 @@ static inline int vnc_display_pw_expire(DisplayState *ds, 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(void);

View File

@@ -617,8 +617,10 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add)
unsigned delta;
/* kvm works in page size chunks, but the function may be called
with sub-page size and unaligned start address. */
delta = TARGET_PAGE_ALIGN(size) - size;
with sub-page size and unaligned start address. Pad the start
address to next and truncate size to previous page boundary. */
delta = (TARGET_PAGE_SIZE - (start_addr & ~TARGET_PAGE_MASK));
delta &= ~TARGET_PAGE_MASK;
if (delta > size) {
return;
}
@@ -1681,6 +1683,11 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
cpu->kvm_vcpu_dirty = false;
}
void kvm_cpu_clean_state(CPUState *cpu)
{
cpu->kvm_vcpu_dirty = false;
}
int kvm_cpu_exec(CPUState *cpu)
{
struct kvm_run *run = cpu->kvm_run;

View File

@@ -115,6 +115,7 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,
VCardAppletPrivate *applet_private;
int size, next;
unsigned char *sign_buffer;
bool retain_sign_buffer = FALSE;
vcard_7816_status_t status;
VCardStatus ret = VCARD_FAIL;
@@ -178,6 +179,7 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,
pki_applet->sign_buffer = sign_buffer;
pki_applet->sign_buffer_len = size;
*response = vcard_make_response(VCARD7816_STATUS_SUCCESS);
retain_sign_buffer = TRUE;
break;
case 0x00:
/* we now have the whole buffer, do the operation, result will be
@@ -200,9 +202,11 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,
VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
break;
}
g_free(sign_buffer);
pki_applet->sign_buffer = NULL;
pki_applet->sign_buffer_len = 0;
if (!retain_sign_buffer) {
g_free(sign_buffer);
pki_applet->sign_buffer = NULL;
pki_applet->sign_buffer_len = 0;
}
ret = VCARD_DONE;
break;
case CAC_READ_BUFFER:

View File

@@ -597,7 +597,7 @@ connect_to_qemu(
const char *port
) {
struct addrinfo hints;
struct addrinfo *server;
struct addrinfo *server = NULL;
int ret, sock;
sock = socket(AF_INET, SOCK_STREAM, 0);
@@ -629,9 +629,14 @@ connect_to_qemu(
if (verbose) {
printf("Connected (sizeof Header=%zd)!\n", sizeof(VSCMsgHeader));
}
freeaddrinfo(server);
return sock;
cleanup_socket:
if (server) {
freeaddrinfo(server);
}
closesocket(sock);
return -1;
}

View File

@@ -5,3 +5,5 @@ obj-$(TARGET_HAS_BFLT) += flatload.o
obj-$(TARGET_I386) += vm86.o
obj-$(TARGET_ARM) += arm/nwfpe/
obj-$(TARGET_M68K) += m68k-sim.o
obj-binfmt-y = binfmt.o

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