Compare commits

...

192 Commits

Author SHA1 Message Date
Anthony Liguori
e389e937a7 Update version and changelog for release
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-01-14 08:40:19 -06:00
Anthony Liguori
73b48d914f Update SeaBIOS to 0.5.1
- 5da6833 Update version to 0.5.1
 - 669c991 Fix sign error preventing incorrect memory over 4gig calculation.
 - 7e6bd3e Minor - better indent assembler in int1587.
 - 48cf232 Add comment explaining why mptable is in low memory.
 - 643062f Add int1589 support.
 - 085debd Set FDPT in irq table even for small drives.
 - 7c1b186 Reduce #ifs by weeding out some cross-chunk function definitions.
 - f9b25d3 Fix vgahook sign issue; add warning to build to catch future cases.
 - 3862b2d vgabios: Fix compile error due to fixed prototypes.
 - 1ca05b0 Be sure to add "void" to all function prototypes that take no args.
 - b5bb9db mptable: Reset pinmask on new bus or device.
 - 8918989 Detect latest FC12 gcc -combine breakage.
 - c9d3c2d Minor vga binary cleanups.
 - 9a8609f Make MTRR region 0xc0000-0x100000 be cached.
 - fdca418 Force a link error if a function is used from the wrong code chunk.
 - dad41d9 Add __noreturn define for __attribute__((noreturn)).
 - c003148 Implement native 32bit APM support.
 - 5c99b6c Commit compiled dsdt file; misc comment updates.
 - 29f4b91 prevent acpi from rerouting SCI interrupt
 - 4c94b7e enumerate all PCI buses in mptable
 - 871e0a0 Add support for 32bit PCI BIOS entry.
 - eda2c83 Only add "addr32" to memory accesses that require them.
 - 52a300f Introduce MODESEGMENT define; rename VISIBLE32 to VISIBLE32FLAT.
 - fe2c3ee Allocate smbios in temp space and copy into final location.
 - b164d2c Clear user reserved interrupts (0x60-0x66).
 - d9104ff Remove pci_bios_bigmem_addr; set pci_bios_mem_addr=0xe0000000
 - 14021f2 Add initial support for ATA DMA.
 - 8362699 Allocate mptable in temp space and copy into final location.
 - 979862e Also report memory over 4G during init.
 - 928d4df provide correct pci routing information in mptable
 - afc02da Add symbolic definitions for MTRR code.
 - fb214dc Fix yield() so it works from boot code.
 - 2ceeec9 Fix potential build failure due to text16 section being too large.
 - a2195e4 Increase version in preparation for next release.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2010-01-14 08:40:11 -06:00
Milan Plzik
3999bf3244 Qemu's internal TFTP server breaks lock-step-iness of TFTP
According to RFC 1350 and RFC 2347, TFTP server should answer RRQ by
either OACK or DATA packet. Qemu's internal TFTP server answers RRQ with
additional options by sending both OACK and DATA packet, thus breaking
the "lock-step" feature of the protocol, and also confuses client.

  Proposed solution would be to, in case of OACK packet, wait for ACK
from client and just then start sending data. Attached patch implements
this.

Signed-off-by: Thomas Horsten <thomas@horsten.com>
Signed-off-by: Milan Plzik <milan.plzik@gmail.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 1cb1a66aed)
2010-01-13 17:22:57 -06:00
Kevin Wolf
a3441a43a6 osdep.c: Fix accept4 fallback
Commit 3a03bfa5 added a fallback in case the Linux kernel running qemu is older
than the kernel of the build system. Unfortunately, v1 was committed instead of
v2, so the code has a bug that was revealed in the review (checking for the
wrong error code).

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 347ed55cd1)
2010-01-13 17:22:33 -06:00
Gerd Hoffmann
49a3aaac4a pc: add rombar to compat properties for pc-0.10 and pc-0.11
So '-M pc-0.10' and '-M pc-0.11' will use the fw_cfg rom load method
by default.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 20a86364c9)
2010-01-12 14:48:35 -06:00
Gerd Hoffmann
027866ce23 pci: allow loading roms via fw_cfg.
This patch adds a pci bus property 'rombar' which specifies whenever
the pci rom should be loaded via pci rom bar (default) or via fw_cfg.
The later can be used for compatibility with older qemu versions where
no pci rom bar is present.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 88169ddf82)
2010-01-12 14:48:27 -06:00
Gerd Hoffmann
04babf6c6f roms: rework rom loading via fw
This patch changes the way rom loading via fw_cfg is handled.
Instead of having pc_init1() call a function which passed all
roms to the firmware config we simply pass a pointer to fw_cfg
to the rom loader.

Advantage: loading roms via firmware works also for devices which
are initialized after pc_init1(), i.e. everyting added via -device.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 8832cb805d)
2010-01-12 14:48:19 -06:00
Gerd Hoffmann
d2b8117310 fw_cfg: rom loader tweaks.
Changes:
 - make dir argument mandatory, we allways have one anyway
   (vgaroms or genroms).
 - check for duplicates, skip loading if found.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit de9352bcae)
2010-01-12 14:48:07 -06:00
Gerd Hoffmann
0c4b9aef7b roms: minor fixes and cleanups.
Changes:
  - Drop extra file argument from rom_add_file().
  - Drop fw_dir check in do_info_roms, we allways have a dir name.
  - code style fixes.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit bdb5ee3064)
2010-01-12 14:48:00 -06:00
Gerd Hoffmann
431c829f33 pc: add machine type for 0.12
Add a new machine type for qemu 0.12.

Also fixup the 0.11 machine type: msi for virtio-blk-pci was enabled
after the 0.11 release, so turn it off in the 0.11 machine type.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2cae6f5e34)
2010-01-12 14:47:53 -06:00
Aurelien Jarno
be7398ec06 loader: more ignores for rom intended to be loaded by the bios
Similarly to what has been done in e405a2ba91,
ignore rom intended to be loaded by the bios in find_rom() and rom_copy().

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit f21a59c224)
2010-01-12 14:44:50 -06:00
Stefano Stabellini
be59ce1f48 vnc_refresh: return if vd->timer is NULL
Hi all,
calling vnc_update_client in vnc_refresh might have the unlikely side
effect of setting vd->timer = NULL, if the last vnc client disconnected.
In this case we have to return from vnc_refresh without updating the
timer, otherwise we cause a segfault.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 83755c173f)
2010-01-12 13:34:48 -06:00
Luiz Capitulino
eacad66dbe QMP: Don't free async event's 'data'
The monitor_protocol_event() function will free the
event's data, this is wrong as 'data' management is up
to the caller.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 3d72f9a2be)
2010-01-12 13:33:13 -06:00
Thomas Horsten
66dbb62824 Handle TFTP ERROR from client
If a PXE client only wants to find out the size of a file, it will
open the file and then abort the transfer by sending a TFTP ERROR packet.

The ERROR packet should cause qemu to terminate the session. If not,
the sessions will soon run out and cause timeouts in the client.

Also, if a TFTP session already exists with same IP/UDP port, it
should be terminated when a new RRQ is received, instead of creating a
duplicate (which will never be used).

A patch for gPXE to send the ERROR packet is also being submitted to
gPXE. Together they resolve slowness/hanging when booting pxegrub from
qemu's internal TFTP server. The patch from Milan Plzik to return
after sending OACK is also required for a complete fix.

Signed-off-by: Thomas Horsten <thomas@horsten.com>
Signed-off-by: Milan Plzik <milan.plzik@gmail.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit bfe4e17242)
2010-01-12 13:31:51 -06:00
Christoph Hellwig
d47d251286 dmg: fix ->open failure
Currently the dmg image format driver simply opens the images as raw
if any kind of failure happens.  This is contrarty to the behaviour
of all other image formats which just return an error and let the
block core deal with it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 1559ca00bc)
2010-01-12 13:31:21 -06:00
Michael S. Tsirkin
348af56fae virtio-pci: thinko fix
Since patch ed757e140c0ada220f213036e4497315d24ca8bct, virtio will
sometimes clear all status registers on bus master disable, which loses
information such as VIRTIO_CONFIG_S_FAILED bit.  This is a result of
a patch being misapplied: code uses !  instead of ~ for bit
operations as in Yan's original patch.  This obviously does not make
sense.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 49e75cf388)
2010-01-12 13:30:08 -06:00
Stefan Weil
09866b9baa pc-bios: Update README (SeaBIOS)
The PC BIOS no longer comes from Bochs.
This patch updates the related entry.

V2 - Modify SeaBIOS description and URL
     (Thanks to Gleb Natapov for the hint).

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit c0ced0f3a7)
2010-01-12 13:29:48 -06:00
Roland Dreier
e1daf40e3e vmware_vga: Check cursor dimensions passed from guest to avoid buffer overflow
Check that the cursor dimensions passed from the guest for the
DEFINE_CURSOR command don't overflow the available space in the
cursor.image[] or cursor.mask[] arrays before copying data from the
guest into those arrays.

Signed-off-by: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f2d928d44e)
2010-01-11 10:03:39 -06:00
Gleb Natapov
de3ea06d59 remove pending exception on vcpu reset.
Without this qemu can even start on kvm modules with events support
since default value of exception_injected in zero and this is #DE
exception.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit e73223a584)
2010-01-11 10:03:30 -06:00
Jiri Denemark
fe46a160ce Fix CPU topology initialization
Late initialization of CPU topology in CPUState prevents KVM guests to
actually see the topology.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 3f7638ec40)
2010-01-11 10:03:18 -06:00
Huang Ying
8033c42abd MCE: Fix bug of IA32_MCG_STATUS after system reset
Now, if we inject a fatal MCE into guest OS, for example Linux, Linux
will go panic and then reboot. But if we inject another MCE now,
system will reset directly instead of go panic firstly, because
MCG_STATUS.MCIP is set to 1 and not cleared after reboot. This is does
not follow the behavior in real hardware.

This patch fixes this via set env->mcg_status to 0 during system reset.

Signed-off-by: Huang Ying <ying.huang@intel.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit af364b418c)
2010-01-11 10:02:55 -06:00
Avi Kivity
4713c69fa2 linuxboot: fix gdt address calculation
The gdt address calculation in linuxboot.bin is broken in two ways: first
it loads %cs into %eax, but that instruction leaves the high bits of %eax
undefined and we did not clear them.  Secondly, we completely ignore the
incorrect %eax, and use the undefined %ebx instead.

With these issues fixed, linuxboot works again.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d0652aa8ac)
2010-01-08 10:01:39 -06:00
Luiz Capitulino
d68bf60838 QMP: Drop wrong assert()
Some commands return a QList of QDicts, which is valid,
but will trig the assert().

Just drop it.

Reported-by: Nathan Baum <nathan@parenthephobia.org.uk>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 810f49b56a)
2010-01-08 10:01:26 -06:00
Anthony Liguori
57fa5ca551 vnc: Fix artifacts in hextile decoding
02c2b87 introduced a regression whereas the foreground color in a hextile
update was not being properly invalidated leading to artifacts.

It's still necessary to explicitly invalidate the foreground color with a
SubrectColoured tile even though we no longer send a foreground color as
part of the tile.

Reported-by: Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 18cb1d8557)
2010-01-07 07:59:28 -06:00
Anthony Liguori
8610774f79 Merge remote branch 'mst/stable-0.12' into stable-0.12 2010-01-06 09:17:53 -06:00
Aurelien Jarno
76ba04832b target-i386: Fix "call im" on x86_64 when executing 32-bit code
Similarly to what is done in 32938e127f
for "jmp im", trunc the immediate to 32-bit when not running in 64-bit
mode.

Reported-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2010-01-03 03:16:59 +01:00
Michael Tokarev
644f5de21b Add missing newline at the end of options list
In qemu-kvm this place looks even more "interesting":

 -runas user     Change to user id user just before starting the VM.
 -readconfig <file>
 -writeconfig <file>
                read/write config file-no-kvm         disable KVM hardware virtualization
 -no-kvm-irqchip disable KVM kernel mode PIC/IOAPIC/LAPIC
 -no-kvm-pit     disable KVM kernel mode PIT

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 19e65b47f6)
2009-12-30 13:46:40 +01:00
Avi Kivity
dcc0da8297 Don't load options roms intended to be loaded by the bios in qemu
The first such option rom will load at address 0, which isn't very nice,
and the second will report a conflict and abort, which is horrible.

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit e405a2ba91)
2009-12-24 19:35:24 +01:00
Scott Tsai
41193c50fa USB: Improve usbdevice error messages
When an non-existent USB device is specified on the command line,
print "qemu: could not add USB device 'X'".
Likewise for the usb_{add,del} monitor commands.

Signed-off-by: Scott Tsai <scottt.tw@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 59d1c1c2d7)
2009-12-23 07:42:38 +01:00
Aurelien Jarno
da0266005a cpu-all.h: fix cpu_get_real_ticks() #ifdef
Reported-by: Hervé Poussineau <hpoussin@reactos.org>

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 9706c06d9c)
2009-12-20 21:47:03 +01:00
Blue Swirl
eacdccbb3e alpha: fix compile
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2009-12-20 10:27:44 +00:00
Kirill A. Shutemov
65e8c51928 user_only: compile everything with -fpie
We really need compile _all_ sources for user target with -fpie when
use --enable-user-pie.

It's regression introduced by commit add16157d7.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
[blauwirbel@gmail.com: combined 299060a0 and 58faa1a6 to avoid breakage]
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2009-12-20 11:35:57 +02:00
Artyom Tarasenko
e470436f19 fdc/sparc32: don't hang on detection under OBP
Stepping through the SS-5's OBP initialization routines
it looks like reading fdc main status register should
clear the fd interrupt.
The patch doesn't fix problems with fdc on sparc platform,
it only fixes fdc detection.

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2009-12-20 11:35:48 +02:00
Artyom Tarasenko
b60c2c74f3 scsi-disk: Inquiry with allocation length of CDB < 36 (v4)
According to the SCSI-2 specification,
http://ldkelley.com/SCSI2/SCSI2/SCSI2/SCSI2-08.html#8.2.5 ,
"if the allocation length of the command descriptor block (CDB) is too
small to transfer all of the parameters, the additional length shall
not be adjusted to reflect the truncation."
The 36 mandatory bytes of response are written to outbuf, and then
only the length requested in CDB is transferred.

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2009-12-20 11:35:28 +02:00
Anthony Liguori
fe1b69708c Update version and changelog for 0.12.1
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-19 19:31:18 -06:00
Kevin Wolf
a1678e85db Multiboot support: Fix rom_copy
ROMs need to be loaded if they are anywhere in the requested area, not
only at the very beginning. This fixes Multiboot with ELF kernels that
have more than one program header.

Signed-off-by: Kevin Wolf <mail@kevin-wolf.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 935effc2bb)
2009-12-19 21:51:10 +01:00
Aurelien Jarno
8212d18cf5 roms: allow roms to be loaded at address 0
It was possible to load roms at address 0, but commit
632cf034b4 started to forbid that, which
broke at least ARM versatile.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit f9e69bd9cf)
2009-12-19 19:46:10 +01:00
Anthony Liguori
6c412ddf1c Update for 0.12.0 release
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-19 08:26:29 -06:00
Anthony Liguori
862ad4be53 Update to SeaBIOS 0.5.0
The only change is updating the makefile but that way we're carrying an official
release.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit eac1bb74be4d95616b8a6217e020b1b0d6918608)
2009-12-19 08:26:28 -06:00
Anthony Liguori
aac2ad563a Revert "monitor: Convert do_migrate_set_speed() to QObject"
This reverts commit 3a4921047d.

From Luiz:

  do_migrate_set_speed() accepts a suffix for the 'value' argument and this is
  not good for QMP.  We will have to add a new argument type to handle that and
  this will have to wait for 0.13.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 46ee2295678af629a2869e4e331e4e002bcc31fd)
2009-12-19 08:26:28 -06:00
Anthony Liguori
eb41f58a4e e1000: Don't muck with PCI commmand register
Otherwise, the driver does not work in Linux after the INT_DISABLE changes in
PCI.

Michael Tsirkin had a patch to do this, I'm not sure what happened to it.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 17a7a5c59c4d72dd1d5666f348b010be6b10163c)
2009-12-19 08:26:28 -06:00
Luiz Capitulino
5543b41167 monitor: do_balloon(): Use 'M' argument type
This makes do_balloon() accept megabyte values from the user
Monitor while accepting byte values for QMP.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 056001ab30b1e596b992e70f9cb2adacef9c0ad0)
2009-12-19 08:26:28 -06:00
Luiz Capitulino
31d85f6a6b monitor: Introduce 'M' argument type
This is a target long value in megabytes which should be
converted to bytes.

It will be used by handlers which accept a megabyte value
when in "user mode".

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 7cfe34fe4e3b518485c15aa9a78b4cf9cbd11a4d)
2009-12-19 08:26:28 -06:00
Luiz Capitulino
9c49a2533c QMP: Update spec file
- Remove "draft" status
- Change default success response to be json-object
- Change error and event data member to be a json-object
- Update examples
- Add new section "Compatibility Considerations"
- Other fixes and clarifications

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 58341bcd112cf11c6266cabe36921572fa4b019d)
2009-12-19 08:26:28 -06:00
Luiz Capitulino
c6faf5fd73 QMP: Update README file
- Fix output description
- Fix command-line usage notes
- Minor improvements

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d683cfb1a94aa61ace4ce7ce824f1e087b37b851)
2009-12-19 08:26:27 -06:00
Luiz Capitulino
069def25cb QMP: Assure that returned data is a QDict
This is for debug purposes only.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 19863875a2e18fc868a7b830f16fa76d32518bd1)
2009-12-19 08:26:27 -06:00
Luiz Capitulino
3733a1e804 QMP: Return an empty dict by default
Currently, when a regular command doesn't have any data to output,
QMP will emit:

{ "return": "OK" }

Returning an empty dict is better though, because dicts can support
some protocol changes in a compatible way.

So, with this commit we will return:

{ "return": {} }

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit e38fb11b5099db8de8d60d536d4a01610ee4c08b)
2009-12-19 08:26:27 -06:00
Luiz Capitulino
5b06a3f785 QMP: Only handle converted commands
Looks like I dropped this check when addressing the 'query-'
commands request.

QMP should only handle converted commands, obviously.

Reported-by: Markus Armbruster <armbru@redhat.com>

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 89f5461fc9a3c437e632f6895dc605e8f03b925e)
2009-12-19 08:26:27 -06:00
Anthony Liguori
baaf73aaac Update SeaBIOS to include PCI based option rom loading
Also remove pcbios from the tree.  It will no longer work.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2dc3f77c86)
2009-12-19 08:26:27 -06:00
Gerd Hoffmann
345c22aa80 roms: remove option rom packing logic
Now that we load the option roms via fw_cfg, we can stop copying
them to the 0xc000 -> 0xe000.  The patch does just that.

Also the rom loader gets simplified as all remaining users of the
rom loader load the bits at a fixed address so the packing and
aligning logic can go away.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 632cf034b4)
2009-12-19 08:26:26 -06:00
Gerd Hoffmann
26bb2a0865 roms: use new fw_cfg file xfer support.
roms: use fw_cfg for vgabios and option rom loading, additionally to
deploying them the traditional way (copy to 0xc0000 -> 0xe0000 range).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 379526a40e)
2009-12-19 08:26:25 -06:00
Gerd Hoffmann
e6ea832410 fw_cfg: add API for file transfer.
This patch adds a file transfer interface to fw_cfg.  Intended to be
used for passing non-pci option roms and vgabios to seabios.  Namespace
is modeled after the existing cbfs filesystem support in seabios.

Reading the new FW_CFG_FILE_DIR entry returns a file list.
Fields there are in network byte order (aka bigendian).

aliguori: fix fw_cfg.h for multiboot.bin, add proper fw_cfg.h declarations,
          quiet fprintf() in fw_cfg.c

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit abe147e0ce)
2009-12-19 08:26:25 -06:00
Gerd Hoffmann
22d0cc8d38 fw_cfg: make calls typesafe
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit c2b5bda43a)
2009-12-19 08:26:25 -06:00
Gerd Hoffmann
898829d5c7 pci romfiles: add property, add default to PCIDeviceInfo
This patch adds a romfile property to the pci bus.  It allows to specify
a romfile to load into the rom bar of the pci device.  The default value
comes from a new field in PCIDeviceInfo.  The property allows to change
the file and also to disable the rom loading using an empty string.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 8c52c8f320)
2009-12-19 08:26:24 -06:00
Anthony Liguori
72bb3c7571 Support PCI based option rom loading
Currently, we preload option roms into the option rom space in memory.  This
prevents DDIM from functioning correctly which severely limits the number
of roms we can support.

This patch introduces a pci_add_option_rom() which registers the
PCI_ROM_ADDRESS bar which points to our option rom.  It also converts over
the cirrus vga adapter, the rtl8139, virtio, and the e1000 to use this
new mechanism.

The result is that PXE boot functions even with three unique types of cards.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit c2039bd0ff)
2009-12-19 08:26:24 -06:00
Daniel P. Berrange
48c437f0ab Fix backcompat for hotplug of SCSI controllers
SCSI controllers have no trouble existing without any attached
disks. This could be achieved with the (legacy) monitor syntax

  pci_add pci_addr=auto storage if=scsi

This is now denied with

  scsi requires a backing file/device.
  failed to add if=scsi

There is no need for this denial and it breaks compatability
with existing QEMU usage, so remove the check for presence
of a drive.

  Signed-off-by: Daniel P. Berrange <berrange@redhat.com>

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit ec7efac4a9)
2009-12-19 08:26:24 -06:00
Juan Quintela
07d00c2174 fdc: fix migration from 0.11
0.11 uses as instance ide io_base, get it back

Signed-off-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 47f5ba7248)
2009-12-19 08:26:24 -06:00
Juan Quintela
3243a06f51 Revert "fdc: fix vmstate variable passed"
Floppy used the io_base address to register savevm region.

This reverts commit 2966b390d0.

Signed-off-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit aef30c3c6a)
2009-12-19 08:26:24 -06:00
Jan Kiszka
1c3f96be38 monitor: Accept input only byte-wise
This allows to suspend command interpretation and execution
synchronously, e.g. during migration.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit c62313bbdc)
2009-12-19 08:26:24 -06:00
Anthony Liguori
df9e7219db Revert "kvm: x86: Save/restore exception_index"
This reverts commit ebbc8a3d8e.

As suggested by Jan Kiszka,

  "It was obsoleted by d1793b836f8f123b961c613de1bb1c0c185c84cc and now
   saves/restores a useless field."

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit acb6685fea)
2009-12-19 08:26:24 -06:00
Dave Airlie
e83421f511 vmware: increase cursor buffer size.
The cursor pixmap size we calculate later ends up being 4096 dwords
long by the looks of it. This boots an F12 LiveCD now.

Signed-off-by: Dave Airlie <airlied@linux.ie>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 8095cb3ed2)
2009-12-19 08:26:24 -06:00
Anthony Liguori
2b311b3cce VMware VGA: Only enable dirty log tracking when fifo is disabled
This patch enables dirty log tracking whenever it's needed and disables it
when it is not.

We unconditionally enable dirty log tracking on reset, restart dirty log
tracking when PCI IO regions are remapped, and disable/enable it based on
commands from the guest.

Rebased-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit b5cc6e32ba)
2009-12-19 08:26:23 -06:00
Anthony Liguori
4b5db3749c Fix VMware VGA depth computation
VMware VGA requires that the depth presented to the guest is the same as the
DisplaySurface that it renders to.  This is because it performs a very simple
memcpy() to blit from one surface to another.

We currently hardcode a 24-bit depth.  The surface allocator for SDL may, and
usually will, allocate a surface with a different depth causing screen
corruption.

This changes the code to allocate the DisplaySurface before initializing the
device which allows the depth of the DisplaySurface to be used instead of
hardcoding something.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit a6109ff1b5)
2009-12-19 08:26:23 -06:00
Anthony Liguori
a1497a782c Make sure to enable dirty log tracking for VMware VGA
This is needed for VMware VGA to work properly under KVM.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit ee3e41a9a0)
2009-12-19 08:26:23 -06:00
Anthony Liguori
3c547d7bb7 Make sure to enable dirty tracking of VBE vram mapping
Apparently, VBE maps the VGA vram to a fixed physical location.  KVM requires
that all mappings of the VGA vram have dirty tracking enabled on them.  Any
access to the VGA vram through the VBE mapping currently fails to result in
dirty page tracking updates causing a black screen.

This is the true root cause of VMware VGA not working correctly under KVM and
likely also an issue with some of the std-vga black screen issues too.

Cirrus does not enable VBE so it would not be a problem when using Cirrus.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Rebased-by: Dave Airlie <airlied@redhat.com>
(cherry picked from commit f0138a63a4)
2009-12-19 08:26:23 -06:00
Dave Airlie
3b43502e3a vmware: setup PCI BAR 2 for FIFO as per vmware spec
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f351d050dc)
2009-12-19 08:26:23 -06:00
Gerd Hoffmann
078517421f qdev: improve property error reporting.
Add a error message in case we fail to parse a qdev property.

Also make qemu not abort() in case setting a global property can't be
set.  This used to be a clear programming error.  The introduction of
the -global switch changed that though, so better exit instead (after
printing the new error message).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 9ef5c4bf81)
2009-12-19 08:26:22 -06:00
Gerd Hoffmann
afc7055619 fix vga names in default_list
Fix mismerge between 64465297 and 556cd098.

Cc: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 69fd02eea6)
2009-12-19 08:26:22 -06:00
Gerd Hoffmann
53425683d4 usb-host: check mon before using it.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit eba6fe8732)
2009-12-19 08:26:22 -06:00
Gerd Hoffmann
ef5a63186a usb-net: use qdev for -usbdevice
Rebased to master, adapted to device renaming by armbru,
no other changes.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 42be86ce95)
2009-12-19 08:26:22 -06:00
Gerd Hoffmann
4a0e0accd7 Check rom_load_all() return value.
Check rom_load_all() return value.
Also don't make option rom loading failure fatal.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 15ff770544)
2009-12-19 08:26:22 -06:00
Gerd Hoffmann
73e47683de defaults: update device_list[]
Add isa-fdc (disables default_floppy).
Add ide-drive (disables default_cdrom).

Also walk the -global QemuOpts, so we'll catch
-global isa-fdc.drive{A,B}=<name> too.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d8bcbabf26)
2009-12-19 08:26:21 -06:00
Gerd Hoffmann
115e94a31e defaults: split default_drive
Split default_drive into default_{floppy,cdrom,sdcard}.
Also add QEMUMachine flags to disable them per machine.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit ac33f8fad1)
2009-12-19 08:26:21 -06:00
Luiz Capitulino
5fd5f6999d monitor: Catch printing to non-existent monitor
The monitor_vprintf() function now touches the 'mon' pointer
before calling monitor_puts(), this causes block migration
to segfault as its functions call monitor_printf() with a
NULL 'mon'.

To fix the problem this commit moves the 'mon' NULL check
from monitor_puts() to monitor_vprintf().

This can potentially hide bugs, but for some reason this has
been the behavior for a long time.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2daa119126)
2009-12-19 08:26:21 -06:00
Luiz Capitulino
602e97b725 monitor: Avoid readline functions in QMP
The monitor_read_command() function is readline specific
and should only be used when readline is available.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 183e6e5257)
2009-12-19 08:26:21 -06:00
Luiz Capitulino
97b766dfcd monitor: do_balloon(): Check for errors
do_balloon() should check for ballooning availability as
do_info_balloon() does.

Noted by Daniel P. Berrange <berrange@redhat.com>.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit cfdf2c4057)
2009-12-19 08:26:21 -06:00
Luiz Capitulino
fb8cf78db6 monitor: Use 'device' in eject
Monitor's eject command uses 'filename' for the device name
argument, but 'device' is a better name.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 78d714e08f)
2009-12-19 08:26:21 -06:00
Luiz Capitulino
c5238ac21b QDict: Fix size update
Key replacement should not update the dictionary's size.

This commit also adds a test for the bug.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 29ec3156ee)
2009-12-19 08:26:21 -06:00
Markus Armbruster
99917a99cd qdev: Improve uni-north device names
Switch to the names suggested by Blue Swirl.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 18dd19a7d9)
2009-12-19 08:26:21 -06:00
Daniel P. Berrange
55ed56908f Avoid permanently disabled QEMU monitor when UNIX migration fails
If a UNIX migration command is attempt to a UNIX socket which does
not exist, then the monitor is suspended, but never resumed. This
prevents any further use of the monitor

* migration-unix.c: Only call migrate_fd_monitor_suspend() once
  connected to the UNIX socket.

   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2dd650e58a)
2009-12-19 08:26:20 -06:00
Kevin Wolf
139e310025 Fix loading of ELF multiboot kernels
The multiboot implementation assumed that there is only one program header
(which contains the entry point) and that the entry point is at the start of
the code. This doesn't hold true generally and caused too little data to be
loaded.

Fix the loading code to pass the whole loaded data to the Multiboot Option ROM.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 092493be3c)
2009-12-19 08:26:20 -06:00
Kevin Wolf
bed93b1dcb Revert "Rename DriveInfo.onerror to on_write_error" (fix mismerge)
Part of the first patch of the -drive rerror series has been merged once more
on top of the rest of the series. This effectively disables the rerror option
and always goes with the default value. Reverting the commit re-enables the
option.

This reverts commit fc072ec4df.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 75f1247539)
2009-12-19 08:26:20 -06:00
Kevin Wolf
73b4ac5cd8 qemu-io: Fix memory leak
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 40a0d7c395)
2009-12-19 08:26:20 -06:00
Paolo Bonzini
00e8277b83 Fix thinko in linuxboot.S
The %gs segment that was used was not matching the comments.
I just moved the GDT descriptor on the stack instead.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 36ecd7c016)
2009-12-19 08:26:20 -06:00
Jan Kiszka
a8ea3a357b target-i386: Fix evaluation of DR7 register
hw_breakpoint_type and hw_breakpoint_len used the wrong index multiplier
to extract type and len.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d46272c774)
2009-12-19 08:26:20 -06:00
Jan Kiszka
f8051485c1 kvm: x86: Use separate exception_injected CPUState field
Marcelo correctly remarked that there are usage conflicts between QEMU
core code and KVM /wrt exception_index. So spend a separate field and
also save/restore it properly.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 31827373f0)
2009-12-19 08:26:20 -06:00
Anthony Liguori
807c80b259 vnc: hextile: do not generate ForegroundSpecified and SubrectsColoured tiles
This violates the RFB specification (section 6.6.4).  It happens to work with
most clients but it's still wrong.

Reported-by: Yaniv Kaul <ykaul@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 02c2b87fff)
2009-12-19 08:26:20 -06:00
Anthony Liguori
686a3c3dc2 Revert "pci: interrupt disable bit support"
This reverts commit 0ea5709a32.

Per discussion with Michael Tsirkin, this is too risky for 0.12

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d587e07871)
2009-12-19 08:26:19 -06:00
Alexander Graf
a381d8277c target-ppc: fix ppc32 kvm build
My segment sync patch broke compilation on PPC32, because it was trying to
sync the SLB even though ppc32 CPUs don't have an SLB.

So let's only sync it when we're on a PP64 one!

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 82c09f2f0d)
2009-12-19 09:30:40 +01:00
Alexander Graf
8647b09bfd S390: Bail out without KVM
Currently only the S390 KVM target works. To keep users from accidently not
using KVM, let's not even initialize the machine when KVM is not used.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit e249651ca9)
2009-12-18 16:39:40 +01:00
Alexander Graf
9153014fa0 S390: Don't tell guest we're updating config space
Currently we always set the "config space changed" bit to 1 when triggering
any virtio interrupt. While that worked in 2.6.27, newer kernels interpret
that value as "only the config space changed and nothing else happened".

Since we usually trigger interrupts to tell the guest that something did
happen, we just not tell it the config space changed for now until we
implement the correct callback for that.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 86f3dba651)
2009-12-18 16:36:39 +01:00
Alexander Graf
f6d4446ea8 add default virtcon initialization
When going through the default devices, we don't initialize the virtio
console, unless we're doing -nographic.

I suppose that's just a leftover from the recent code restructuring, so
let's put it in.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 38536da1e3)
2009-12-18 16:36:39 +01:00
Alexander Graf
f1e247ee6b S390: Loop through virtio console devices
We used to always create one single virtio console device. This breaks when
either zero of multiple virtio console devices are requested, so let's use
the same code as on x86.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit a1e4b07f04)
2009-12-18 16:36:38 +01:00
Alexander Graf
a49668769d target-s390: Fail on unknown instructions
We were being a bit too nice and didn't give the guest an invalid instruction
interrupt.

While that works, it's not exactly the fastest thing to do, since now the
guest doesn't know that we're not really implementing that instruction, so it
continues doing it.

We run into this with the set_page_unstable hint instruction. So let's bail out
in these cases.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit d7963c43b9)
2009-12-18 16:36:37 +01:00
Andre Przywara
97d949d9da osdep: Fix runtime failure on older Linux kernels
If QEMU finds newer kernel header files on compilation time, it will use
advertised features like pipe2 or SOCK_CLOEXEC by just doing a compile test.
If later the executables are executed on an older kernel (<2.6.27,
like Xen Dom0 2.6.18), then QEMU will fail on opening sockets and creating
pipes and returns the rather unspecific "qemu_init_main_loop failed".
This patch fixes this by checking the return values of these calls
for EINVAL and ENOSYS and falling back to the older versions automatically.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2009-12-18 16:30:45 +01:00
Juergen Lock
040093b1a5 Fix a make -j race
Make libuser.a depend on $(GENERATED_HEADERS) too so make -j won't start
building it before the headers exist.  (There may be more bugs like this
but at least this makes (g)make -j4 started from scratch on a quadcore
now always complete here again.)

Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit c1bb0dcef2)
2009-12-17 18:27:27 +01:00
Richard Henderson
5d4e53dc81 target-alpha: Fix generic ctz64.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 06445248d2)
2009-12-17 18:24:59 +01:00
Stefan Weil
3ebee80226 s390: Fix buggy assignment
nd->model keeps dynamically allocated model names.
So casting of a constant string is wrong here.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 5a2b3fc5aa)
2009-12-16 18:25:30 +01:00
Michael S. Tsirkin
c56651312b e1000: fix init values for command register
Command register for e1000 was initialized to
values out of spec: all of bus master,
io, memory and interrupt disable bits were set.

This breaks the device now that we actually respect
the interrupt disable bit, unless the guest
happens to clear it. Fix, and make the device
more spec compliant, by not touching
the default.

There are implications for migration
from old qemu as well, will be addressed
separately.

Reported-by: Luiz Capitulino <lcapitulino@redhat.com>
Tested-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2009-12-15 13:55:20 +02:00
Nathan Froyd
869ca150e7 target-mips: fix user-mode emulation startup
Running programs with the MIPS user-mode emulator fails during dynamic
loading, as floating-point instructions are not enabled in in
env->hflags.  Move the code for doing so from fpu_init to cpu_reset so
the MIPS_HFLAG_{FPU,F64} setting doesn't get clobbered by cpu_reset
setting env->hflags to MIPS_HFLAG_UM.

The same end can be achieved by swapping the ordering of fpu_init and
cpu_reset in cpu_mips_init, but it seemed better to consolidate the
CONFIG_USER_ONLY code into a single location.

Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 91a7593526)
2009-12-13 21:05:16 +01:00
Andre Przywara
910628f396 target-i386: Update CPUID feature set for TCG
The CPUID features QEMU presented to the guest were not up-to-date
with QEMU's emulated feature set.
Add the missing bits of recent (and not so recent) additions to
QEMU's emulation engine.
For stability reasons only the user mode usable bits are exposed for
now, features like Monitor or CR8LEG are left out.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit f1e00a9cf3)
2009-12-13 20:56:26 +01:00
Michael S. Tsirkin
251241dc90 s390: typo fix
s390 code has an obvious typo, which results in:
hw/s390-virtio.c: At top level:
hw/s390-virtio.c:249: error: request for member ‘no_vga’ in something not a structure or union

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2009-12-13 19:47:12 +01:00
Michael S. Tsirkin
03a23e5c6e s390: fix build on 32 bit host
Building on 32 bit host we get:
hw/s390-virtio.c: In function ‘s390_init’:
hw/s390-virtio.c:184: error: integer constant is too large for ‘unsigned long’ type
64 bit values must be ULL.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2009-12-13 19:47:09 +01:00
Anthony Liguori
a68fc29ceb Update Changelog and VERSION for 0.12.0-rc2
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-12 08:29:25 -06:00
Glauber Costa
0014803d23 v2: properly save kvm system time msr registers
Currently, the msrs involved in setting up pvclock are not saved over
migration and/or save/restore. This patch puts their value in special
fields in our CPUState, and deal with them using vmstate.

kvm also has to account for it, by including them in the msr list
for the ioctls.

This is a backport from qemu-kvm.git

[v2: sucessfully build without kerneldir ]

Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 1a03675db1)
2009-12-12 08:17:33 -06:00
Luiz Capitulino
5118f7b47c VNC: Convert do_info_vnc() to QObject
Return a QDict with server information. Connected clients are returned
as a QList of QDicts.

The new functions (vnc_qdict_remote_addr(), vnc_qdict_local_addr() and
put_addr_qdict()) are used to insert 'host' and 'service' information
in the returned QDict.

This patch is big, but I don't see how to split it.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d96fd29cca)
2009-12-12 08:17:33 -06:00
Luiz Capitulino
1c1d7bda2c PCI: Convert pci_device_hot_add() to QObject
Return a QDict with information about the just added device.

This commit should not change user output.

Please, note that this patch does not do error handling
conversion. In error conditions the handler still calls
monitor_printf().

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 7a344f7ac7)
2009-12-12 08:17:32 -06:00
Luiz Capitulino
bdae662c94 char: Convert qemu_chr_info() to QObject
Each device is represented by a QDict. The returned QObject is a QList
of all devices.

This commit should not change user output.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 588b383201)
2009-12-12 08:17:32 -06:00
Luiz Capitulino
0108d4e323 block: Convert bdrv_info_stats() to QObject
Each device statistic information is stored in a QDict and
the returned QObject is a QList of all devices.

This commit should not change user output.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 218a536a7a)
2009-12-12 08:17:32 -06:00
Luiz Capitulino
4305793bad block: Convert bdrv_info() to QObject
Each block device information is stored in a QDict and the
returned QObject is a QList of all devices.

This commit should not change user output.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d15e546567)
2009-12-12 08:17:32 -06:00
Luiz Capitulino
d2d51eeff0 migration: Convert do_info_migrate() to QObject
Return a QDict, which may contain up to more two QDicts, depending
on the type of migration we're performing.

IMPORTANT: as a QInt stores a int64_t integer, RAM values are going
to be stored as int64_t and not as uint64_t as they are today. If
this is a problem QInt will have to be changed.

This commit should not change user output.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit c86a668390)
2009-12-12 08:17:32 -06:00
Luiz Capitulino
3be42b28c1 monitor: Convert do_info_mice() to QObject
Each mouse is represented by a QDict, the returned QObject is a QList of
all mice.

This commit should not change user output.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit e78c48ec4e)
2009-12-12 08:17:32 -06:00
Luiz Capitulino
ee70ef8771 monitor: Convert do_info_uuid() to QObject
snprintf() is used because the UUID_FMT is too complex for
qobject_from_jsonf().

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 9603ceba2e)
2009-12-12 08:17:31 -06:00
Luiz Capitulino
5f9fe0f8d0 monitor: Convert do_info_hpet() to QObject
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 14f0720df9)
2009-12-12 08:17:31 -06:00
Luiz Capitulino
7589acc9e8 monitor: Convert do_info_name() to QObject
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit e05486cba6)
2009-12-12 08:17:31 -06:00
Luiz Capitulino
94f539bdac monitor: Convert do_info_kvm() to QObject
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2af5ba712b)
2009-12-12 08:17:31 -06:00
Luiz Capitulino
e637fd2386 monitor: Convert do_info_status() to QObject
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit c0e8520ed5)
2009-12-12 08:17:31 -06:00
Luiz Capitulino
6e785bee32 monitor: do_info_version(): Use QDict
All 'info' commands should use QDict, this commit also kills
monitor_print_qobject() as do_info_version() doesn't use it
anymore (and no handler will).

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 45e914cfe0)
2009-12-12 08:17:31 -06:00
Luiz Capitulino
f883e4f7b8 monitor: do_info_cpus(): Use QBool
While there update the documentation as well.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 55483ad657)
2009-12-12 08:17:31 -06:00
Luiz Capitulino
5daa7bb7a4 monitor: Fix do_info_commands() output
Should return a QDict and should not print the user protocol bits
(eg. "c|cont").

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 1a728677d4)
2009-12-12 08:17:31 -06:00
Luiz Capitulino
b0a84d0525 monitor: Fix do_info_balloon() output
Monitor commands should always return values in bytes and info
commands should always return a QDict.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 7f1796713e)
2009-12-12 08:17:31 -06:00
Luiz Capitulino
f1f84ba223 QDict: Introduce qdict_get_qlist()
A helper function to get a QList from a QDict.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f2e1750803)
2009-12-12 08:17:31 -06:00
Luiz Capitulino
db830f26cb QDict: Introduce qdict_get_qbool()
This is a helper function that does type checking before retrieving
a QBool from the dictionary.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit cd4dde36ae)
2009-12-12 08:17:31 -06:00
Luiz Capitulino
61a606dade Makefile: move QObject objs to their own entry
Other subsystems will need to link against them.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2a01000f7d)
2009-12-12 08:17:31 -06:00
Luiz Capitulino
2d95575edb Introduce qemu-objects.h header file
An easy way to include all QEMU objects.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2471dd00ef)
2009-12-12 08:17:31 -06:00
Gerd Hoffmann
d707483ce3 vnc: fix capslock tracking logic.
The capslock tracking logic added by commit
6b1325029d doesn't work correctly for vnc
clients without EXT_KEY_EVENT support.  The reason is that qemu converts
keysyms for letters to lowercase for the keysym2scancode lookup.  It
then also passes the lowercase value down to do_key_event(), but the
capslock tracking code needs it with the correct case to work properly.

This patch adds a new variable for the lowercase keysym so we'll keep
the unmodified value for do_key_event().

The keysym2scancode is not needed with EXT_KEY_EVENT capable clients
like any app based on the gtk-vnc widget, so I missed that case in
testing ...

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 4a93fe1708)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
e2deb622c2 QemuOpts: allow larger option values.
Use case: loooooooooooooooooong file names for -drive file=...

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d318ff9900)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
6e792a557e scsi: fix drive hotplug.
This patch fills the DriveInfo->unit after hotplugging a scsi disk.
It makes a difference when auto-assigning a scsi id, where unit was
left filled with '-1' instead of the actual scsi id.

With this patch applied the the drive naming logic in drive_init() works
as good as it did in previous releases.  Which means it works fine with
a single scsi bus.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 11f4d7f483)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
ea2138cf90 pci: don't hw_error() when no slot is available.
Current PCI code will simply hw_error() and thus abort in case no free
PCI slot is available or the requested PCI slot is already in use by
another device.  For the hotplug case this behavior is not acceptable.
This patch makes qemu pass up the error properly, so the calling code
can decide whenever it wants to exit with an error (on startup) or
whenever it wants to continue (hotplug).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 09e3acc6cf)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
992f3cb78e pci: don't abort() when trying to hotplug with acpi off.
The PCI bus on x86 requires ACPI for hotplug support, thus disbling ACPI
also disables hotplug for the PCI bus.  This patch makes qemu check
whenever the PCI bus in question can handle hotplug before trying to add
devices.  This is needed because qdev will abort() on any attempt to
hotplug devices into a non-hotpluggable bus.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 53e0d8affe)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
828b2ff676 Set default console to virtio on S390x
All "normal" system emulation targets in qemu I'm aware of display
output on either VGA or serial output.

Our S390x virtio machine doesn't have such kind of legacy hardware. So
instead we need to default to a virtio console.

Add flags to QEMUMachine to indicate which kind of default devices make
sense for the machine in question.  Use it for S390x: enable virtcon,
disable serial, parallel and vga.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 986c5f7854)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
a231a8272c default devices: virtio consoles.
This patch adds a variable default_virtcon which says whenever a default
virtio console should be added.  It is disabled by default, followup
patch will enable it for s390.  It is cleared when qemu finds
'-virtiocon', '-device virtio-console-s390' or '-device
virtio-console-pci' on the command line.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit aee1b935c5)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
f2604b35dc add -qmp convinience switch
Acts like -monitor but switched into qmp mode.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 6ca5582d4f)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
fc05630f1f add new -mon switch
Add -mon switch which maps pretty straight forward into the QemuOpts
internal representation:

  -mon chardev=<name>[,mode=[control|readline]][,[no]default]

Via config file:

[mon]
   chardev = "<name>"
   mode = "readline"
   default = "on"

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 22a0e04b9b)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
ad960ddbce rework -monitor handling, switch to QemuOpts
This patch reworks the -monitor handling:

 - It adds a new "mon" QemuOpts list for the monitor(s).
 - It adds a monitor_parse() function to parse the -monitor switch.
 - It adds a mon_init function to initialize the monitor(s) from the
   "mon" QemuOpts list.
 - It winds up everything and removes the old bits.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 8858934370)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
239a69680c un-static qemu_chr_parse_compat()
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 33521634bf)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
f4f1df70f2 default devices: drives
Add a default_drive variable which specified whenever the default drives
(cdrom, floppy, sd) should be created.  It is cleared when the new
-nodefaults switch is specified on the command line.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit aa40fc9c96)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
782e9e6554 default devices: network
Add a default_net variable which specified whenever a default network
should be created.  It is cleared in case any -net option is specified
and it is also added to the new -nodefaults switch.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit cb4522ccf6)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
64de0113f1 default devices: add global cmd line option.
Add global command line option to disable default devices.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d8c208dd8a)
2009-12-12 08:17:30 -06:00
Gerd Hoffmann
84db615abc default devices: vga adapter.
Qemu creates a vga display for you in case you didn't specify one on the
command line.  Right now this is tied to the '-vga <type>' command line
switch, which in turn causes trouble if you are creating your gfx card
using '-device VGA,<props>'.

This patch adds a variable default_vga which says whenever a default
serial line should be added.  It is enabled by default.  It is cleared
when qemu finds '-vga' or '-device {VGA,Cirrus VGA,QEMUware SVGA}' on
the command line.

'-device VGA' still doesn't work though due to a initialization order
issue (vga must init before calling i440fx_init_memory_mappings).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 64465297cd)
2009-12-12 08:17:29 -06:00
Gerd Hoffmann
7c6a56cc63 zap serial_monitor_mux
The logic in this code obviously predates the multiple monitor
capability of qemu and looks increasingly silly these days.

I think the intention of this piece of code is to get a reasonable
default for the -nographic case: have monitor and serial line muxed
on stdio.

With the new default_serial and default_monitor variables we have now
doing just that became much easier ;)

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit e1c09175bc)
2009-12-12 08:17:29 -06:00
Gerd Hoffmann
a20600b917 default devices: qemu monitor.
This patch makes the monitor default device configuration work like the
default serial and parallel port devices.  It adds a variable
default_monitor which says whenever a default monitor should be added.
It is enabled by default.  It is cleared when qemu finds '-monitor' on
the command line.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit abdeed06b4)
2009-12-12 08:17:29 -06:00
Gerd Hoffmann
4986fd4111 default devices: parallel port.
Qemu creates a default parallel port for you in case you didn't specify
one on the command line.  Right now this is tied to the '-parallel
<chardev>' command line switch, which in turn causes trouble if you are
creating your parallel port via '-device isa-parallel,<props>'.

This patch adds a variable default_parallel which says whenever a default
parallel port should be added.  It is enabled by default.  It is cleared
when qemu finds '-parallel' or '-device isa-parallel' on the command line.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 6a5e8b0e31)
2009-12-12 08:17:29 -06:00
Gerd Hoffmann
96639424e2 default devices: core code & serial lines.
Qemu creates a default serial line for you in case you didn't specify
one on the command line.  Right now this is tied to the '-serial
<chardev>' command line switch, which in turn causes trouble if you are
creating your serial line via '-device isa-serial,<props>'.

This patch adds a variable default_serial which says whenever a default
serial line should be added.  It is enabled by default.  It is cleared
when qemu finds '-serial' or '-device isa-serial' on the command line.

Part of the patch is some infrastructure for the '-device $driver'
checking (default_driver_check function) which will also be used by the
other patches of this series.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 998bbd74b9)
2009-12-12 08:17:29 -06:00
Gerd Hoffmann
6ac733bf09 vc: colorize chardev title line with blue background.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 735ba58849)
2009-12-12 08:17:29 -06:00
Gerd Hoffmann
25d82d3311 chardev: move greeting into vc backend.
Make the 'vc' chardev backend print a title line with the chardev name
after initialization, using CharDriverState->label.

This replaces the banner printing code in vl.c.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 51bfa4d316)
2009-12-12 08:17:29 -06:00
Gerd Hoffmann
f9800fe5a0 Revert "Set default console to virtio on S390x"
This reverts commit 93d434b4ae.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 014100bb73)
2009-12-12 08:17:29 -06:00
Gerd Hoffmann
542d991b4c Revert "monitor: Command-line flag to enable control mode"
This reverts commit adcb181afe.

Conflicts:

	monitor.h

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 4e307fc883)
2009-12-12 08:17:29 -06:00
Gerd Hoffmann
d1d6963eba chardev: make chardevs specified in config file work.
The patch decuples the -chardev switch and the actual chardev
initialization.  Without this patch qemu ignores chardev entries
coming via -readconfig.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 1a688d3bbc)
2009-12-12 08:17:29 -06:00
Gerd Hoffmann
7058b807cd qdev: also match bus name for global properties
i.e. -global PCI.<property>=<value> will set a default property for all
PCI devices.  Also works for the compat properties used by machine
types.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 07a8de3566)
2009-12-12 08:17:29 -06:00
Gerd Hoffmann
f49d2561cb qdev: add command line option to set global defaults for properties.
This patch adds infrastructure and command line option for setting
global defaults for device properties, i.e. you can for example use

  -global virtio-blk-pci.vectors=0

to turn off msi by default for all virtio block devices.  The config
file syntax is:

[global]
  driver = "virtio-blk-pci"
  property = "vectors"
  value = "0"

This can also be used to set properties for devices which are not
created via -device but implicitly via machine init, i.e.

  -global isa-fdc,driveA=<name>

This patch uses the mechanism which configures properties for the
compatibility machine types (pc-0.10 & friends).  The command line
takes precedence over the machine type values.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit d0fef6fbea)
2009-12-12 08:17:29 -06:00
Gerd Hoffmann
a63e5f1971 qdev: make compat stuff more generic
This patch renames the compat properties into global properties and
makes them more generic.  The compatibility stuff is only one of
multiple possible users now.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 458fb6792d)
2009-12-12 08:17:29 -06:00
Jan Kiszka
ebbc8a3d8e kvm: x86: Save/restore exception_index
As KVM now makes use of exception_index to keep pending exceptions, we
have to save&restore this field as well.

NOTE: We have to nail the arch-independent exception_index down to a
certain bit width for proper vmstate processing, namely to 32 bit.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 4d6e3ac5d4)
2009-12-12 08:17:28 -06:00
Markus Armbruster
08b2d3ba9a Fix recently added QERR_ definitions
Commits c7c338c4, 41471a23, 7a046f5f and a488be27 used
lower_case_with_underscores for class values.  Existing usage
CamelCase.  ChangeToThatForConsistency.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit bd9d30640c)
2009-12-12 08:17:28 -06:00
Markus Armbruster
72fbd9f97c qdev: Replace device names containing whitespace
Device names with whitespace require quoting in the shell and in the
monitor.  Some of the offenders are also overly long.  Some have a
more convenient alias, some don't.

The place for verbose device names is DeviceInfo member desc.  The
name should be short & sweet.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 556cd09885)
2009-12-12 08:17:28 -06:00
Markus Armbruster
5b6d0419d9 qdev: Separate USB product description from qdev name
Using the qdev name for the product description makes for inconvenient
qdev names.

Put the product description in new USBDeviceInfo member product_desc.
Make usb_qdev_init() use it.  No user or guest visible change, since
the value is still the same.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 063846984c)
2009-12-12 08:17:28 -06:00
Markus Armbruster
9df9eeeb18 qdev: Rename USBDevice member devname to product_desc
It's not a device name, it's the USB product description string.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 0fe6d12e0b)
2009-12-12 08:17:28 -06:00
Gleb Natapov
5b6321a237 fix rtc-td-hack on host without high-res timers
On hosts without high-res timers it is impossible to inject rtc interrupt
faster then 1kHz. Windows sometimes configures RTC to generate 1kHz
interrupts, so we can't inject missed interrupts when running on such
hosts. Always injecting an interrupt on REG_C read is also not an option
since Windows wait for REG_C to become zero with interrupt disabled
during boot. This patch uses mixed approach: accelerate timer + inject
up to 1000 interrupts on REG_C read.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit ba32edab7f)
2009-12-12 08:17:28 -06:00
Michael S. Tsirkin
5e0c455842 virtio: verify features on load
migrating between hosts which have different features
might break silently, if the migration destination
does not support some features supported by source.

Prevent this from happening by comparing acked feature
bits with the mask supported by the device.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 6d74ca5aa8)
2009-12-12 08:17:28 -06:00
Dave Airlie
4d687b13cf vmware_vga: add rom file so that it boots.
This just adds the rom file to the vmware SVGA chipset so it boots.

Signed-off-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit b3c3f123f7)
2009-12-12 08:17:28 -06:00
Anthony Liguori
d7b8193716 Do not abort on qemu_malloc(0) in production builds
qemu_malloc() does not allow size=0 to be passed in and aborts on this behavior.

Unfortunately, there is good reason to believe that within qemu, there are a
number of, so far, undetected places that assume size=0 can be safely passed.
Since we do not want to abort unnecessarily in production builds, return
qemu_malloc(1) whenever the version file indicates that this is a production
build.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 20ff6c8066)
2009-12-12 08:17:26 -06:00
Paul Brook
2e51813417 Fix ARM userspace strex implementation.
Signed-off-by: Paul Brook <paul@codesourcery.com>
2009-12-11 15:49:14 +00:00
Michael S. Tsirkin
90f445e1c9 qemu: delete rule target on error
Instruct make to remove any rule target on error. This prevetns
situation where there was an error during build but generated file still
stays behind.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 7dbbbb0c9e)
2009-12-07 16:36:50 -06:00
Markus Armbruster
143d288cba QMP: add human-readable description to error response
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 77e595e7c6)
2009-12-07 16:36:50 -06:00
Markus Armbruster
13a2ccc46f monitor: convert do_getfd() to QError
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 7cdfcfe18f)
2009-12-07 16:36:50 -06:00
Markus Armbruster
ea2b7d7079 QError: New QERR_TOO_MANY_FILES
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit a488be27e5)
2009-12-07 16:36:50 -06:00
Markus Armbruster
0b52786ce1 New QERR_INVALID_PARAMETER
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 7a046f5f14)
2009-12-07 16:36:50 -06:00
Markus Armbruster
e36469149a QError: New QERR_FD_NOT_SUPPLIED
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 41471a2338)
2009-12-07 16:36:50 -06:00
Markus Armbruster
e5fc266be5 monitor: convert do_closefd() to QError
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 063c1a0918)
2009-12-07 16:36:50 -06:00
Markus Armbruster
3e4cd634cc QError: New QERR_FD_NOT_FOUND
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit c7c338c497)
2009-12-07 16:36:50 -06:00
Markus Armbruster
06976f82e7 monitor: convert do_change() to QObject, QError
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit ec3b82afaa)
2009-12-07 16:36:50 -06:00
Markus Armbruster
fe7c6c90a8 QError: New QERR_VNC_SERVER_FAILED
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit a6906e31a8)
2009-12-07 16:36:50 -06:00
Markus Armbruster
960a4b537a QError: New QERR_SET_PASSWD_FAILED
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 7a84cb23c0)
2009-12-07 16:36:49 -06:00
Markus Armbruster
c756b1e762 QError: New QERR_INVALID_BLOCK_FORMAT
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 17901e7532)
2009-12-07 16:36:49 -06:00
Markus Armbruster
06921ec84f monitor: convert do_eject() to QError
Also affects do_change(), because the two share eject_device().

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2c2a6bb860)
2009-12-07 16:36:49 -06:00
Markus Armbruster
8cb1cec656 QError: New QERR_DEVICE_NOT_REMOVABLE
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 5cfe026475)
2009-12-07 16:36:49 -06:00
Markus Armbruster
a46657d185 QError: New QERR_DEVICE_LOCKED
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit b086838090)
2009-12-07 16:36:49 -06:00
Markus Armbruster
28acf422cb QError: Put error definitions in alphabetical order
Also fix the odd typoe and clean up whitespace.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit e16a181222)
2009-12-07 16:36:49 -06:00
Markus Armbruster
a7d5da8857 monitor: Fix double-prompt after "change vnc passwd BLA"
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 2895e075c6)
2009-12-07 16:36:49 -06:00
Luiz Capitulino
931a548be3 monitor: do_cont(): Don't ask for passwords
The do_cont() function will ask the user to enter a password if a
device is encrypted.

This is invalid under QMP, so we raise a QERR_DEVICE_ENCRYPTED
error.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 94171e119c)
2009-12-07 16:36:49 -06:00
Luiz Capitulino
bcddbd0f6a QError: new class for device encrypted errors
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 0df37c411c)
2009-12-07 16:36:49 -06:00
Luiz Capitulino
b3dfdb5a3b monitor: Introduce 'block_passwd' command
When using encrypted disk images, QEMU will prompt the user
for passwords when started.

This makes sense for the user protocol, but doesn't for QMP.

The solution is to have Monitor command which allows the user
or a Client to set passwords in advance, so that we avoid
the prompt completely.

This is what block_passwd does, for example:

(QEMU) block_passwd ide0-hd0 foobar

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit a3a55a2edb)
2009-12-07 16:36:49 -06:00
Luiz Capitulino
6ccc51fd20 QError: Add class for invalid passwords
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit f6d855c50d)
2009-12-07 16:36:49 -06:00
Michael S. Tsirkin
0ea5709a32 pci: interrupt disable bit support
Interrupt disable bit is mandatory in PCI spec.
Implement it to make devices spec compliant.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Isaku Yamahata <yamahata@valinux.co.jp>
(cherry picked from commit b6981cb57b)
2009-12-07 16:36:49 -06:00
Michael S. Tsirkin
67a2698dac pci: interrupt status bit implementation
interrupt status is a mandatory feature in PCI spec,
so devices must implement it to be spec compliant.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Isaku Yamahata <yamahata@valinux.co.jp>
(cherry picked from commit f9bf77dd1f)
2009-12-07 16:36:48 -06:00
Michael S. Tsirkin
eea4acfa5c pci: prepare irq code for interrupt state
This rearranges code in preparation for interrupt state
implementation.
Changes:
	- split up bus walk away from interrupt handling
          into a subroutine
	- change irq_state from an array to bitmask
	- verify that irq_state values are 0 or 1 on load

There are no functional changes.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Isaku Yamahata <yamahata@valinux.co.jp>
(cherry picked from commit d036bb215e)
2009-12-07 16:36:48 -06:00
Michael S. Tsirkin
c99d32efe6 msix: function mask support
Function mask is a mandatory feature in MSIX
spec so not implementing it is a spec violation.
Implement.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 5b5cb08683)
2009-12-07 16:36:48 -06:00
Michael S. Tsirkin
9fa7591beb msix: macro rename for function mask support
rename ENABLE_OFFSET -> CONTROL_OFFSET, since
same byte includes function mask.
This is in preparation for function mask support.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 2760952ba9)
2009-12-07 16:36:48 -06:00
Andre Przywara
066263f377 cpuid: Fix multicore setup on Intel
The multicore CPUID code detects whether the guest is an Intel or an
AMD CPU, because the Linux kernel is picky about the CmpLegacy bit.
KVM by default passes through the host's vendor, which was not
catched by the code. So fork out the vendor determining bits into a
separate function to be used from both places and always get the real
vendor.
This fixes KVM's multicore setup on Intel CPUs.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Reported-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 6d9fef1a02)
2009-12-07 16:36:48 -06:00
Jan Kiszka
20c1a35211 kvm: x86: Fix initial kvm_has_msr_star
KVM_GET_MSR_INDEX_LIST returns -E2BIG when the provided space is too
small for all MSRs. But this is precisely the error we trigger with the
initial request in order to obtain that size. Do not fail in that case.

This caused a subtle corruption of the guest state as MSR_STAR was not
properly saved/restored. The corruption became visible with latest kvm
optimizing the MSR updates.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit 6fb6d24554)
2009-12-07 16:36:46 -06:00
Aurelien Jarno
ea6112b165 Update OpenBIOS images to r640
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2009-12-06 13:00:22 +01:00
Anthony Liguori
e222100afe Update version to -rc1
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2009-12-05 11:22:19 -06:00
110 changed files with 2837 additions and 1056 deletions

108
Changelog
View File

@@ -1,3 +1,111 @@
version 0.12.2:
- Qemu's internal TFTP server breaks lock-step-iness of TFTP (Milan Plzik)
- osdep.c: Fix accept4 fallback (Kevin Wolf)
- pc: add rombar to compat properties for pc-0.10 and pc-0.11 (Gerd Hoffmann)
- pci: allow loading roms via fw_cfg. (Gerd Hoffmann)
- roms: rework rom loading via fw (Gerd Hoffmann)
- fw_cfg: rom loader tweaks. (Gerd Hoffmann)
- roms: minor fixes and cleanups. (Gerd Hoffmann)
- pc: add machine type for 0.12 (Gerd Hoffmann)
- loader: more ignores for rom intended to be loaded by the bios (Aurelien Jarno)
- vnc_refresh: return if vd->timer is NULL (Stefano Stabellini)
- QMP: Don't free async event's 'data' (Luiz Capitulino)
- Handle TFTP ERROR from client (Thomas Horsten)
- dmg: fix ->open failure (Christoph Hellwig)
- virtio-pci: thinko fix (Michael S. Tsirkin)
- pc-bios: Update README (SeaBIOS) (Stefan Weil)
- vmware_vga: Check cursor dimensions passed from guest to avoid buffer overflow (Roland Dreier)
- remove pending exception on vcpu reset. (Gleb Natapov)
- Fix CPU topology initialization (Jiri Denemark)
- MCE: Fix bug of IA32_MCG_STATUS after system reset (Huang Ying)
- linuxboot: fix gdt address calculation (Avi Kivity)
- QMP: Drop wrong assert() (Luiz Capitulino)
- vnc: Fix artifacts in hextile decoding (Anthony Liguori)
- target-i386: Fix "call im" on x86_64 when executing 32-bit code (Aurelien Jarno)
- Add missing newline at the end of options list (Michael Tokarev)
- Don't load options roms intended to be loaded by the bios in qemu (Avi Kivity)
- USB: Improve usbdevice error messages (Scott Tsai)
- cpu-all.h: fix cpu_get_real_ticks() #ifdef (Aurelien Jarno)
- alpha: fix compile (Blue Swirl)
- user_only: compile everything with -fpie (Kirill A. Shutemov)
- fdc/sparc32: don't hang on detection under OBP (Artyom Tarasenko)
- scsi-disk: Inquiry with allocation length of CDB < 36 (v4) (Artyom Tarasenko)
- e1000: fix init values for command register (Michael S. Tsirkin)
version 0.12.1:
- loader: fix rom loading at address 0 (fixes target-arm) (Aurelien Jarno)
- loader: fix rom_copy (fixes multiboot) (Kevin Wolf)
version 0.12.0:
- Update to SeaBIOS 0.5.0
- e1000: fix device link status in Linux (Anthony Liguori)
- monitor: fix QMP for balloon command (Luiz Capitulino)
- QMP: Return an empty dict by default (Luiz Capitulino)
- QMP: Only handle converted commands (Luiz Capitulino)
- pci: support PCI based option rom loading (Gerd Hoffman/Anthony Liguori)
- Fix backcompat for hotplug of SCSI controllers (Daniel P. Berrange)
- fdc: fix migration from 0.11 (Juan Quintela)
- vmware-vga: fix segv on cursor resize. (Dave Airlie)
- vmware-vga: various fixes (Dave Airlie/Anthony Liguori)
- qdev: improve property error reporting. (Gerd Hoffmann)
- fix vga names in default_list (Gerd Hoffmann)
- usb-host: check mon before using it. (Gerd Hoffmann)
- usb-net: use qdev for -usbdevice (Gerd Hoffmann)
- monitor: Catch printing to non-existent monitor (Luiz Capitulino)
- Avoid permanently disabled QEMU monitor when UNIX migration fails (Daniel P. Berrange)
- Fix loading of ELF multiboot kernels (Kevin Wolf)
- qemu-io: Fix memory leak (Kevin Wolf)
- Fix thinko in linuxboot.S (Paolo Bonzini)
- target-i386: Fix evaluation of DR7 register (Jan Kiszka)
- vnc: hextile: do not generate ForegroundSpecified and SubrectsColoured tiles (Anthony Liguori)
- S390: Bail out without KVM (Alexander Graf)
- S390: Don't tell guest we're updating config space (Alexander Graf)
- target-s390: Fail on unknown instructions (Alexander Graf)
- osdep: Fix runtime failure on older Linux kernels (Andre Przywara)
- Fix a make -j race (Juergen Lock)
- target-alpha: Fix generic ctz64. (Richard Henderson)
- s390: Fix buggy assignment (Stefan Weil)
- target-mips: fix user-mode emulation startup (Nathan Froyd)
- target-i386: Update CPUID feature set for TCG (Andre Przywara)
- s390: fix build on 32 bit host (Michael S. Tsirkin)
version 0.12.0-rc2:
- v2: properly save kvm system time msr registers (Glauber Costa)
- convert more monitor commands to qmp (Luiz Capitulino)
- vnc: fix capslock tracking logic. (Gerd Hoffmann)
- QemuOpts: allow larger option values. (Gerd Hoffmann)
- scsi: fix drive hotplug. (Gerd Hoffmann)
- pci: don't hw_error() when no slot is available. (Gerd Hoffmann)
- pci: don't abort() when trying to hotplug with acpi off. (Gerd Hoffmann)
- allow default devices to be implemented in config file (Gerd Hoffman)
- vc: colorize chardev title line with blue background. (Gerd Hoffmann)
- chardev: make chardevs specified in config file work. (Gerd Hoffmann)
- qdev: also match bus name for global properties (Gerd Hoffmann)
- qdev: add command line option to set global defaults for properties. (Gerd Hoffmann)
- kvm: x86: Save/restore exception_index (Jan Kiszka)
- qdev: Replace device names containing whitespace (Markus Armbruster)
- fix rtc-td-hack on host without high-res timers (Gleb Natapov)
- virtio: verify features on load (Michael S. Tsirkin)
- vmware_vga: add rom file so that it boots. (Dave Airlie)
- Do not abort on qemu_malloc(0) in production builds (Anthony Liguori)
- Fix ARM userspace strex implementation. (Paul Brook)
- qemu: delete rule target on error (Michael S. Tsirkin)
- QMP: add human-readable description to error response (Markus Armbruster)
- convert more monitor commands to QError (Markus Armbruster)
- monitor: Fix double-prompt after "change vnc passwd BLA" (Markus Armbruster)
- monitor: do_cont(): Don't ask for passwords (Luiz Capitulino)
- monitor: Introduce 'block_passwd' command (Luiz Capitulino)
- pci: interrupt disable bit support (Michael S. Tsirkin)
- pci: interrupt status bit implementation (Michael S. Tsirkin)
- pci: prepare irq code for interrupt state (Michael S. Tsirkin)
- msix: function mask support (Michael S. Tsirkin)
- msix: macro rename for function mask support (Michael S. Tsirkin)
- cpuid: Fix multicore setup on Intel (Andre Przywara)
- kvm: x86: Fix initial kvm_has_msr_star (Jan Kiszka)
- Update OpenBIOS images to r640 (Aurelien Jarno)
version 0.10.2:
- fix savevm/loadvm (Anthony Liguori)

View File

@@ -70,7 +70,7 @@ $(filter %-softmmu,$(SUBDIR_RULES)): libqemu_common.a
$(filter %-user,$(SUBDIR_RULES)): libuser.a
libuser.a:
libuser.a: $(GENERATED_HEADERS)
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libuser V="$(V)" TARGET_DIR="libuser/" all,)
ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
@@ -81,6 +81,12 @@ ALL_SUBDIRS=$(TARGET_DIRS) $(patsubst %,pc-bios/%, $(ROMS))
recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES)
#######################################################################
# QObject
qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
qobject-obj-y += qerror.o
#######################################################################
# block-obj-y is code used by both qemu system emulation and qemu-img
@@ -120,6 +126,7 @@ net-obj-y += $(addprefix net/, $(net-nested-y))
obj-y = $(block-obj-y)
obj-y += $(net-obj-y)
obj-y += $(qobject-obj-y)
obj-y += readline.o console.o
obj-y += tcg-runtime.o host-utils.o
@@ -152,8 +159,6 @@ obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o
obj-y += qemu-char.o aio.o savevm.o
obj-y += msmouse.o ps2.o
obj-y += qdev.o qdev-properties.o
obj-y += qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o json-lexer.o
obj-y += json-streamer.o json-parser.o qjson.o qerror.o
obj-y += qemu-config.o block-migration.o
obj-$(CONFIG_BRLAPI) += baum.o
@@ -230,18 +235,18 @@ libqemu_common.a: $(obj-y)
qemu-img.o: qemu-img-cmds.h
qemu-img$(EXESUF): qemu-img.o qemu-tool.o $(block-obj-y)
qemu-img$(EXESUF): qemu-img.o qemu-tool.o $(block-obj-y) $(qobject-obj-y)
qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o $(block-obj-y)
qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o $(block-obj-y) $(qobject-obj-y)
qemu-io$(EXESUF): qemu-io.o qemu-tool.o cmd.o $(block-obj-y)
qemu-io$(EXESUF): qemu-io.o qemu-tool.o cmd.o $(block-obj-y) $(qobject-obj-y)
qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $@")
check-qint: check-qint.o qint.o qemu-malloc.o
check-qstring: check-qstring.o qstring.o qemu-malloc.o
check-qdict: check-qdict.o qdict.o qint.o qstring.o qemu-malloc.o
check-qdict: check-qdict.o qdict.o qint.o qstring.o qbool.o qemu-malloc.o qlist.o
check-qlist: check-qlist.o qlist.o qint.o qemu-malloc.o
check-qfloat: check-qfloat.o qfloat.o qemu-malloc.o
check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o qemu-malloc.o

View File

@@ -2,10 +2,15 @@
include ../config-host.mak
include $(SRC_PATH)/rules.mak
-include config.mak
.PHONY: all
VPATH=$(SRC_PATH)
# Do not take %.o from $(SRC_PATH), only %.c and %.h
# All %.o for user targets should be built with -fpie, when
# configured with --enable-user-pie, so we don't want to
# take %.o from $(SRC_PATH), since they built without -fpie
vpath %.c %.h $(SRC_PATH)
QEMU_CFLAGS+=-I..

View File

@@ -4,45 +4,57 @@
Introduction
-------------
The QEMU Monitor Protocol (QMP) is a JSON[1] based protocol for QEMU.
The QEMU Monitor Protocol (QMP) allows applications to communicate with
QEMU's Monitor.
By using it applications can control QEMU in reliable and "parseable" way,
QMP also provides asynchronous events support.
QMP is JSON[1] based and has the following features:
- Lightweight, text-based, easy to parse data format
- Asynchronous events support
- Stability
For more information, please, refer to the following files:
o qmp-spec.txt QEMU Monitor Protocol current draft specification
o qmp-spec.txt QEMU Monitor Protocol current specification
o qmp-events.txt List of available asynchronous events
There are also two simple Python scripts available:
o qmp-shell A shell
o vm-info Show some informations about the Virtal Machine
o vm-info Show some information about the Virtual Machine
[1] http://www.json.org
Usage
-----
To enable QMP, QEMU has to be started in "control mode". This is done
by passing the flag "control" to the "-monitor" command-line option.
To enable QMP, QEMU has to be started in "control mode". There are
two ways of doing this, the simplest one is using the the '-qmp'
command-line option.
For example:
$ qemu [...] -monitor control,tcp:localhost:4444,server
$ qemu [...] -qmp tcp:localhost:4444,server
Will start QEMU in control mode, waiting for a client TCP connection
on localhost port 4444.
To manually test it you can connect with telnet and issue commands:
It is also possible to use the '-mon' command-line option to have
more complex combinations. Please, refer to the QEMU's manpage for
more information.
Simple Testing
--------------
To manually test QMP one can connect with telnet and issue commands:
$ telnet localhost 4444
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
{"QMP": {"capabilities": []}}
{ "execute": "query-version" }
{"return": "0.11.50"}
{"return": {"qemu": "0.11.50", "package": ""}}
Contact
-------

View File

@@ -1,4 +1,4 @@
QEMU Monitor Protocol Draft Specification - Version 0.1
QEMU Monitor Protocol Specification - Version 0.1
1. Introduction
===============
@@ -27,9 +27,9 @@ the JSON standard:
http://www.ietf.org/rfc/rfc4627.txt
For convenience, json-objects mentioned in this document will have its members
in a certain order. However, in real protocol usage json-objects members can
be in ANY order, thus no particular order should be assumed.
For convenience, json-object members and json-array elements mentioned in
this document will be in a certain order. However, in real protocol usage
they can be in ANY order, thus no particular order should be assumed.
2.1 General Definitions
-----------------------
@@ -85,12 +85,13 @@ without errors.
The format is:
{ "return": json-value, "id": json-value }
{ "return": json-object, "id": json-value }
Where,
- The "return" member contains the command returned data, which is defined
in a per-command basis or "OK" if the command does not return data
in a per-command basis or an empty json-object if the command does not
return data
- The "id" member contains the transaction identification associated
with the command execution (if issued by the Client)
@@ -102,13 +103,16 @@ completed because of an error condition.
The format is:
{ "error": { "class": json-string, "data": json-value }, "id": json-value }
{ "error": { "class": json-string, "data": json-object, "desc": json-string },
"id": json-value }
Where,
- The "class" member contains the error class name (eg. "ServiceUnavailable")
- The "data" member contains specific error data and is defined in a
per-command basis, it will be an empty json-object if the error has no data
- The "desc" member is a human-readable error message. Clients should
not attempt to parse this message.
- The "id" member contains the transaction identification associated with
the command execution (if issued by the Client)
@@ -124,7 +128,7 @@ to the Client at any time. They are called 'asynchronous events'.
The format is:
{ "event": json-string, "data": json-value,
{ "event": json-string, "data": json-object,
"timestamp": { "seconds": json-number, "microseconds": json-number } }
Where,
@@ -132,7 +136,7 @@ The format is:
- The "event" member contains the event's name
- The "data" member contains event specific data, which is defined in a
per-event basis, it is optional
- The "timestamp" member contains the exact time of when the event ocurred
- The "timestamp" member contains the exact time of when the event occurred
in the Server. It is a fixed json-object with time in seconds and
microseconds
@@ -154,19 +158,20 @@ S: {"QMP": {"capabilities": []}}
---------------------------
C: { "execute": "stop" }
S: {"return": "OK"}
S: {"return": {}}
3.3 KVM information
-------------------
C: {"execute": "query-kvm", "id": "example"}
S: {"return": "enabled", "id": "example"}
C: { "execute": "query-kvm", "id": "example" }
S: {"return": {"enabled": true, "present": true}, "id": "example"}
3.4 Parsing error
------------------
C: { "execute": }
S: {"error": {"class": "JSONParsing", "data": {}}}
S: {"error": {"class": "JSONParsing", "desc": "Invalid JSON syntax", "data":
{}}}
3.5 Powerdown event
-------------------
@@ -174,19 +179,25 @@ S: {"error": {"class": "JSONParsing", "data": {}}}
S: {"timestamp": {"seconds": 1258551470, "microseconds": 802384}, "event":
"POWERDOWN"}
4. Notes to Client implementors
-------------------------------
4. Compatibility Considerations
--------------------------------
4.1 It is recommended to always start the Server in pause mode, thus the
Client is able to perform any setup procedure without the risk of
race conditions and related problems
In order to achieve maximum compatibility between versions, Clients must not
assume any particular:
4.2 It is recommended to always check the capabilities json-array, issued
with the greeting message, at connection time
- Size of json-objects or length of json-arrays
- Order of json-object members or json-array elements
- Amount of errors generated by a command, that is, new errors can be added
to any existing command in newer versions of the Server
4.3 Json-objects or json-arrays mentioned in this document are not fixed
and no particular size or number of members/elements should be assumed.
New members/elements can be added at any time.
Additionally, Clients should always:
4.4 No particular order of json-objects members should be assumed, they
can change at any time
- Check the capabilities json-array at connection time
- Check the availability of commands with 'query-commands' before issuing them
5. Recommendations to Client implementors
-----------------------------------------
5.1 The Server should be always started in pause mode, thus the Client is
able to perform any setup procedure without the risk of race conditions
and related problems

View File

@@ -1 +1 @@
0.11.50
0.12.2

233
block.c
View File

@@ -26,6 +26,7 @@
#include "monitor.h"
#include "block_int.h"
#include "module.h"
#include "qemu-objects.h"
#ifdef CONFIG_BSD
#include <sys/types.h>
@@ -1139,61 +1140,203 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
}
void bdrv_info(Monitor *mon)
static void bdrv_print_dict(QObject *obj, void *opaque)
{
BlockDriverState *bs;
QDict *bs_dict;
Monitor *mon = opaque;
for (bs = bdrv_first; bs != NULL; bs = bs->next) {
monitor_printf(mon, "%s:", bs->device_name);
monitor_printf(mon, " type=");
switch(bs->type) {
case BDRV_TYPE_HD:
monitor_printf(mon, "hd");
break;
case BDRV_TYPE_CDROM:
monitor_printf(mon, "cdrom");
break;
case BDRV_TYPE_FLOPPY:
monitor_printf(mon, "floppy");
break;
}
monitor_printf(mon, " removable=%d", bs->removable);
if (bs->removable) {
monitor_printf(mon, " locked=%d", bs->locked);
}
if (bs->drv) {
monitor_printf(mon, " file=");
monitor_print_filename(mon, bs->filename);
if (bs->backing_file[0] != '\0') {
monitor_printf(mon, " backing_file=");
monitor_print_filename(mon, bs->backing_file);
}
monitor_printf(mon, " ro=%d", bs->read_only);
monitor_printf(mon, " drv=%s", bs->drv->format_name);
monitor_printf(mon, " encrypted=%d", bdrv_is_encrypted(bs));
} else {
monitor_printf(mon, " [not inserted]");
}
monitor_printf(mon, "\n");
bs_dict = qobject_to_qdict(obj);
monitor_printf(mon, "%s: type=%s removable=%d",
qdict_get_str(bs_dict, "device"),
qdict_get_str(bs_dict, "type"),
qdict_get_bool(bs_dict, "removable"));
if (qdict_get_bool(bs_dict, "removable")) {
monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked"));
}
if (qdict_haskey(bs_dict, "inserted")) {
QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted"));
monitor_printf(mon, " file=");
monitor_print_filename(mon, qdict_get_str(qdict, "file"));
if (qdict_haskey(qdict, "backing_file")) {
monitor_printf(mon, " backing_file=");
monitor_print_filename(mon, qdict_get_str(qdict, "backing_file"));
}
monitor_printf(mon, " ro=%d drv=%s encrypted=%d",
qdict_get_bool(qdict, "ro"),
qdict_get_str(qdict, "drv"),
qdict_get_bool(qdict, "encrypted"));
} else {
monitor_printf(mon, " [not inserted]");
}
monitor_printf(mon, "\n");
}
/* The "info blockstats" command. */
void bdrv_info_stats(Monitor *mon)
void bdrv_info_print(Monitor *mon, const QObject *data)
{
qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon);
}
/**
* bdrv_info(): Block devices information
*
* Each block device information is stored in a QDict and the
* returned QObject is a QList of all devices.
*
* The QDict contains the following:
*
* - "device": device name
* - "type": device type
* - "removable": true if the device is removable, false otherwise
* - "locked": true if the device is locked, false otherwise
* - "inserted": only present if the device is inserted, it is a QDict
* containing the following:
* - "file": device file name
* - "ro": true if read-only, false otherwise
* - "drv": driver format name
* - "backing_file": backing file name if one is used
* - "encrypted": true if encrypted, false otherwise
*
* Example:
*
* [ { "device": "ide0-hd0", "type": "hd", "removable": false, "locked": false,
* "inserted": { "file": "/tmp/foobar", "ro": false, "drv": "qcow2" } },
* { "device": "floppy0", "type": "floppy", "removable": true,
* "locked": false } ]
*/
void bdrv_info(Monitor *mon, QObject **ret_data)
{
QList *bs_list;
BlockDriverState *bs;
bs_list = qlist_new();
for (bs = bdrv_first; bs != NULL; bs = bs->next) {
monitor_printf(mon, "%s:"
" rd_bytes=%" PRIu64
" wr_bytes=%" PRIu64
" rd_operations=%" PRIu64
" wr_operations=%" PRIu64
"\n",
bs->device_name,
bs->rd_bytes, bs->wr_bytes,
bs->rd_ops, bs->wr_ops);
QObject *bs_obj;
const char *type = "unknown";
switch(bs->type) {
case BDRV_TYPE_HD:
type = "hd";
break;
case BDRV_TYPE_CDROM:
type = "cdrom";
break;
case BDRV_TYPE_FLOPPY:
type = "floppy";
break;
}
bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': %s, "
"'removable': %i, 'locked': %i }",
bs->device_name, type, bs->removable,
bs->locked);
assert(bs_obj != NULL);
if (bs->drv) {
QObject *obj;
QDict *bs_dict = qobject_to_qdict(bs_obj);
obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, "
"'encrypted': %i }",
bs->filename, bs->read_only,
bs->drv->format_name,
bdrv_is_encrypted(bs));
assert(obj != NULL);
if (bs->backing_file[0] != '\0') {
QDict *qdict = qobject_to_qdict(obj);
qdict_put(qdict, "backing_file",
qstring_from_str(bs->backing_file));
}
qdict_put_obj(bs_dict, "inserted", obj);
}
qlist_append_obj(bs_list, bs_obj);
}
*ret_data = QOBJECT(bs_list);
}
static void bdrv_stats_iter(QObject *data, void *opaque)
{
QDict *qdict;
Monitor *mon = opaque;
qdict = qobject_to_qdict(data);
monitor_printf(mon, "%s:", qdict_get_str(qdict, "device"));
qdict = qobject_to_qdict(qdict_get(qdict, "stats"));
monitor_printf(mon, " rd_bytes=%" PRId64
" wr_bytes=%" PRId64
" rd_operations=%" PRId64
" wr_operations=%" PRId64
"\n",
qdict_get_int(qdict, "rd_bytes"),
qdict_get_int(qdict, "wr_bytes"),
qdict_get_int(qdict, "rd_operations"),
qdict_get_int(qdict, "wr_operations"));
}
void bdrv_stats_print(Monitor *mon, const QObject *data)
{
qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon);
}
/**
* bdrv_info_stats(): show block device statistics
*
* Each device statistic information is stored in a QDict and
* the returned QObject is a QList of all devices.
*
* The QDict contains the following:
*
* - "device": device name
* - "stats": A QDict with the statistics information, it contains:
* - "rd_bytes": bytes read
* - "wr_bytes": bytes written
* - "rd_operations": read operations
* - "wr_operations": write operations
*
* Example:
*
* [ { "device": "ide0-hd0",
* "stats": { "rd_bytes": 512,
* "wr_bytes": 0,
* "rd_operations": 1,
* "wr_operations": 0 } },
* { "device": "ide1-cd0",
* "stats": { "rd_bytes": 0,
* "wr_bytes": 0,
* "rd_operations": 0,
* "wr_operations": 0 } } ]
*/
void bdrv_info_stats(Monitor *mon, QObject **ret_data)
{
QObject *obj;
QList *devices;
BlockDriverState *bs;
devices = qlist_new();
for (bs = bdrv_first; bs != NULL; bs = bs->next) {
obj = qobject_from_jsonf("{ 'device': %s, 'stats': {"
"'rd_bytes': %" PRId64 ","
"'wr_bytes': %" PRId64 ","
"'rd_operations': %" PRId64 ","
"'wr_operations': %" PRId64
"} }",
bs->device_name,
bs->rd_bytes, bs->wr_bytes,
bs->rd_ops, bs->wr_ops);
assert(obj != NULL);
qlist_append_obj(devices, obj);
}
*ret_data = QOBJECT(devices);
}
const char *bdrv_get_encrypted_filename(BlockDriverState *bs)

View File

@@ -4,6 +4,7 @@
#include "qemu-aio.h"
#include "qemu-common.h"
#include "qemu-option.h"
#include "qobject.h"
/* block.c */
typedef struct BlockDriver BlockDriver;
@@ -45,8 +46,10 @@ typedef struct QEMUSnapshotInfo {
#define BDRV_SECTOR_SIZE (1 << BDRV_SECTOR_BITS)
#define BDRV_SECTOR_MASK ~(BDRV_SECTOR_SIZE - 1);
void bdrv_info(Monitor *mon);
void bdrv_info_stats(Monitor *mon);
void bdrv_info_print(Monitor *mon, const QObject *data);
void bdrv_info(Monitor *mon, QObject **ret_data);
void bdrv_stats_print(Monitor *mon, const QObject *data);
void bdrv_info_stats(Monitor *mon, QObject **ret_data);
void bdrv_init(void);
void bdrv_init_with_whitelist(void);

View File

@@ -90,24 +90,21 @@ static int dmg_open(BlockDriverState *bs, const char *filename, int flags)
/* read offset of info blocks */
if(lseek(s->fd,-0x1d8,SEEK_END)<0) {
dmg_close:
close(s->fd);
/* open raw instead */
bs->drv=bdrv_find_format("raw");
return bs->drv->bdrv_open(bs, filename, flags);
goto fail;
}
info_begin=read_off(s->fd);
if(info_begin==0)
goto dmg_close;
goto fail;
if(lseek(s->fd,info_begin,SEEK_SET)<0)
goto dmg_close;
goto fail;
if(read_uint32(s->fd)!=0x100)
goto dmg_close;
goto fail;
if((count = read_uint32(s->fd))==0)
goto dmg_close;
goto fail;
info_end = info_begin+count;
if(lseek(s->fd,0xf8,SEEK_CUR)<0)
goto dmg_close;
goto fail;
/* read offsets */
last_in_offset = last_out_offset = 0;
@@ -116,14 +113,14 @@ dmg_close:
count = read_uint32(s->fd);
if(count==0)
goto dmg_close;
goto fail;
type = read_uint32(s->fd);
if(type!=0x6d697368 || count<244)
lseek(s->fd,count-4,SEEK_CUR);
else {
int new_size, chunk_count;
if(lseek(s->fd,200,SEEK_CUR)<0)
goto dmg_close;
goto fail;
chunk_count = (count-204)/40;
new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
s->types = qemu_realloc(s->types, new_size/2);
@@ -142,7 +139,7 @@ dmg_close:
chunk_count--;
i--;
if(lseek(s->fd,36,SEEK_CUR)<0)
goto dmg_close;
goto fail;
continue;
}
read_uint32(s->fd);
@@ -163,11 +160,14 @@ dmg_close:
s->compressed_chunk = qemu_malloc(max_compressed_size+1);
s->uncompressed_chunk = qemu_malloc(512*max_sectors_per_chunk);
if(inflateInit(&s->zstream) != Z_OK)
goto dmg_close;
goto fail;
s->current_chunk = s->n_chunks;
return 0;
fail:
close(s->fd);
return -1;
}
static inline int is_sector_in_chunk(BDRVDMGState* s,

View File

@@ -205,6 +205,8 @@ START_TEST(qdict_put_exists_test)
value = qdict_get_int(tests_dict, key);
fail_unless(value == 2);
fail_unless(qdict_size(tests_dict) == 1);
}
END_TEST

21
configure vendored
View File

@@ -256,6 +256,7 @@ blobs="yes"
pkgversion=""
check_utests="no"
user_pie="no"
zero_malloc=""
# OS specific
if check_define __linux__ ; then
@@ -1792,8 +1793,9 @@ fi
# Consult white-list to determine whether to enable werror
# by default. Only enable by default for git builds
z_version=`cut -f3 -d. $source_path/VERSION`
if test -z "$werror" ; then
z_version=`cut -f3 -d. $source_path/VERSION`
if test "$z_version" = "50" -a \
"$linux" = "yes" ; then
werror="yes"
@@ -1802,6 +1804,16 @@ if test -z "$werror" ; then
fi
fi
# Disable zero malloc errors for official releases unless explicitly told to
# enable/disable
if test -z "$zero_malloc" ; then
if test "$z_version" = "50" ; then
zero_malloc="no"
else
zero_malloc="yes"
fi
fi
if test "$werror" = "yes" ; then
QEMU_CFLAGS="-Werror $QEMU_CFLAGS"
fi
@@ -2109,6 +2121,10 @@ fi
echo "CONFIG_UNAME_RELEASE=\"$uname_release\"" >> $config_host_mak
if test "$zero_malloc" = "yes" ; then
echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak
fi
# USB host support
case "$usb" in
linux)
@@ -2636,3 +2652,6 @@ d=libuser
mkdir -p $d
rm -f $d/Makefile
ln -s $source_path/Makefile.user $d/Makefile
if test "$static" = "no" -a "$user_pie" = "yes" ; then
echo "QEMU_CFLAGS+=-fpie" > $d/config.mak
fi

View File

@@ -1384,6 +1384,16 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds, QemuOpt
s->t_attrib = s->t_attrib_default;
text_console_resize(s);
if (chr->label) {
char msg[128];
int len;
s->t_attrib.bgcol = COLOR_BLUE;
len = snprintf(msg, sizeof(msg), "%s console\r\n", chr->label);
console_puts(chr, (uint8_t*)msg, len);
s->t_attrib = s->t_attrib_default;
}
qemu_chr_generic_open(chr);
if (chr->init)
chr->init(chr);

View File

@@ -44,7 +44,8 @@ struct MouseTransformInfo {
int a[7];
};
void do_info_mice(Monitor *mon);
void do_info_mice_print(Monitor *mon, const QObject *data);
void do_info_mice(Monitor *mon, QObject **ret_data);
void do_mouse_set(Monitor *mon, const QDict *qdict);
/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
@@ -322,7 +323,8 @@ void vnc_display_init(DisplayState *ds);
void vnc_display_close(DisplayState *ds);
int vnc_display_open(DisplayState *ds, const char *display);
int vnc_display_password(DisplayState *ds, const char *password);
void do_info_vnc(Monitor *mon);
void do_info_vnc_print(Monitor *mon, const QObject *data);
void do_info_vnc(Monitor *mon, QObject **ret_data);
char *vnc_display_local_addr(DisplayState *ds);
/* curses.c */

View File

@@ -1017,7 +1017,8 @@ static inline int64_t cpu_get_real_ticks (void)
#endif
}
#elif (defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__)
#elif defined(__mips__) && \
((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__))
/*
* binutils wants to use rdhwr only on mips32r2
* but as linux kernel emulate it, it's fine

View File

@@ -164,7 +164,7 @@ static inline int ctz64(uint64_t val)
{
#if QEMU_GNUC_PREREQ(3, 4)
if (val)
return __builtin_ctz(val);
return __builtin_ctzll(val);
else
return 64;
#else

View File

@@ -19,8 +19,15 @@ typedef struct QEMUMachine {
QEMUMachineInitFunc *init;
int use_scsi;
int max_cpus;
int no_serial:1,
no_parallel:1,
use_virtcon:1,
no_vga:1,
no_floppy:1,
no_cdrom:1,
no_sdcard:1;
int is_default;
CompatProperty *compat_props;
GlobalProperty *compat_props;
struct QEMUMachine *next;
} QEMUMachine;

View File

@@ -552,7 +552,7 @@ static struct bt_device_s *bt_hid_init(struct bt_scatternet_s *net,
BT_HID_MTU, bt_hid_new_interrupt_ch);
s->usbdev = dev;
s->btdev.device.lmp_name = s->usbdev->devname;
s->btdev.device.lmp_name = s->usbdev->product_desc;
usb_hid_datain_cb(s->usbdev, s, bt_hid_datain);
s->btdev.device.handle_destroy = bt_hid_destroy;
@@ -566,6 +566,6 @@ static struct bt_device_s *bt_hid_init(struct bt_scatternet_s *net,
struct bt_device_s *bt_keyboard_init(struct bt_scatternet_s *net)
{
USBDevice *dev = usb_create_simple(NULL /* FIXME */, "QEMU USB Keyboard");
USBDevice *dev = usb_create_simple(NULL /* FIXME */, "usb-kbd");
return bt_hid_init(net, dev, class_keyboard);
}

View File

@@ -3209,22 +3209,21 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
pci_register_bar((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE,
PCI_BASE_ADDRESS_SPACE_MEMORY, cirrus_pci_mmio_map);
}
/* ROM BIOS */
rom_add_vga(VGABIOS_CIRRUS_FILENAME);
return 0;
}
void pci_cirrus_vga_init(PCIBus *bus)
{
pci_create_simple(bus, -1, "Cirrus VGA");
pci_create_simple(bus, -1, "cirrus-vga");
}
static PCIDeviceInfo cirrus_vga_info = {
.qdev.name = "Cirrus VGA",
.qdev.name = "cirrus-vga",
.qdev.desc = "Cirrus CLGD 54xx VGA",
.qdev.size = sizeof(PCICirrusVGAState),
.qdev.vmsd = &vmstate_pci_cirrus_vga,
.init = pci_cirrus_vga_initfn,
.romfile = VGABIOS_CIRRUS_FILENAME,
.config_write = pci_cirrus_write_config,
};

View File

@@ -1089,7 +1089,6 @@ static int pci_e1000_init(PCIDevice *pci_dev)
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
pci_config_set_device_id(pci_conf, E1000_DEVID);
*(uint16_t *)(pci_conf+0x04) = cpu_to_le16(0x0407);
*(uint16_t *)(pci_conf+0x06) = cpu_to_le16(0x0010);
pci_conf[0x08] = 0x03;
pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
@@ -1121,14 +1120,6 @@ static int pci_e1000_init(PCIDevice *pci_dev)
d->dev.qdev.info->name, d->dev.qdev.id, d);
qemu_format_nic_info_str(&d->nic->nc, macaddr);
if (!pci_dev->qdev.hotplugged) {
static int loaded = 0;
if (!loaded) {
rom_add_option("pxe-e1000.bin");
loaded = 1;
}
}
return 0;
}
@@ -1146,6 +1137,7 @@ static PCIDeviceInfo e1000_info = {
.qdev.vmsd = &vmstate_e1000,
.init = pci_e1000_init,
.exit = pci_e1000_uninit,
.romfile = "pxe-e1000.bin",
.qdev.props = (Property[]) {
DEFINE_NIC_PROPERTIES(E1000State, conf),
DEFINE_PROP_END_OF_LIST(),

View File

@@ -661,7 +661,7 @@ static int fdc_post_load(void *opaque, int version_id)
}
static const VMStateDescription vmstate_fdc = {
.name = "fdctrl",
.name = "fdc",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
@@ -699,31 +699,6 @@ static const VMStateDescription vmstate_fdc = {
}
};
static const VMStateDescription vmstate_fdc_isa = {
.name = "fdc",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
.fields = (VMStateField []) {
/* Controller State */
VMSTATE_STRUCT(state, fdctrl_isabus_t, 0, vmstate_fdc, fdctrl_t),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_fdc_sysbus = {
.name = "fdc",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
.fields = (VMStateField []) {
/* Controller State */
VMSTATE_STRUCT(state, fdctrl_sysbus_t, 0, vmstate_fdc, fdctrl_t),
VMSTATE_END_OF_LIST()
}
};
static void fdctrl_external_reset_sysbus(DeviceState *d)
{
fdctrl_sysbus_t *sys = container_of(d, fdctrl_sysbus_t, busdev.qdev);
@@ -960,6 +935,12 @@ static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl)
fdctrl->dsr &= ~FD_DSR_PWRDOWN;
fdctrl->dor |= FD_DOR_nRESET;
/* Sparc mutation */
if (fdctrl->sun4m) {
retval |= FD_MSR_DIO;
fdctrl_reset_irq(fdctrl);
};
FLOPPY_DPRINTF("main status register: 0x%02x\n", retval);
return retval;
@@ -1926,7 +1907,7 @@ fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
return fdctrl;
}
static int fdctrl_init_common(fdctrl_t *fdctrl)
static int fdctrl_init_common(fdctrl_t *fdctrl, target_phys_addr_t io_base)
{
int i, j;
static int command_tables_inited = 0;
@@ -1957,6 +1938,7 @@ static int fdctrl_init_common(fdctrl_t *fdctrl)
DMA_register_channel(fdctrl->dma_chann, &fdctrl_transfer_handler, fdctrl);
fdctrl_connect_drives(fdctrl);
vmstate_register(io_base, &vmstate_fdc, fdctrl);
return 0;
}
@@ -1980,7 +1962,7 @@ static int isabus_fdc_init1(ISADevice *dev)
isa_init_irq(&isa->busdev, &fdctrl->irq, isairq);
fdctrl->dma_chann = dma_chann;
ret = fdctrl_init_common(fdctrl);
ret = fdctrl_init_common(fdctrl, iobase);
return ret;
}
@@ -1998,7 +1980,7 @@ static int sysbus_fdc_init1(SysBusDevice *dev)
qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
fdctrl->dma_chann = -1;
ret = fdctrl_init_common(fdctrl);
ret = fdctrl_init_common(fdctrl, io);
return ret;
}
@@ -2015,7 +1997,7 @@ static int sun4m_fdc_init1(SysBusDevice *dev)
qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
fdctrl->sun4m = 1;
return fdctrl_init_common(fdctrl);
return fdctrl_init_common(fdctrl, io);
}
static ISADeviceInfo isa_fdc_info = {
@@ -2023,7 +2005,6 @@ static ISADeviceInfo isa_fdc_info = {
.qdev.name = "isa-fdc",
.qdev.size = sizeof(fdctrl_isabus_t),
.qdev.no_user = 1,
.qdev.vmsd = &vmstate_fdc_isa,
.qdev.reset = fdctrl_external_reset_isa,
.qdev.props = (Property[]) {
DEFINE_PROP_DRIVE("driveA", fdctrl_isabus_t, state.drives[0].dinfo),
@@ -2036,7 +2017,6 @@ static SysBusDeviceInfo sysbus_fdc_info = {
.init = sysbus_fdc_init1,
.qdev.name = "sysbus-fdc",
.qdev.size = sizeof(fdctrl_sysbus_t),
.qdev.vmsd = &vmstate_fdc_sysbus,
.qdev.reset = fdctrl_external_reset_sysbus,
.qdev.props = (Property[]) {
DEFINE_PROP_DRIVE("driveA", fdctrl_sysbus_t, state.drives[0].dinfo),
@@ -2049,7 +2029,6 @@ static SysBusDeviceInfo sun4m_fdc_info = {
.init = sun4m_fdc_init1,
.qdev.name = "SUNW,fdtwo",
.qdev.size = sizeof(fdctrl_sysbus_t),
.qdev.vmsd = &vmstate_fdc_sysbus,
.qdev.reset = fdctrl_external_reset_sysbus,
.qdev.props = (Property[]) {
DEFINE_PROP_DRIVE("drive", fdctrl_sysbus_t, state.drives[0].dinfo),

View File

@@ -45,11 +45,12 @@ typedef struct _FWCfgEntry {
FWCfgCallback callback;
} FWCfgEntry;
typedef struct _FWCfgState {
struct _FWCfgState {
FWCfgEntry entries[2][FW_CFG_MAX_ENTRY];
FWCfgFiles *files;
uint16_t cur_entry;
uint32_t cur_offset;
} FWCfgState;
};
static void fw_cfg_write(FWCfgState *s, uint8_t value)
{
@@ -210,9 +211,8 @@ static const VMStateDescription vmstate_fw_cfg = {
}
};
int fw_cfg_add_bytes(void *opaque, uint16_t key, uint8_t *data, uint32_t len)
int fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len)
{
FWCfgState *s = opaque;
int arch = !!(key & FW_CFG_ARCH_LOCAL);
key &= FW_CFG_ENTRY_MASK;
@@ -226,37 +226,36 @@ int fw_cfg_add_bytes(void *opaque, uint16_t key, uint8_t *data, uint32_t len)
return 1;
}
int fw_cfg_add_i16(void *opaque, uint16_t key, uint16_t value)
int fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value)
{
uint16_t *copy;
copy = qemu_malloc(sizeof(value));
*copy = cpu_to_le16(value);
return fw_cfg_add_bytes(opaque, key, (uint8_t *)copy, sizeof(value));
return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
}
int fw_cfg_add_i32(void *opaque, uint16_t key, uint32_t value)
int fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value)
{
uint32_t *copy;
copy = qemu_malloc(sizeof(value));
*copy = cpu_to_le32(value);
return fw_cfg_add_bytes(opaque, key, (uint8_t *)copy, sizeof(value));
return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
}
int fw_cfg_add_i64(void *opaque, uint16_t key, uint64_t value)
int fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
{
uint64_t *copy;
copy = qemu_malloc(sizeof(value));
*copy = cpu_to_le64(value);
return fw_cfg_add_bytes(opaque, key, (uint8_t *)copy, sizeof(value));
return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
}
int fw_cfg_add_callback(void *opaque, uint16_t key, FWCfgCallback callback,
int fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
void *callback_opaque, uint8_t *data, size_t len)
{
FWCfgState *s = opaque;
int arch = !!(key & FW_CFG_ARCH_LOCAL);
if (!(key & FW_CFG_WRITE_CHANNEL))
@@ -275,8 +274,54 @@ int fw_cfg_add_callback(void *opaque, uint16_t key, FWCfgCallback callback,
return 1;
}
void *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
target_phys_addr_t ctl_addr, target_phys_addr_t data_addr)
int fw_cfg_add_file(FWCfgState *s, const char *dir, const char *filename,
uint8_t *data, uint32_t len)
{
const char *basename;
int i, index;
if (!s->files) {
int dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS;
s->files = qemu_mallocz(dsize);
fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, (uint8_t*)s->files, dsize);
}
index = be32_to_cpu(s->files->count);
if (index == FW_CFG_FILE_SLOTS) {
fprintf(stderr, "fw_cfg: out of file slots\n");
return 0;
}
fw_cfg_add_bytes(s, FW_CFG_FILE_FIRST + index, data, len);
basename = strrchr(filename, '/');
if (basename) {
basename++;
} else {
basename = filename;
}
snprintf(s->files->f[index].name, sizeof(s->files->f[index].name),
"%s/%s", dir, basename);
for (i = 0; i < index; i++) {
if (strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
FW_CFG_DPRINTF("%s: skip duplicate: %s\n", __FUNCTION__,
s->files->f[index].name);
return 1;
}
}
s->files->f[index].size = cpu_to_be32(len);
s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index);
FW_CFG_DPRINTF("%s: #%d: %s (%d bytes)\n", __FUNCTION__,
index, s->files->f[index].name, len);
s->files->count = cpu_to_be32(index+1);
return 1;
}
FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
target_phys_addr_t ctl_addr, target_phys_addr_t data_addr)
{
FWCfgState *s;
int io_ctl_memory, io_data_memory;

View File

@@ -26,7 +26,11 @@
#define FW_CFG_SETUP_ADDR 0x16
#define FW_CFG_SETUP_SIZE 0x17
#define FW_CFG_SETUP_DATA 0x18
#define FW_CFG_MAX_ENTRY 0x19
#define FW_CFG_FILE_DIR 0x19
#define FW_CFG_FILE_FIRST 0x20
#define FW_CFG_FILE_SLOTS 0x10
#define FW_CFG_MAX_ENTRY (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS)
#define FW_CFG_WRITE_CHANNEL 0x4000
#define FW_CFG_ARCH_LOCAL 0x8000
@@ -35,16 +39,31 @@
#define FW_CFG_INVALID 0xffff
#ifndef NO_QEMU_PROTOS
typedef struct FWCfgFile {
uint32_t size; /* file size */
uint16_t select; /* write this to 0x510 to read it */
uint16_t reserved;
char name[56];
} FWCfgFile;
typedef struct FWCfgFiles {
uint32_t count;
FWCfgFile f[];
} FWCfgFiles;
typedef void (*FWCfgCallback)(void *opaque, uint8_t *data);
int fw_cfg_add_bytes(void *opaque, uint16_t key, uint8_t *data, uint32_t len);
int fw_cfg_add_i16(void *opaque, uint16_t key, uint16_t value);
int fw_cfg_add_i32(void *opaque, uint16_t key, uint32_t value);
int fw_cfg_add_i64(void *opaque, uint16_t key, uint64_t value);
int fw_cfg_add_callback(void *opaque, uint16_t key, FWCfgCallback callback,
typedef struct _FWCfgState FWCfgState;
int fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len);
int fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);
int fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value);
int fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);
int fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
void *callback_opaque, uint8_t *data, size_t len);
void *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
target_phys_addr_t crl_addr, target_phys_addr_t data_addr);
int fw_cfg_add_file(FWCfgState *s, const char *dir, const char *filename,
uint8_t *data, uint32_t len);
FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
target_phys_addr_t crl_addr, target_phys_addr_t data_addr);
#endif /* NO_QEMU_PROTOS */

View File

@@ -178,7 +178,7 @@ static PCIDeviceInfo grackle_pci_host_info = {
};
static PCIDeviceInfo dec_21154_pci_host_info = {
.qdev.name = "DEC 21154",
.qdev.name = "dec-21154",
.qdev.size = sizeof(PCIDevice),
.init = dec_21154_pci_host_init,
};
@@ -188,7 +188,7 @@ static void grackle_register_devices(void)
sysbus_register_dev("grackle", sizeof(GrackleState),
pci_grackle_init_device);
pci_qdev_register(&grackle_pci_host_info);
sysbus_register_dev("DEC 21154", sizeof(GrackleState),
sysbus_register_dev("dec-21154", sizeof(GrackleState),
pci_dec_21154_init_device);
pci_qdev_register(&dec_21154_pci_host_info);
}

View File

@@ -245,7 +245,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
{
PCIDevice *dev;
dev = pci_create(bus, -1, "CMD646 IDE");
dev = pci_create(bus, -1, "cmd646-ide");
qdev_prop_set_uint32(&dev->qdev, "secondary", secondary_ide_enabled);
qdev_init_nofail(&dev->qdev);
@@ -254,7 +254,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
static PCIDeviceInfo cmd646_ide_info[] = {
{
.qdev.name = "CMD646 IDE",
.qdev.name = "cmd646-ide",
.qdev.size = sizeof(PCIIDEState),
.init = pci_cmd646_ide_initfn,
.qdev.props = (Property[]) {

View File

@@ -161,7 +161,7 @@ void pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
{
PCIDevice *dev;
dev = pci_create_simple(bus, devfn, "PIIX3 IDE");
dev = pci_create_simple(bus, devfn, "piix3-ide");
pci_ide_create_devs(dev, hd_table);
}
@@ -171,18 +171,18 @@ void pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
{
PCIDevice *dev;
dev = pci_create_simple(bus, devfn, "PIIX4 IDE");
dev = pci_create_simple(bus, devfn, "piix4-ide");
pci_ide_create_devs(dev, hd_table);
}
static PCIDeviceInfo piix_ide_info[] = {
{
.qdev.name = "PIIX3 IDE",
.qdev.name = "piix3-ide",
.qdev.size = sizeof(PCIIDEState),
.qdev.no_user = 1,
.init = pci_piix3_ide_initfn,
},{
.qdev.name = "PIIX4 IDE",
.qdev.name = "piix4-ide",
.qdev.size = sizeof(PCIIDEState),
.qdev.no_user = 1,
.init = pci_piix4_ide_initfn,

View File

@@ -48,6 +48,7 @@
#include "sysemu.h"
#include "uboot_image.h"
#include "loader.h"
#include "fw_cfg.h"
#include <zlib.h>
@@ -526,15 +527,15 @@ struct Rom {
char *path;
size_t romsize;
uint8_t *data;
int align;
int isrom;
char *fw_dir;
char *fw_file;
target_phys_addr_t min;
target_phys_addr_t max;
target_phys_addr_t addr;
QTAILQ_ENTRY(Rom) next;
};
static FWCfgState *fw_cfg;
static QTAILQ_HEAD(, Rom) roms = QTAILQ_HEAD_INITIALIZER(roms);
int rom_enable_driver_roms;
@@ -548,7 +549,7 @@ static void rom_insert(Rom *rom)
/* list is ordered by load address */
QTAILQ_FOREACH(item, &roms, next) {
if (rom->min >= item->min)
if (rom->addr >= item->addr)
continue;
QTAILQ_INSERT_BEFORE(item, rom, next);
return;
@@ -556,8 +557,8 @@ static void rom_insert(Rom *rom)
QTAILQ_INSERT_TAIL(&roms, rom, next);
}
int rom_add_file(const char *file,
target_phys_addr_t min, target_phys_addr_t max, int align)
int rom_add_file(const char *file, const char *fw_dir,
target_phys_addr_t addr)
{
Rom *rom;
int rc, fd = -1;
@@ -576,9 +577,11 @@ int rom_add_file(const char *file,
goto err;
}
rom->align = align;
rom->min = min;
rom->max = max;
if (fw_dir) {
rom->fw_dir = qemu_strdup(fw_dir);
rom->fw_file = qemu_strdup(file);
}
rom->addr = addr;
rom->romsize = lseek(fd, 0, SEEK_END);
rom->data = qemu_mallocz(rom->romsize);
lseek(fd, 0, SEEK_SET);
@@ -590,6 +593,8 @@ int rom_add_file(const char *file,
}
close(fd);
rom_insert(rom);
if (rom->fw_file && fw_cfg)
fw_cfg_add_file(fw_cfg, rom->fw_dir, rom->fw_file, rom->data, rom->romsize);
return 0;
err:
@@ -603,15 +608,13 @@ err:
}
int rom_add_blob(const char *name, const void *blob, size_t len,
target_phys_addr_t min, target_phys_addr_t max, int align)
target_phys_addr_t addr)
{
Rom *rom;
rom = qemu_mallocz(sizeof(*rom));
rom->name = qemu_strdup(name);
rom->align = align;
rom->min = min;
rom->max = max;
rom->addr = addr;
rom->romsize = len;
rom->data = qemu_mallocz(rom->romsize);
memcpy(rom->data, blob, len);
@@ -623,14 +626,14 @@ int rom_add_vga(const char *file)
{
if (!rom_enable_driver_roms)
return 0;
return rom_add_file(file, PC_ROM_MIN_VGA, PC_ROM_MAX, PC_ROM_ALIGN);
return rom_add_file(file, "vgaroms", 0);
}
int rom_add_option(const char *file)
{
if (!rom_enable_driver_roms)
return 0;
return rom_add_file(file, PC_ROM_MIN_OPTION, PC_ROM_MAX, PC_ROM_ALIGN);
return rom_add_file(file, "genroms", 0);
}
static void rom_reset(void *unused)
@@ -638,8 +641,12 @@ static void rom_reset(void *unused)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->data == NULL)
if (rom->fw_file) {
continue;
}
if (rom->data == NULL) {
continue;
}
cpu_physical_memory_write_rom(rom->addr, rom->data, rom->romsize);
if (rom->isrom) {
/* rom needs to be written only once */
@@ -656,32 +663,17 @@ int rom_load_all(void)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (addr < rom->min)
addr = rom->min;
if (rom->max) {
/* load address range */
if (rom->align) {
addr += (rom->align-1);
addr &= ~(rom->align-1);
}
if (addr + rom->romsize > rom->max) {
fprintf(stderr, "rom: out of memory (rom %s, "
"addr 0x" TARGET_FMT_plx
", size 0x%zx, max 0x" TARGET_FMT_plx ")\n",
rom->name, addr, rom->romsize, rom->max);
return -1;
}
} else {
/* fixed address requested */
if (addr != rom->min) {
fprintf(stderr, "rom: requested regions overlap "
"(rom %s. free=0x" TARGET_FMT_plx
", addr=0x" TARGET_FMT_plx ")\n",
rom->name, addr, rom->min);
return -1;
}
if (rom->fw_file) {
continue;
}
rom->addr = addr;
if (addr > rom->addr) {
fprintf(stderr, "rom: requested regions overlap "
"(rom %s. free=0x" TARGET_FMT_plx
", addr=0x" TARGET_FMT_plx ")\n",
rom->name, addr, rom->addr);
return -1;
}
addr = rom->addr;
addr += rom->romsize;
memtype = cpu_get_physical_page_desc(rom->addr) & (3 << IO_MEM_SHIFT);
if (memtype == IO_MEM_ROM)
@@ -692,22 +684,35 @@ int rom_load_all(void)
return 0;
}
void rom_set_fw(void *f)
{
fw_cfg = f;
}
static Rom *find_rom(target_phys_addr_t addr)
{
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->max)
if (rom->fw_file) {
continue;
if (rom->min > addr)
}
if (rom->addr > addr) {
continue;
if (rom->min + rom->romsize < addr)
}
if (rom->addr + rom->romsize < addr) {
continue;
}
return rom;
}
return NULL;
}
/*
* Copies memory from registered ROMs to dest. Any memory that is contained in
* a ROM between addr and addr + size is copied. Note that this can involve
* multiple ROMs, which need not start at addr and need not end at addr + size.
*/
int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size)
{
target_phys_addr_t end = addr + size;
@@ -716,25 +721,27 @@ int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->max)
if (rom->fw_file) {
continue;
if (rom->min > addr)
}
if (rom->addr + rom->romsize < addr) {
continue;
if (rom->min + rom->romsize < addr)
continue;
if (rom->min > end)
}
if (rom->addr > end) {
break;
if (!rom->data)
}
if (!rom->data) {
continue;
}
d = dest + (rom->min - addr);
d = dest + (rom->addr - addr);
s = rom->data;
l = rom->romsize;
if (rom->min < addr) {
if (rom->addr < addr) {
d = dest;
s += (addr - rom->min);
l -= (addr - rom->min);
s += (addr - rom->addr);
l -= (addr - rom->addr);
}
if ((d + l) > (dest + size)) {
l = dest - d;
@@ -753,7 +760,7 @@ void *rom_ptr(target_phys_addr_t addr)
rom = find_rom(addr);
if (!rom || !rom->data)
return NULL;
return rom->data + (addr - rom->min);
return rom->data + (addr - rom->addr);
}
void do_info_roms(Monitor *mon)
@@ -761,10 +768,19 @@ void do_info_roms(Monitor *mon)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
monitor_printf(mon, "addr=" TARGET_FMT_plx
" size=0x%06zx mem=%s name=\"%s\" \n",
rom->addr, rom->romsize,
rom->isrom ? "rom" : "ram",
rom->name);
if (!rom->fw_file) {
monitor_printf(mon, "addr=" TARGET_FMT_plx
" size=0x%06zx mem=%s name=\"%s\" \n",
rom->addr, rom->romsize,
rom->isrom ? "rom" : "ram",
rom->name);
} else {
monitor_printf(mon, "fw=%s/%s"
" size=0x%06zx name=\"%s\" \n",
rom->fw_dir,
rom->fw_file,
rom->romsize,
rom->name);
}
}
}

View File

@@ -19,19 +19,21 @@ void pstrcpy_targphys(const char *name,
target_phys_addr_t dest, int buf_size,
const char *source);
int rom_add_file(const char *file,
target_phys_addr_t min, target_phys_addr_t max, int align);
int rom_add_file(const char *file, const char *fw_dir,
target_phys_addr_t addr);
int rom_add_blob(const char *name, const void *blob, size_t len,
target_phys_addr_t min, target_phys_addr_t max, int align);
target_phys_addr_t addr);
int rom_load_all(void);
void rom_set_fw(void *f);
int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size);
void *rom_ptr(target_phys_addr_t addr);
void do_info_roms(Monitor *mon);
#define rom_add_file_fixed(_f, _a) \
rom_add_file(_f, _a, 0, 0)
rom_add_file(_f, NULL, _a)
#define rom_add_blob_fixed(_f, _b, _l, _a) \
rom_add_blob(_f, _b, _l, _a, 0, 0)
rom_add_blob(_f, _b, _l, _a)
#define PC_ROM_MIN_VGA 0xc0000
#define PC_ROM_MIN_OPTION 0xc8000

View File

@@ -30,6 +30,8 @@
//#define DEBUG_CMOS
#define RTC_REINJECT_ON_ACK_COUNT 1000
#define RTC_SECONDS 0
#define RTC_SECONDS_ALARM 1
#define RTC_MINUTES 2
@@ -76,6 +78,7 @@ struct RTCState {
int64_t next_periodic_time;
/* second update */
int64_t next_second_time;
uint16_t irq_reinject_on_ack_count;
uint32_t irq_coalesced;
uint32_t period;
QEMUTimer *coalesced_timer;
@@ -180,6 +183,8 @@ static void rtc_periodic_timer(void *opaque)
s->cmos_data[RTC_REG_C] |= 0xc0;
#ifdef TARGET_I386
if(rtc_td_hack) {
if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT)
s->irq_reinject_on_ack_count = 0;
apic_reset_irq_delivered();
rtc_irq_raise(s->irq);
if (!apic_get_irq_delivered()) {
@@ -458,6 +463,18 @@ static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
case RTC_REG_C:
ret = s->cmos_data[s->cmos_index];
qemu_irq_lower(s->irq);
#ifdef TARGET_I386
if(s->irq_coalesced &&
s->irq_reinject_on_ack_count < RTC_REINJECT_ON_ACK_COUNT) {
s->irq_reinject_on_ack_count++;
apic_reset_irq_delivered();
qemu_irq_raise(s->irq);
if (apic_get_irq_delivered())
s->irq_coalesced--;
break;
}
#endif
s->cmos_data[RTC_REG_C] = 0x00;
break;
default:

View File

@@ -20,6 +20,7 @@
#define PCI_MSIX_FLAGS 2 /* Table at lower 11 bits */
#define PCI_MSIX_FLAGS_QSIZE 0x7FF
#define PCI_MSIX_FLAGS_ENABLE (1 << 15)
#define PCI_MSIX_FLAGS_MASKALL (1 << 14)
#define PCI_MSIX_FLAGS_BIRMASK (7 << 0)
/* MSI-X capability structure */
@@ -27,9 +28,10 @@
#define MSIX_PBA_OFFSET 8
#define MSIX_CAP_LENGTH 12
/* MSI enable bit is in byte 1 in FLAGS register */
#define MSIX_ENABLE_OFFSET (PCI_MSIX_FLAGS + 1)
/* MSI enable bit and maskall bit are in byte 1 in FLAGS register */
#define MSIX_CONTROL_OFFSET (PCI_MSIX_FLAGS + 1)
#define MSIX_ENABLE_MASK (PCI_MSIX_FLAGS_ENABLE >> 8)
#define MSIX_MASKALL_MASK (PCI_MSIX_FLAGS_MASKALL >> 8)
/* MSI-X table format */
#define MSIX_MSG_ADDR 0
@@ -101,22 +103,11 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
bar_nr);
pdev->msix_cap = config_offset;
/* Make flags bit writeable. */
pdev->wmask[config_offset + MSIX_ENABLE_OFFSET] |= MSIX_ENABLE_MASK;
pdev->wmask[config_offset + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |
MSIX_MASKALL_MASK;
return 0;
}
/* Handle MSI-X capability config write. */
void msix_write_config(PCIDevice *dev, uint32_t addr,
uint32_t val, int len)
{
unsigned enable_pos = dev->msix_cap + MSIX_ENABLE_OFFSET;
if (addr + len <= enable_pos || addr > enable_pos)
return;
if (msix_enabled(dev))
qemu_set_irq(dev->irq[0], 0);
}
static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr)
{
PCIDevice *dev = opaque;
@@ -157,10 +148,50 @@ static void msix_clr_pending(PCIDevice *dev, int vector)
*msix_pending_byte(dev, vector) &= ~msix_pending_mask(vector);
}
static int msix_function_masked(PCIDevice *dev)
{
return dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_MASKALL_MASK;
}
static int msix_is_masked(PCIDevice *dev, int vector)
{
unsigned offset = vector * MSIX_ENTRY_SIZE + MSIX_VECTOR_CTRL;
return dev->msix_table_page[offset] & MSIX_VECTOR_MASK;
return msix_function_masked(dev) ||
dev->msix_table_page[offset] & MSIX_VECTOR_MASK;
}
static void msix_handle_mask_update(PCIDevice *dev, int vector)
{
if (!msix_is_masked(dev, vector) && msix_is_pending(dev, vector)) {
msix_clr_pending(dev, vector);
msix_notify(dev, vector);
}
}
/* Handle MSI-X capability config write. */
void msix_write_config(PCIDevice *dev, uint32_t addr,
uint32_t val, int len)
{
unsigned enable_pos = dev->msix_cap + MSIX_CONTROL_OFFSET;
int vector;
if (addr + len <= enable_pos || addr > enable_pos) {
return;
}
if (!msix_enabled(dev)) {
return;
}
qemu_set_irq(dev->irq[0], 0);
if (msix_function_masked(dev)) {
return;
}
for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
msix_handle_mask_update(dev, vector);
}
}
static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
@@ -170,10 +201,7 @@ static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;
int vector = offset / MSIX_ENTRY_SIZE;
pci_set_long(dev->msix_table_page + offset, val);
if (!msix_is_masked(dev, vector) && msix_is_pending(dev, vector)) {
msix_clr_pending(dev, vector);
msix_notify(dev, vector);
}
msix_handle_mask_update(dev, vector);
}
static void msix_mmio_write_unallowed(void *opaque, target_phys_addr_t addr,
@@ -327,7 +355,7 @@ int msix_present(PCIDevice *dev)
int msix_enabled(PCIDevice *dev)
{
return (dev->cap_present & QEMU_PCI_CAP_MSIX) &&
(dev->config[dev->msix_cap + MSIX_ENABLE_OFFSET] &
(dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &
MSIX_ENABLE_MASK);
}
@@ -363,8 +391,8 @@ void msix_reset(PCIDevice *dev)
if (!(dev->cap_present & QEMU_PCI_CAP_MSIX))
return;
msix_free_irq_entries(dev);
dev->config[dev->msix_cap + MSIX_ENABLE_OFFSET] &=
~dev->wmask[dev->msix_cap + MSIX_ENABLE_OFFSET];
dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
memset(dev->msix_table_page, 0, MSIX_PAGE_SIZE);
msix_mask_all(dev, dev->msix_entries_nr);
}

39
hw/pc.c
View File

@@ -560,19 +560,21 @@ static int load_multiboot(void *fw_cfg,
}
if (!(flags & 0x00010000)) { /* MULTIBOOT_HEADER_HAS_ADDR */
uint64_t elf_entry;
uint64_t elf_low, elf_high;
int kernel_size;
fclose(f);
kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_low, &elf_high,
0, ELF_MACHINE, 0);
if (kernel_size < 0) {
fprintf(stderr, "Error while loading elf kernel\n");
exit(1);
}
mh_load_addr = mh_entry_addr = elf_entry;
mb_kernel_size = kernel_size;
mh_load_addr = elf_low;
mb_kernel_size = elf_high - elf_low;
mh_entry_addr = elf_entry;
mb_kernel_data = qemu_malloc(mb_kernel_size);
if (rom_copy(mb_kernel_data, elf_entry, kernel_size) != kernel_size) {
if (rom_copy(mb_kernel_data, mh_load_addr, mb_kernel_size) != mb_kernel_size) {
fprintf(stderr, "Error while fetching elf kernel from rom\n");
exit(1);
}
@@ -1088,6 +1090,7 @@ static void pc_init1(ram_addr_t ram_size,
bios_size, bios_offset | IO_MEM_ROM);
fw_cfg = bochs_bios_init();
rom_set_fw(fw_cfg);
if (linux_boot) {
load_linux(fw_cfg, kernel_filename, initrd_filename, kernel_cmdline, below_4g_mem_size);
@@ -1285,7 +1288,7 @@ void cmos_set_s3_resume(void)
}
static QEMUMachine pc_machine = {
.name = "pc-0.11",
.name = "pc-0.12",
.alias = "pc",
.desc = "Standard PC",
.init = pc_init_pci,
@@ -1293,12 +1296,31 @@ static QEMUMachine pc_machine = {
.is_default = 1,
};
static QEMUMachine pc_machine_v0_11 = {
.name = "pc-0.11",
.desc = "Standard PC, qemu 0.11",
.init = pc_init_pci,
.max_cpus = 255,
.compat_props = (GlobalProperty[]) {
{
.driver = "virtio-blk-pci",
.property = "vectors",
.value = stringify(0),
},{
.driver = "PCI",
.property = "rombar",
.value = stringify(0),
},
{ /* end of list */ }
}
};
static QEMUMachine pc_machine_v0_10 = {
.name = "pc-0.10",
.desc = "Standard PC, qemu 0.10",
.init = pc_init_pci,
.max_cpus = 255,
.compat_props = (CompatProperty[]) {
.compat_props = (GlobalProperty[]) {
{
.driver = "virtio-blk-pci",
.property = "class",
@@ -1315,6 +1337,10 @@ static QEMUMachine pc_machine_v0_10 = {
.driver = "virtio-blk-pci",
.property = "vectors",
.value = stringify(0),
},{
.driver = "PCI",
.property = "rombar",
.value = stringify(0),
},
{ /* end of list */ }
},
@@ -1330,6 +1356,7 @@ static QEMUMachine isapc_machine = {
static void pc_machine_init(void)
{
qemu_register_machine(&pc_machine);
qemu_register_machine(&pc_machine_v0_11);
qemu_register_machine(&pc_machine_v0_10);
qemu_register_machine(&isapc_machine);
}

View File

@@ -33,6 +33,7 @@
#include "scsi.h"
#include "virtio-blk.h"
#include "qemu-config.h"
#include "qemu-objects.h"
#if defined(TARGET_I386)
static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
@@ -40,7 +41,18 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
const char *opts_str)
{
QemuOpts *opts;
int ret;
PCIBus *bus;
int ret, devfn;
bus = pci_get_bus_devfn(&devfn, devaddr);
if (!bus) {
monitor_printf(mon, "Invalid PCI device address %s\n", devaddr);
return NULL;
}
if (!((BusState*)bus)->allow_hotplug) {
monitor_printf(mon, "PCI bus doesn't support hotplug\n");
return NULL;
}
opts = qemu_opts_parse(&qemu_net_opts, opts_str ? opts_str : "", NULL);
if (!opts) {
@@ -82,6 +94,7 @@ static int scsi_hot_add(DeviceState *adapter, DriveInfo *dinfo, int printinfo)
*/
dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1);
scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo, dinfo->unit);
dinfo->unit = scsidev->id;
if (printinfo)
qemu_error("OK bus %d, unit %d\n", scsibus->busnr, scsidev->id);
@@ -179,17 +192,17 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
monitor_printf(mon, "Invalid PCI device address %s\n", devaddr);
return NULL;
}
if (!((BusState*)bus)->allow_hotplug) {
monitor_printf(mon, "PCI bus doesn't support hotplug\n");
return NULL;
}
switch (type) {
case IF_SCSI:
if (!dinfo) {
monitor_printf(mon, "scsi requires a backing file/device.\n");
return NULL;
}
dev = pci_create(bus, devfn, "lsi53c895a");
if (qdev_init(&dev->qdev) < 0)
dev = NULL;
if (dev) {
if (dev && dinfo) {
if (scsi_hot_add(&dev->qdev, dinfo, 0) != 0) {
qdev_unplug(&dev->qdev);
dev = NULL;
@@ -212,7 +225,36 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
return dev;
}
void pci_device_hot_add(Monitor *mon, const QDict *qdict)
void pci_device_hot_add_print(Monitor *mon, const QObject *data)
{
QDict *qdict;
assert(qobject_type(data) == QTYPE_QDICT);
qdict = qobject_to_qdict(data);
monitor_printf(mon, "OK domain %d, bus %d, slot %d, function %d\n",
(int) qdict_get_int(qdict, "domain"),
(int) qdict_get_int(qdict, "bus"),
(int) qdict_get_int(qdict, "slot"),
(int) qdict_get_int(qdict, "function"));
}
/**
* pci_device_hot_add(): Hot add a PCI device
*
* Return a QDict with the following device information:
*
* - "domain": domain number
* - "bus": bus number
* - "slot": slot number
* - "function": function number
*
* Example:
*
* { "domain": 0, "bus": 0, "slot": 5, "function": 0 }
*/
void pci_device_hot_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
PCIDevice *dev = NULL;
const char *pci_addr = qdict_get_str(qdict, "pci_addr");
@@ -239,9 +281,11 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "invalid type: %s\n", type);
if (dev) {
monitor_printf(mon, "OK domain %d, bus %d, slot %d, function %d\n",
0, pci_bus_num(dev->bus), PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));
*ret_data =
qobject_from_jsonf("{ 'domain': 0, 'bus': %d, 'slot': %d, "
"'function': %d }", pci_bus_num(dev->bus),
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
assert(*ret_data != NULL);
} else
monitor_printf(mon, "failed to add %s\n", opts);
}

194
hw/pci.c
View File

@@ -26,6 +26,7 @@
#include "monitor.h"
#include "net.h"
#include "sysemu.h"
#include "loader.h"
//#define DEBUG_PCI
#ifdef DEBUG_PCI
@@ -62,12 +63,15 @@ static struct BusInfo pci_bus_info = {
.print_dev = pcibus_dev_print,
.props = (Property[]) {
DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
DEFINE_PROP_UINT32("rombar", PCIDevice, rom_bar, 1),
DEFINE_PROP_END_OF_LIST()
}
};
static void pci_update_mappings(PCIDevice *d);
static void pci_set_irq(void *opaque, int irq_num, int level);
static int pci_add_option_rom(PCIDevice *pdev);
target_phys_addr_t pci_mem_base;
static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
@@ -103,11 +107,48 @@ static int pci_bar(PCIDevice *d, int reg)
return type == PCI_HEADER_TYPE_BRIDGE ? PCI_ROM_ADDRESS1 : PCI_ROM_ADDRESS;
}
static inline int pci_irq_state(PCIDevice *d, int irq_num)
{
return (d->irq_state >> irq_num) & 0x1;
}
static inline void pci_set_irq_state(PCIDevice *d, int irq_num, int level)
{
d->irq_state &= ~(0x1 << irq_num);
d->irq_state |= level << irq_num;
}
static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change)
{
PCIBus *bus;
for (;;) {
bus = pci_dev->bus;
irq_num = bus->map_irq(pci_dev, irq_num);
if (bus->set_irq)
break;
pci_dev = bus->parent_dev;
}
bus->irq_count[irq_num] += change;
bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
}
/* Update interrupt status bit in config space on interrupt
* state change. */
static void pci_update_irq_status(PCIDevice *dev)
{
if (dev->irq_state) {
dev->config[PCI_STATUS] |= PCI_STATUS_INTERRUPT;
} else {
dev->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT;
}
}
static void pci_device_reset(PCIDevice *dev)
{
int r;
memset(dev->irq_state, 0, sizeof dev->irq_state);
dev->irq_state = 0;
pci_update_irq_status(dev);
dev->config[PCI_COMMAND] &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER);
dev->config[PCI_CACHE_LINE_SIZE] = 0x0;
@@ -274,6 +315,43 @@ static VMStateInfo vmstate_info_pci_config = {
.put = put_pci_config_device,
};
static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size)
{
PCIDevice *s = container_of(pv, PCIDevice, config);
uint32_t irq_state[PCI_NUM_PINS];
int i;
for (i = 0; i < PCI_NUM_PINS; ++i) {
irq_state[i] = qemu_get_be32(f);
if (irq_state[i] != 0x1 && irq_state[i] != 0) {
fprintf(stderr, "irq state %d: must be 0 or 1.\n",
irq_state[i]);
return -EINVAL;
}
}
for (i = 0; i < PCI_NUM_PINS; ++i) {
pci_set_irq_state(s, i, irq_state[i]);
}
return 0;
}
static void put_pci_irq_state(QEMUFile *f, void *pv, size_t size)
{
int i;
PCIDevice *s = container_of(pv, PCIDevice, config);
for (i = 0; i < PCI_NUM_PINS; ++i) {
qemu_put_be32(f, pci_irq_state(s, i));
}
}
static VMStateInfo vmstate_info_pci_irq_state = {
.name = "pci irq state",
.get = get_pci_irq_state,
.put = put_pci_irq_state,
};
const VMStateDescription vmstate_pci_device = {
.name = "PCIDevice",
.version_id = 2,
@@ -284,7 +362,9 @@ const VMStateDescription vmstate_pci_device = {
VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
vmstate_info_pci_config,
PCI_CONFIG_SPACE_SIZE),
VMSTATE_INT32_ARRAY_V(irq_state, PCIDevice, PCI_NUM_PINS, 2),
VMSTATE_BUFFER_UNSAFE_INFO(irq_state, PCIDevice, 2,
vmstate_info_pci_irq_state,
PCI_NUM_PINS * sizeof(int32_t)),
VMSTATE_END_OF_LIST()
}
};
@@ -299,7 +379,9 @@ const VMStateDescription vmstate_pcie_device = {
VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
vmstate_info_pci_config,
PCIE_CONFIG_SPACE_SIZE),
VMSTATE_INT32_ARRAY_V(irq_state, PCIDevice, PCI_NUM_PINS, 2),
VMSTATE_BUFFER_UNSAFE_INFO(irq_state, PCIDevice, 2,
vmstate_info_pci_irq_state,
PCI_NUM_PINS * sizeof(int32_t)),
VMSTATE_END_OF_LIST()
}
};
@@ -311,12 +393,23 @@ static inline const VMStateDescription *pci_get_vmstate(PCIDevice *s)
void pci_device_save(PCIDevice *s, QEMUFile *f)
{
/* Clear interrupt status bit: it is implicit
* in irq_state which we are saving.
* This makes us compatible with old devices
* which never set or clear this bit. */
s->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT;
vmstate_save_state(f, pci_get_vmstate(s), s);
/* Restore the interrupt status bit. */
pci_update_irq_status(s);
}
int pci_device_load(PCIDevice *s, QEMUFile *f)
{
return vmstate_load_state(f, pci_get_vmstate(s), s, s->version_id);
int ret;
ret = vmstate_load_state(f, pci_get_vmstate(s), s, s->version_id);
/* Restore the interrupt status bit. */
pci_update_irq_status(s);
return ret;
}
static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
@@ -490,16 +583,18 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
if (!bus->devices[devfn])
goto found;
}
hw_error("PCI: no devfn available for %s, all in use\n", name);
qemu_error("PCI: no devfn available for %s, all in use\n", name);
return NULL;
found: ;
} else if (bus->devices[devfn]) {
hw_error("PCI: devfn %d not available for %s, in use by %s\n", devfn,
qemu_error("PCI: devfn %d not available for %s, in use by %s\n", devfn,
name, bus->devices[devfn]->name);
return NULL;
}
pci_dev->bus = bus;
pci_dev->devfn = devfn;
pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
pci_dev->irq_state = 0;
pci_config_alloc(pci_dev);
header_type &= ~PCI_HEADER_TYPE_MULTI_FUNCTION;
@@ -535,6 +630,9 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
pci_dev = do_pci_register_device(pci_dev, bus, name, devfn,
config_read, config_write,
PCI_HEADER_TYPE_NORMAL);
if (pci_dev == NULL) {
hw_error("PCI: can't register device\n");
}
return pci_dev;
}
static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
@@ -882,23 +980,15 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
static void pci_set_irq(void *opaque, int irq_num, int level)
{
PCIDevice *pci_dev = opaque;
PCIBus *bus;
int change;
change = level - pci_dev->irq_state[irq_num];
change = level - pci_irq_state(pci_dev, irq_num);
if (!change)
return;
pci_dev->irq_state[irq_num] = level;
for (;;) {
bus = pci_dev->bus;
irq_num = bus->map_irq(pci_dev, irq_num);
if (bus->set_irq)
break;
pci_dev = bus->parent_dev;
}
bus->irq_count[irq_num] += change;
bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
pci_set_irq_state(pci_dev, irq_num, level);
pci_update_irq_status(pci_dev);
pci_change_irq_level(pci_dev, irq_num, change);
}
/***********************************************************/
@@ -1270,9 +1360,17 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,
info->config_read, info->config_write,
info->header_type);
if (pci_dev == NULL)
return -1;
rc = info->init(pci_dev);
if (rc != 0)
return rc;
/* rom loading */
if (pci_dev->romfile == NULL && info->romfile != NULL)
pci_dev->romfile = qemu_strdup(info->romfile);
pci_add_option_rom(pci_dev);
if (qdev->hotplugged)
bus->hotplug(pci_dev, 1);
return 0;
@@ -1350,6 +1448,64 @@ static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id,
return next;
}
static void pci_map_option_rom(PCIDevice *pdev, int region_num, pcibus_t addr, pcibus_t size, int type)
{
cpu_register_physical_memory(addr, size, pdev->rom_offset);
}
/* Add an option rom for the device */
static int pci_add_option_rom(PCIDevice *pdev)
{
int size;
char *path;
void *ptr;
if (!pdev->romfile)
return 0;
if (strlen(pdev->romfile) == 0)
return 0;
if (!pdev->rom_bar) {
/*
* Load rom via fw_cfg instead of creating a rom bar,
* for 0.11 compatibility.
*/
int class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
if (class == 0x0300) {
rom_add_vga(pdev->romfile);
} else {
rom_add_option(pdev->romfile);
}
return 0;
}
path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile);
if (path == NULL) {
path = qemu_strdup(pdev->romfile);
}
size = get_image_size(path);
if (size < 0) {
qemu_error("%s: failed to find romfile \"%s\"\n", __FUNCTION__,
pdev->romfile);
return -1;
}
if (size & (size - 1)) {
size = 1 << qemu_fls(size);
}
pdev->rom_offset = qemu_ram_alloc(size);
ptr = qemu_get_ram_ptr(pdev->rom_offset);
load_image(path, ptr);
qemu_free(path);
pci_register_bar(pdev, PCI_ROM_SLOT, size,
0, pci_map_option_rom);
return 0;
}
/* Reserve space and add capability to the linked list in pci config space */
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size)
{

View File

@@ -102,6 +102,7 @@ typedef struct PCIIORegion {
#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
#define PCI_COMMAND_MASTER 0x4 /* Enable bus master */
#define PCI_STATUS 0x06 /* 16 bits */
#define PCI_STATUS_INTERRUPT 0x08
#define PCI_REVISION_ID 0x08 /* 8 bits */
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
#define PCI_CLASS_DEVICE 0x0a /* Device class */
@@ -220,7 +221,7 @@ struct PCIDevice {
qemu_irq *irq;
/* Current IRQ levels. Used internally by the generic PCI code. */
int irq_state[PCI_NUM_PINS];
uint8_t irq_state;
/* Capability bits */
uint32_t cap_present;
@@ -241,6 +242,11 @@ struct PCIDevice {
uint32_t msix_bar_size;
/* Version id needed for VMState */
int32_t version_id;
/* Location of option rom */
char *romfile;
ram_addr_t rom_offset;
uint32_t rom_bar;
};
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
@@ -379,6 +385,9 @@ typedef struct {
/* pcie stuff */
int is_express; /* is this device pci express? */
/* rom bar */
const char *romfile;
} PCIDeviceInfo;
void pci_qdev_register(PCIDeviceInfo *info);

View File

@@ -500,7 +500,12 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
dev->info->name, name);
return -1;
}
return prop->info->parse(dev, prop, value);
if (prop->info->parse(dev, prop, value) != 0) {
fprintf(stderr, "property \"%s.%s\": failed to parse \"%s\"\n",
dev->info->name, name, value);
return -1;
}
return 0;
}
void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
@@ -593,26 +598,33 @@ void qdev_prop_set_defaults(DeviceState *dev, Property *props)
}
}
static CompatProperty *compat_props;
static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
void qdev_prop_register_compat(CompatProperty *props)
void qdev_prop_register_global(GlobalProperty *prop)
{
compat_props = props;
QTAILQ_INSERT_TAIL(&global_props, prop, next);
}
void qdev_prop_set_compat(DeviceState *dev)
void qdev_prop_register_global_list(GlobalProperty *props)
{
CompatProperty *prop;
int i;
if (!compat_props) {
return;
for (i = 0; props[i].driver != NULL; i++) {
qdev_prop_register_global(props+i);
}
for (prop = compat_props; prop->driver != NULL; prop++) {
if (strcmp(dev->info->name, prop->driver) != 0) {
}
void qdev_prop_set_globals(DeviceState *dev)
{
GlobalProperty *prop;
QTAILQ_FOREACH(prop, &global_props, next) {
if (strcmp(dev->info->name, prop->driver) != 0 &&
strcmp(dev->info->bus_info->name, prop->driver) != 0) {
continue;
}
if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
abort();
exit(1);
}
}
}

View File

@@ -103,7 +103,7 @@ DeviceState *qdev_create(BusState *bus, const char *name)
dev->parent_bus = bus;
qdev_prop_set_defaults(dev, dev->info->props);
qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
qdev_prop_set_compat(dev);
qdev_prop_set_globals(dev);
QLIST_INSERT_HEAD(&bus->children, dev, sibling);
if (qdev_hotplug) {
assert(bus->allow_hotplug);

View File

@@ -92,11 +92,12 @@ struct PropertyInfo {
int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
};
struct CompatProperty {
typedef struct GlobalProperty {
const char *driver;
const char *property;
const char *value;
};
QTAILQ_ENTRY(GlobalProperty) next;
} GlobalProperty;
/*** Board API. This should go away once we have a machine config file. ***/
@@ -256,8 +257,9 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
void qdev_prop_set_defaults(DeviceState *dev, Property *props);
void qdev_prop_register_compat(CompatProperty *props);
void qdev_prop_set_compat(DeviceState *dev);
void qdev_prop_register_global(GlobalProperty *prop);
void qdev_prop_register_global_list(GlobalProperty *props);
void qdev_prop_set_globals(DeviceState *dev);
/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
extern struct BusInfo system_bus_info;

View File

@@ -3353,14 +3353,6 @@ static int pci_rtl8139_init(PCIDevice *dev)
qemu_mod_timer(s->timer,
rtl8139_get_next_tctr_time(s,qemu_get_clock(vm_clock)));
#endif /* RTL8139_ONBOARD_TIMER */
if (!dev->qdev.hotplugged) {
static int loaded = 0;
if (!loaded) {
rom_add_option("pxe-rtl8139.bin");
loaded = 1;
}
}
return 0;
}
@@ -3371,6 +3363,7 @@ static PCIDeviceInfo rtl8139_info = {
.qdev.vmsd = &vmstate_rtl8139,
.init = pci_rtl8139_init,
.exit = pci_rtl8139_uninit,
.romfile = "pxe-rtl8139.bin",
.qdev.props = (Property[]) {
DEFINE_NIC_PROPERTIES(RTL8139State, conf),
DEFINE_PROP_END_OF_LIST(),

View File

@@ -307,7 +307,7 @@ static void virtio_s390_notify(void *opaque, uint16_t vector)
uint64_t token = s390_virtio_device_vq_token(dev, vector);
/* XXX kvm dependency! */
kvm_s390_virtio_irq(s390_cpu_addr2state(0), 1, token);
kvm_s390_virtio_irq(s390_cpu_addr2state(0), 0, token);
}
/**************** S390 Virtio Bus Device Descriptions *******************/

View File

@@ -142,6 +142,13 @@ static void s390_init(ram_addr_t ram_size,
ram_addr_t initrd_size = 0;
int i;
/* XXX we only work on KVM for now */
if (!kvm_enabled()) {
fprintf(stderr, "The S390 target only works with KVM enabled\n");
exit(1);
}
/* get a BUS */
s390_bus = s390_virtio_bus_init(&ram_size);
@@ -181,7 +188,7 @@ static void s390_init(ram_addr_t ram_size,
cpu_synchronize_state(env);
env->psw.addr = KERN_IMAGE_START;
env->psw.mask = 0x0000000180000000UL;
env->psw.mask = 0x0000000180000000ULL;
}
if (initrd_filename) {
@@ -201,7 +208,11 @@ static void s390_init(ram_addr_t ram_size,
}
/* Create VirtIO console */
qdev_init_nofail(qdev_create((BusState *)s390_bus, "virtio-console-s390"));
for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
if (virtcon_hds[i]) {
qdev_init_nofail(qdev_create((BusState *)s390_bus, "virtio-console-s390"));
}
}
/* Create VirtIO network adapters */
for(i = 0; i < nb_nics; i++) {
@@ -209,7 +220,7 @@ static void s390_init(ram_addr_t ram_size,
DeviceState *dev;
if (!nd->model) {
nd->model = (char*)"virtio";
nd->model = qemu_strdup("virtio");
}
if (strcmp(nd->model, "virtio")) {
@@ -243,6 +254,10 @@ static QEMUMachine s390_machine = {
.alias = "s390",
.desc = "VirtIO based S390 machine",
.init = s390_init,
.no_serial = 1,
.no_parallel = 1,
.use_virtcon = 1,
.no_vga = 1,
.max_cpus = 255,
.is_default = 1,
};

View File

@@ -5,6 +5,12 @@
* Based on code by Fabrice Bellard
*
* Written by Paul Brook
* Modifications:
* 2009-Dec-12 Artyom Tarasenko : implemented stamdard inquiry for the case
* when the allocation length of CDB is smaller
* than 36.
* 2009-Oct-13 Artyom Tarasenko : implemented the block descriptor in the
* MODE SENSE response.
*
* This code is licenced under the LGPL.
*
@@ -406,11 +412,6 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
return -1;
}
if (req->cmd.xfer < 36) {
BADF("Error: Inquiry (STANDARD) buffer size %zd "
"is less than 36 (TODO: only 5 required)\n", req->cmd.xfer);
}
buflen = req->cmd.xfer;
if (buflen > SCSI_MAX_INQUIRY_LEN)
buflen = SCSI_MAX_INQUIRY_LEN;
@@ -436,7 +437,15 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
Some later commands are also implemented. */
outbuf[2] = 3;
outbuf[3] = 2; /* Format 2 */
outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */
if (buflen > 36) {
outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */
} else {
/* If the allocation length of CDB is too small,
the additional length is not adjusted */
outbuf[4] = 36 - 5;
}
/* Sync data transfer and TCQ. */
outbuf[7] = 0x10 | (req->bus->tcq ? 0x02 : 0);
return buflen;

View File

@@ -87,7 +87,7 @@ static uint32_t syborg_virtio_readl(void *opaque, target_phys_addr_t offset)
break;
case SYBORG_VIRTIO_HOST_FEATURES:
ret = vdev->get_features(vdev);
ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
ret |= vdev->binding->get_features(s);
break;
case SYBORG_VIRTIO_GUEST_FEATURES:
ret = vdev->features;
@@ -242,8 +242,16 @@ static void syborg_virtio_update_irq(void *opaque, uint16_t vector)
qemu_set_irq(proxy->irq, level != 0);
}
static unsigned syborg_virtio_get_features(void *opaque)
{
unsigned ret = 0;
ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
return ret;
}
static VirtIOBindings syborg_virtio_bindings = {
.notify = syborg_virtio_update_irq
.notify = syborg_virtio_update_irq,
.get_features = syborg_virtio_get_features,
};
static int syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)

View File

@@ -148,7 +148,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
/* Use values found on a real PowerMac */
/* Uninorth main bus */
dev = qdev_create(NULL, "Uni-north main");
dev = qdev_create(NULL, "uni-north");
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
d = FROM_SYSBUS(UNINState, s);
@@ -157,7 +157,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
pic, 11 << 3, 4);
#if 0
pci_create_simple(d->host_state.bus, 11 << 3, "Uni-north main");
pci_create_simple(d->host_state.bus, 11 << 3, "uni-north");
#endif
sysbus_mmio_map(s, 0, 0xf2800000);
@@ -166,12 +166,12 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
/* DEC 21154 bridge */
#if 0
/* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */
pci_create_simple(d->host_state.bus, 12 << 3, "DEC 21154");
pci_create_simple(d->host_state.bus, 12 << 3, "dec-21154");
#endif
/* Uninorth AGP bus */
pci_create_simple(d->host_state.bus, 11 << 3, "Uni-north AGP");
dev = qdev_create(NULL, "Uni-north AGP");
pci_create_simple(d->host_state.bus, 11 << 3, "uni-north-agp");
dev = qdev_create(NULL, "uni-north-agp");
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
sysbus_mmio_map(s, 0, 0xf0800000);
@@ -180,8 +180,8 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
/* Uninorth internal bus */
#if 0
/* XXX: not needed for now */
pci_create_simple(d->host_state.bus, 14 << 3, "Uni-north internal");
dev = qdev_create(NULL, "Uni-north internal");
pci_create_simple(d->host_state.bus, 14 << 3, "uni-north-pci");
dev = qdev_create(NULL, "uni-north-pci");
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
sysbus_mmio_map(s, 0, 0xf4800000);
@@ -260,41 +260,41 @@ static int unin_internal_pci_host_init(PCIDevice *d)
}
static PCIDeviceInfo unin_main_pci_host_info = {
.qdev.name = "Uni-north main",
.qdev.name = "uni-north",
.qdev.size = sizeof(PCIDevice),
.init = unin_main_pci_host_init,
};
static PCIDeviceInfo dec_21154_pci_host_info = {
.qdev.name = "DEC 21154",
.qdev.name = "dec-21154",
.qdev.size = sizeof(PCIDevice),
.init = dec_21154_pci_host_init,
};
static PCIDeviceInfo unin_agp_pci_host_info = {
.qdev.name = "Uni-north AGP",
.qdev.name = "uni-north-agp",
.qdev.size = sizeof(PCIDevice),
.init = unin_agp_pci_host_init,
};
static PCIDeviceInfo unin_internal_pci_host_info = {
.qdev.name = "Uni-north internal",
.qdev.name = "uni-north-pci",
.qdev.size = sizeof(PCIDevice),
.init = unin_internal_pci_host_init,
};
static void unin_register_devices(void)
{
sysbus_register_dev("Uni-north main", sizeof(UNINState),
sysbus_register_dev("uni-north", sizeof(UNINState),
pci_unin_main_init_device);
pci_qdev_register(&unin_main_pci_host_info);
sysbus_register_dev("DEC 21154", sizeof(UNINState),
sysbus_register_dev("dec-21154", sizeof(UNINState),
pci_dec_21154_init_device);
pci_qdev_register(&dec_21154_pci_host_info);
sysbus_register_dev("Uni-north AGP", sizeof(UNINState),
sysbus_register_dev("uni-north-agp", sizeof(UNINState),
pci_unin_agp_init_device);
pci_qdev_register(&unin_agp_pci_host_info);
sysbus_register_dev("Uni-north internal", sizeof(UNINState),
sysbus_register_dev("uni-north-pci", sizeof(UNINState),
pci_unin_internal_init_device);
pci_qdev_register(&unin_internal_pci_host_info);
}

View File

@@ -630,7 +630,7 @@ USBDevice *usb_bt_init(HCIInfo *hci)
if (!hci)
return NULL;
dev = usb_create_simple(NULL /* FIXME */, "QEMU BT dongle");
dev = usb_create_simple(NULL /* FIXME */, "usb-bt-dongle");
s = DO_UPCAST(struct USBBtState, dev, dev);
s->dev.opaque = s;
@@ -645,7 +645,8 @@ USBDevice *usb_bt_init(HCIInfo *hci)
}
static struct USBDeviceInfo bt_info = {
.qdev.name = "QEMU BT dongle",
.product_desc = "QEMU BT dongle",
.qdev.name = "usb-bt-dongle",
.qdev.size = sizeof(struct USBBtState),
.init = usb_bt_initfn,
.handle_packet = usb_generic_handle_packet,

View File

@@ -43,7 +43,7 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
USBDeviceInfo *info = DO_UPCAST(USBDeviceInfo, qdev, base);
int rc;
pstrcpy(dev->devname, sizeof(dev->devname), qdev->info->name);
pstrcpy(dev->product_desc, sizeof(dev->product_desc), info->product_desc);
dev->info = info;
dev->auto_attach = 1;
rc = dev->info->init(dev);
@@ -131,7 +131,7 @@ static void do_attach(USBDevice *dev)
if (dev->attached) {
fprintf(stderr, "Warning: tried to attach usb device %s twice\n",
dev->devname);
dev->product_desc);
return;
}
dev->attached++;
@@ -153,7 +153,7 @@ int usb_device_attach(USBDevice *dev)
if (bus->nfree == 1) {
/* Create a new hub and chain it on. */
hub = usb_create_simple(bus, "QEMU USB Hub");
hub = usb_create_simple(bus, "usb-hub");
}
do_attach(dev);
return 0;
@@ -166,7 +166,7 @@ int usb_device_detach(USBDevice *dev)
if (!dev->attached) {
fprintf(stderr, "Warning: tried to detach unattached usb device %s\n",
dev->devname);
dev->product_desc);
return -1;
}
dev->attached--;
@@ -228,7 +228,7 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
monitor_printf(mon, "%*saddr %d.%d, speed %s, name %s%s\n",
indent, "", bus->busnr, dev->addr,
usb_speed(dev->speed), dev->devname,
usb_speed(dev->speed), dev->product_desc,
dev->attached ? ", attached" : "");
}
@@ -249,7 +249,8 @@ void usb_info(Monitor *mon)
if (!dev)
continue;
monitor_printf(mon, " Device %d.%d, Speed %s Mb/s, Product %s\n",
bus->busnr, dev->addr, usb_speed(dev->speed), dev->devname);
bus->busnr, dev->addr, usb_speed(dev->speed),
dev->product_desc);
}
}
}

View File

@@ -701,7 +701,7 @@ static int usb_hid_handle_control(USBDevice *dev, int request, int value,
break;
case 2:
/* product description */
ret = set_usb_string(data, s->dev.devname);
ret = set_usb_string(data, s->dev.product_desc);
break;
case 3:
/* vendor description */
@@ -880,8 +880,8 @@ void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
static struct USBDeviceInfo hid_info[] = {
{
.qdev.name = "QEMU USB Tablet",
.qdev.alias = "usb-tablet",
.product_desc = "QEMU USB Tablet",
.qdev.name = "usb-tablet",
.usbdevice_name = "tablet",
.qdev.size = sizeof(USBHIDState),
.init = usb_tablet_initfn,
@@ -891,8 +891,8 @@ static struct USBDeviceInfo hid_info[] = {
.handle_data = usb_hid_handle_data,
.handle_destroy = usb_hid_handle_destroy,
},{
.qdev.name = "QEMU USB Mouse",
.qdev.alias = "usb-mouse",
.product_desc = "QEMU USB Mouse",
.qdev.name = "usb-mouse",
.usbdevice_name = "mouse",
.qdev.size = sizeof(USBHIDState),
.init = usb_mouse_initfn,
@@ -902,8 +902,8 @@ static struct USBDeviceInfo hid_info[] = {
.handle_data = usb_hid_handle_data,
.handle_destroy = usb_hid_handle_destroy,
},{
.qdev.name = "QEMU USB Keyboard",
.qdev.alias = "usb-kbd",
.product_desc = "QEMU USB Keyboard",
.qdev.name = "usb-kbd",
.usbdevice_name = "keyboard",
.qdev.size = sizeof(USBHIDState),
.init = usb_keyboard_initfn,

View File

@@ -544,7 +544,8 @@ static int usb_hub_initfn(USBDevice *dev)
}
static struct USBDeviceInfo hub_info = {
.qdev.name = "QEMU USB Hub",
.product_desc = "QEMU USB Hub",
.qdev.name = "usb-hub",
.qdev.size = sizeof(USBHubState),
.init = usb_hub_initfn,
.handle_packet = usb_hub_handle_packet,

View File

@@ -591,7 +591,7 @@ static USBDevice *usb_msd_init(const char *filename)
}
/* create guest device */
dev = usb_create(NULL /* FIXME */, "QEMU USB MSD");
dev = usb_create(NULL /* FIXME */, "usb-storage");
qdev_prop_set_drive(&dev->qdev, "drive", dinfo);
if (qdev_init(&dev->qdev) < 0)
return NULL;
@@ -600,8 +600,8 @@ static USBDevice *usb_msd_init(const char *filename)
}
static struct USBDeviceInfo msd_info = {
.qdev.name = "QEMU USB MSD",
.qdev.alias = "usb-storage",
.product_desc = "QEMU USB MSD",
.qdev.name = "usb-storage",
.qdev.size = sizeof(MSDState),
.init = usb_msd_initfn,
.handle_packet = usb_generic_handle_packet,

View File

@@ -1420,8 +1420,7 @@ static void usbnet_cleanup(VLANClientState *nc)
{
USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
rndis_clear_responsequeue(s);
qemu_free(s);
s->nic = NULL;
}
static void usb_net_handle_destroy(USBDevice *dev)
@@ -1429,9 +1428,18 @@ static void usb_net_handle_destroy(USBDevice *dev)
USBNetState *s = (USBNetState *) dev;
/* TODO: remove the nd_table[] entry */
rndis_clear_responsequeue(s);
qemu_del_vlan_client(&s->nic->nc);
}
static NetClientInfo net_usbnet_info = {
.type = NET_CLIENT_TYPE_NIC,
.size = sizeof(NICState),
.can_receive = usbnet_can_receive,
.receive = usbnet_receive,
.cleanup = usbnet_cleanup,
};
static int usb_net_initfn(USBDevice *dev)
{
USBNetState *s = DO_UPCAST(USBNetState, dev, dev);
@@ -1447,47 +1455,50 @@ static int usb_net_initfn(USBDevice *dev)
s->media_state = 0; /* NDIS_MEDIA_STATE_CONNECTED */;
s->filter = 0;
s->vendorid = 0x1234;
qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
s->dev.qdev.info->name, s->dev.qdev.id, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
snprintf(s->usbstring_mac, sizeof(s->usbstring_mac),
"%02x%02x%02x%02x%02x%02x",
0x40,
s->conf.macaddr.a[1],
s->conf.macaddr.a[2],
s->conf.macaddr.a[3],
s->conf.macaddr.a[4],
s->conf.macaddr.a[5]);
return 0;
}
static NetClientInfo net_usbnet_info = {
.type = NET_CLIENT_TYPE_NIC,
.size = sizeof(NICState),
.can_receive = usbnet_can_receive,
.receive = usbnet_receive,
.cleanup = usbnet_cleanup,
};
USBDevice *usb_net_init(NICInfo *nd)
static USBDevice *usb_net_init(const char *cmdline)
{
USBDevice *dev;
USBNetState *s;
QemuOpts *opts;
int idx;
dev = usb_create_simple(NULL /* FIXME */, "QEMU USB Network Interface");
s = DO_UPCAST(USBNetState, dev, dev);
opts = qemu_opts_parse(&qemu_net_opts, cmdline, NULL);
if (!opts) {
return NULL;
}
qemu_opt_set(opts, "type", "nic");
qemu_opt_set(opts, "model", "usb");
memcpy(s->conf.macaddr.a, nd->macaddr, sizeof(nd->macaddr));
s->conf.vlan = nd->vlan;
s->conf.peer = nd->netdev;
idx = net_client_init(NULL, opts, 0);
if (idx == -1) {
return NULL;
}
s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
nd->model, nd->name, s);
qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
snprintf(s->usbstring_mac, sizeof(s->usbstring_mac),
"%02x%02x%02x%02x%02x%02x",
0x40, s->conf.macaddr.a[1], s->conf.macaddr.a[2],
s->conf.macaddr.a[3], s->conf.macaddr.a[4], s->conf.macaddr.a[5]);
fprintf(stderr, "usbnet: initialized mac %02x:%02x:%02x:%02x:%02x:%02x\n",
s->conf.macaddr.a[0], s->conf.macaddr.a[1], s->conf.macaddr.a[2],
s->conf.macaddr.a[3], s->conf.macaddr.a[4], s->conf.macaddr.a[5]);
return (USBDevice *) s;
dev = usb_create(NULL /* FIXME */, "usb-net");
qdev_set_nic_properties(&dev->qdev, &nd_table[idx]);
qdev_init(&dev->qdev);
return dev;
}
static struct USBDeviceInfo net_info = {
.qdev.name = "QEMU USB Network Interface",
.product_desc = "QEMU USB Network Interface",
.qdev.name = "usb-net",
.qdev.size = sizeof(USBNetState),
.init = usb_net_initfn,
.handle_packet = usb_generic_handle_packet,
@@ -1495,6 +1506,12 @@ static struct USBDeviceInfo net_info = {
.handle_control = usb_net_handle_control,
.handle_data = usb_net_handle_data,
.handle_destroy = usb_net_handle_destroy,
.usbdevice_name = "net",
.usbdevice_init = usb_net_init,
.qdev.props = (Property[]) {
DEFINE_NIC_PROPERTIES(USBNetState, conf),
DEFINE_PROP_END_OF_LIST(),
}
};
static void usb_net_register_devices(void)

View File

@@ -1736,7 +1736,7 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev)
void usb_ohci_init_pci(struct PCIBus *bus, int devfn)
{
pci_create_simple(bus, devfn, "OHCI USB PCI");
pci_create_simple(bus, devfn, "pci-ohci");
}
void usb_ohci_init_pxa(target_phys_addr_t base, int num_ports, int devfn,
@@ -1762,8 +1762,7 @@ void usb_ohci_init_sm501(uint32_t mmio_base, uint32_t localmem_base,
}
static PCIDeviceInfo ohci_info = {
.qdev.name = "OHCI USB PCI",
.qdev.alias = "pci-ohci",
.qdev.name = "pci-ohci",
.qdev.desc = "Apple USB Controller",
.qdev.size = sizeof(OHCIPCIState),
.init = usb_ohci_initfn_pci,

View File

@@ -577,7 +577,7 @@ static USBDevice *usb_serial_init(const char *filename)
if (!cdrv)
return NULL;
dev = usb_create(NULL /* FIXME */, "QEMU USB Serial");
dev = usb_create(NULL /* FIXME */, "usb-serial");
qdev_prop_set_chr(&dev->qdev, "chardev", cdrv);
if (vendorid)
qdev_prop_set_uint16(&dev->qdev, "vendorid", vendorid);
@@ -597,7 +597,7 @@ static USBDevice *usb_braille_init(const char *unused)
if (!cdrv)
return NULL;
dev = usb_create(NULL /* FIXME */, "QEMU USB Braille");
dev = usb_create(NULL /* FIXME */, "usb-braille");
qdev_prop_set_chr(&dev->qdev, "chardev", cdrv);
qdev_init(&dev->qdev);
@@ -605,8 +605,8 @@ static USBDevice *usb_braille_init(const char *unused)
}
static struct USBDeviceInfo serial_info = {
.qdev.name = "QEMU USB Serial",
.qdev.alias = "usb-serial",
.product_desc = "QEMU USB Serial",
.qdev.name = "usb-serial",
.qdev.size = sizeof(USBSerialState),
.init = usb_serial_initfn,
.handle_packet = usb_generic_handle_packet,
@@ -625,8 +625,8 @@ static struct USBDeviceInfo serial_info = {
};
static struct USBDeviceInfo braille_info = {
.qdev.name = "QEMU USB Braille",
.qdev.alias = "usb-braille",
.product_desc = "QEMU USB Braille",
.qdev.name = "usb-braille",
.qdev.size = sizeof(USBSerialState),
.init = usb_serial_initfn,
.handle_packet = usb_generic_handle_packet,

View File

@@ -1111,12 +1111,12 @@ static int usb_uhci_piix4_initfn(PCIDevice *dev)
static PCIDeviceInfo uhci_info[] = {
{
.qdev.name = "PIIX3 USB-UHCI",
.qdev.name = "piix3-usb-uhci",
.qdev.size = sizeof(UHCIState),
.qdev.vmsd = &vmstate_uhci,
.init = usb_uhci_piix3_initfn,
},{
.qdev.name = "PIIX4 USB-UHCI",
.qdev.name = "piix4-usb-uhci",
.qdev.size = sizeof(UHCIState),
.qdev.vmsd = &vmstate_uhci,
.init = usb_uhci_piix4_initfn,
@@ -1133,10 +1133,10 @@ device_init(uhci_register);
void usb_uhci_piix3_init(PCIBus *bus, int devfn)
{
pci_create_simple(bus, devfn, "PIIX3 USB-UHCI");
pci_create_simple(bus, devfn, "piix3-usb-uhci");
}
void usb_uhci_piix4_init(PCIBus *bus, int devfn)
{
pci_create_simple(bus, devfn, "PIIX4 USB-UHCI");
pci_create_simple(bus, devfn, "piix4-usb-uhci");
}

View File

@@ -409,8 +409,9 @@ static int usb_wacom_initfn(USBDevice *dev)
}
static struct USBDeviceInfo wacom_info = {
.qdev.name = "QEMU PenPartner Tablet",
.qdev.alias = "wacom-tablet",
.product_desc = "QEMU PenPartner Tablet",
.qdev.name = "usb-wacom-tablet",
.qdev.desc = "QEMU PenPartner Tablet",
.usbdevice_name = "wacom-tablet",
.qdev.size = sizeof(USBWacomState),
.init = usb_wacom_initfn,

View File

@@ -132,7 +132,7 @@ struct USBDevice {
int speed;
uint8_t addr;
char devname[32];
char product_desc[32];
int auto_attach;
int attached;
@@ -185,6 +185,8 @@ struct USBDeviceInfo {
*/
int (*handle_data)(USBDevice *dev, USBPacket *p);
const char *product_desc;
/* handle legacy -usbdevice command line options */
const char *usbdevice_name;
USBDevice *(*usbdevice_init)(const char *params);
@@ -256,9 +258,6 @@ void usb_host_info(Monitor *mon);
/* usb-hid.c */
void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *));
/* usb-net.c */
USBDevice *usb_net_init(NICInfo *nd);
/* usb-bt.c */
USBDevice *usb_bt_init(HCIInfo *hci);

View File

@@ -42,11 +42,7 @@ int isa_vga_init(void)
s->ds = graphic_console_init(s->update, s->invalidate,
s->screen_dump, s->text_update, s);
#ifdef CONFIG_BOCHS_VBE
/* XXX: use optimized standard vga accesses */
cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
VGA_RAM_SIZE, s->vram_offset);
#endif
vga_init_vbe(s);
/* ROM BIOS */
rom_add_vga(VGABIOS_FILENAME);
return 0;

View File

@@ -106,12 +106,7 @@ static int pci_vga_initfn(PCIDevice *dev)
PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);
}
#ifdef CONFIG_BOCHS_VBE
/* XXX: use optimized standard vga accesses */
cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
VGA_RAM_SIZE, s->vram_offset);
#endif
vga_init_vbe(s);
/* ROM BIOS */
rom_add_vga(VGABIOS_FILENAME);
return 0;

View File

@@ -1581,6 +1581,14 @@ static void vga_sync_dirty_bitmap(VGACommonState *s)
cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa0000, 0xa8000);
cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000);
}
#ifdef CONFIG_BOCHS_VBE
if (s->vbe_mapped) {
cpu_physical_sync_dirty_bitmap(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
VBE_DISPI_LFB_PHYSICAL_ADDRESS + s->vram_size);
}
#endif
}
void vga_dirty_log_start(VGACommonState *s)
@@ -1592,6 +1600,35 @@ void vga_dirty_log_start(VGACommonState *s)
kvm_log_start(isa_mem_base + 0xa0000, 0x8000);
kvm_log_start(isa_mem_base + 0xa8000, 0x8000);
}
#ifdef CONFIG_BOCHS_VBE
if (kvm_enabled() && s->vbe_mapped) {
kvm_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
}
#endif
}
void vga_dirty_log_stop(VGACommonState *s)
{
if (kvm_enabled() && s->map_addr)
kvm_log_stop(s->map_addr, s->map_end - s->map_addr);
if (kvm_enabled() && s->lfb_vram_mapped) {
kvm_log_stop(isa_mem_base + 0xa0000, 0x80000);
kvm_log_stop(isa_mem_base + 0xa8000, 0x80000);
}
#ifdef CONFIG_BOCHS_VBE
if (kvm_enabled() && s->vbe_mapped) {
kvm_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
}
#endif
}
void vga_dirty_log_restart(VGACommonState *s)
{
vga_dirty_log_stop(s);
vga_dirty_log_start(s);
}
/*
@@ -2294,6 +2331,15 @@ void vga_init(VGACommonState *s)
qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
}
void vga_init_vbe(VGACommonState *s)
{
#ifdef CONFIG_BOCHS_VBE
/* XXX: use optimized standard vga accesses */
cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
VGA_RAM_SIZE, s->vram_offset);
s->vbe_mapped = 1;
#endif
}
/********************************************************/
/* vga screen dump */

View File

@@ -71,8 +71,8 @@
uint16_t vbe_regs[VBE_DISPI_INDEX_NB]; \
uint32_t vbe_start_addr; \
uint32_t vbe_line_offset; \
uint32_t vbe_bank_mask;
uint32_t vbe_bank_mask; \
int vbe_mapped;
#else
#define VGA_STATE_COMMON_BOCHS_VBE
@@ -194,6 +194,8 @@ void vga_init(VGACommonState *s);
void vga_common_reset(VGACommonState *s);
void vga_dirty_log_start(VGACommonState *s);
void vga_dirty_log_stop(VGACommonState *s);
void vga_dirty_log_restart(VGACommonState *s);
extern const VMStateDescription vmstate_vga_common;
uint32_t vga_ioport_read(void *opaque, uint32_t addr);
@@ -217,6 +219,7 @@ void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1,
unsigned int color_xor);
int vga_ioport_invalid(VGACommonState *s, uint32_t addr);
void vga_init_vbe(VGACommonState *s);
extern const uint8_t sr_mask[8];
extern const uint8_t gr_mask[16];

View File

@@ -236,9 +236,7 @@ static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
switch (addr) {
case VIRTIO_PCI_HOST_FEATURES:
ret = vdev->get_features(vdev);
ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
ret |= (1 << VIRTIO_RING_F_INDIRECT_DESC);
ret |= (1 << VIRTIO_F_BAD_FEATURE);
ret |= vdev->binding->get_features(proxy);
break;
case VIRTIO_PCI_GUEST_FEATURES:
ret = vdev->features;
@@ -374,7 +372,7 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
if (PCI_COMMAND == address) {
if (!(val & PCI_COMMAND_MASTER)) {
proxy->vdev->status &= !VIRTIO_CONFIG_S_DRIVER_OK;
proxy->vdev->status &= ~VIRTIO_CONFIG_S_DRIVER_OK;
}
}
@@ -382,12 +380,22 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
msix_write_config(pci_dev, address, val, len);
}
static unsigned virtio_pci_get_features(void *opaque)
{
unsigned ret = 0;
ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
ret |= (1 << VIRTIO_RING_F_INDIRECT_DESC);
ret |= (1 << VIRTIO_F_BAD_FEATURE);
return ret;
}
static const VirtIOBindings virtio_pci_bindings = {
.notify = virtio_pci_notify,
.save_config = virtio_pci_save_config,
.load_config = virtio_pci_load_config,
.save_queue = virtio_pci_save_queue,
.load_queue = virtio_pci_load_queue,
.get_features = virtio_pci_get_features,
};
static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
@@ -510,14 +518,6 @@ static int virtio_net_init_pci(PCIDevice *pci_dev)
/* make the actual value visible */
proxy->nvectors = vdev->nvectors;
if (!pci_dev->qdev.hotplugged) {
static int loaded = 0;
if (!loaded) {
rom_add_option("pxe-virtio.bin");
loaded = 1;
}
}
return 0;
}
@@ -561,6 +561,7 @@ static PCIDeviceInfo virtio_info[] = {
.qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_net_init_pci,
.exit = virtio_net_exit_pci,
.romfile = "pxe-virtio.bin",
.qdev.props = (Property[]) {
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),

View File

@@ -651,6 +651,9 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
int virtio_load(VirtIODevice *vdev, QEMUFile *f)
{
int num, i, ret;
uint32_t features;
uint32_t supported_features = vdev->get_features(vdev) |
vdev->binding->get_features(vdev->binding_opaque);
if (vdev->binding->load_config) {
ret = vdev->binding->load_config(vdev->binding_opaque, f);
@@ -661,7 +664,13 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
qemu_get_8s(f, &vdev->status);
qemu_get_8s(f, &vdev->isr);
qemu_get_be16s(f, &vdev->queue_sel);
qemu_get_be32s(f, &vdev->features);
qemu_get_be32s(f, &features);
if (features & ~supported_features) {
fprintf(stderr, "Features 0x%x unsupported. Allowed features: 0x%x\n",
features, supported_features);
return -1;
}
vdev->features = features;
vdev->config_len = qemu_get_be32(f);
qemu_get_buffer(f, vdev->config, vdev->config_len);

View File

@@ -31,6 +31,11 @@
/* We've given up on this device. */
#define VIRTIO_CONFIG_S_FAILED 0x80
/* Some virtio feature bits (currently bits 28 through 31) are reserved for the
* transport being used (eg. virtio_ring), the rest are per-device feature bits. */
#define VIRTIO_TRANSPORT_F_START 28
#define VIRTIO_TRANSPORT_F_END 32
/* We notify when the ring is completely used, even if the guest is suppressing
* callbacks */
#define VIRTIO_F_NOTIFY_ON_EMPTY 24
@@ -82,6 +87,7 @@ typedef struct {
void (*save_queue)(void * opaque, int n, QEMUFile *f);
int (*load_config)(void * opaque, QEMUFile *f);
int (*load_queue)(void * opaque, int n, QEMUFile *f);
unsigned (*get_features)(void * opaque);
} VirtIOBindings;
#define VIRTIO_PCI_QUEUE_MAX 16

View File

@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
#include "hw.h"
#include "loader.h"
#include "console.h"
#include "pci.h"
#include "vmware_vga.h"
@@ -66,6 +67,11 @@ struct vmsvga_state_s {
int syncing;
int fb_size;
ram_addr_t fifo_offset;
uint8_t *fifo_ptr;
unsigned int fifo_size;
target_phys_addr_t fifo_base;
union {
uint32_t *fifo;
struct __attribute__((__packed__)) {
@@ -461,7 +467,7 @@ struct vmsvga_cursor_definition_s {
int hot_x;
int hot_y;
uint32_t mask[1024];
uint32_t image[1024];
uint32_t image[4096];
};
#define SVGA_BITMAP_SIZE(w, h) ((((w) + 31) >> 5) * (h))
@@ -556,6 +562,13 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
cursor.height = y = vmsvga_fifo_read(s);
vmsvga_fifo_read(s);
cursor.bpp = vmsvga_fifo_read(s);
if (SVGA_BITMAP_SIZE(x, y) > sizeof cursor.mask ||
SVGA_PIXMAP_SIZE(x, y, cursor.bpp) > sizeof cursor.image) {
args = SVGA_BITMAP_SIZE(x, y) + SVGA_PIXMAP_SIZE(x, y, cursor.bpp);
goto badcmd;
}
for (args = 0; args < SVGA_BITMAP_SIZE(x, y); args ++)
cursor.mask[args] = vmsvga_fifo_read_raw(s);
for (args = 0; args < SVGA_PIXMAP_SIZE(x, y, cursor.bpp); args ++)
@@ -679,7 +692,7 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
return 0x0;
case SVGA_REG_VRAM_SIZE:
return s->vga.vram_size - SVGA_FIFO_SIZE;
return s->vga.vram_size;
case SVGA_REG_FB_SIZE:
return s->fb_size;
@@ -700,10 +713,10 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
return caps;
case SVGA_REG_MEM_START:
return s->vram_base + s->vga.vram_size - SVGA_FIFO_SIZE;
return s->fifo_base;
case SVGA_REG_MEM_SIZE:
return SVGA_FIFO_SIZE;
return s->fifo_size;
case SVGA_REG_CONFIG_DONE:
return s->config;
@@ -765,8 +778,12 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
s->height = -1;
s->invalidated = 1;
s->vga.invalidate(&s->vga);
if (s->enable)
s->fb_size = ((s->depth + 7) >> 3) * s->new_width * s->new_height;
if (s->enable) {
s->fb_size = ((s->depth + 7) >> 3) * s->new_width * s->new_height;
vga_dirty_log_stop(&s->vga);
} else {
vga_dirty_log_start(&s->vga);
}
break;
case SVGA_REG_WIDTH:
@@ -789,7 +806,7 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
case SVGA_REG_CONFIG_DONE:
if (value) {
s->fifo = (uint32_t *) &s->vga.vram_ptr[s->vga.vram_size - SVGA_FIFO_SIZE];
s->fifo = (uint32_t *) s->fifo_ptr;
/* Check range and alignment. */
if ((CMD(min) | CMD(max) |
CMD(next_cmd) | CMD(stop)) & 3)
@@ -909,8 +926,8 @@ static void vmsvga_reset(struct vmsvga_state_s *s)
s->width = -1;
s->height = -1;
s->svgaid = SVGA_ID;
s->depth = 24;
s->bypp = (s->depth + 7) >> 3;
s->depth = ds_get_bits_per_pixel(s->vga.ds);
s->bypp = ds_get_bytes_per_pixel(s->vga.ds);
s->cursor.on = 0;
s->redraw_fifo_first = 0;
s->redraw_fifo_last = 0;
@@ -942,6 +959,8 @@ static void vmsvga_reset(struct vmsvga_state_s *s)
break;
}
s->syncing = 0;
vga_dirty_log_start(&s->vga);
}
static void vmsvga_invalidate_display(void *opaque)
@@ -1058,7 +1077,7 @@ static int vmsvga_post_load(void *opaque, int version_id)
s->invalidated = 1;
if (s->config)
s->fifo = (uint32_t *) &s->vga.vram_ptr[s->vga.vram_size - SVGA_FIFO_SIZE];
s->fifo = (uint32_t *) s->fifo_ptr;
return 0;
}
@@ -1108,22 +1127,25 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
s->scratch_size = SVGA_SCRATCH_SIZE;
s->scratch = qemu_malloc(s->scratch_size * 4);
vmsvga_reset(s);
vga_common_init(&s->vga, vga_ram_size);
vga_init(&s->vga);
vmstate_register(0, &vmstate_vga_common, &s->vga);
s->vga.ds = graphic_console_init(vmsvga_update_display,
vmsvga_invalidate_display,
vmsvga_screen_dump,
vmsvga_text_update, s);
#ifdef CONFIG_BOCHS_VBE
/* XXX: use optimized standard vga accesses */
cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
vga_ram_size, s->vga.vram_offset);
#endif
s->fifo_size = SVGA_FIFO_SIZE;
s->fifo_offset = qemu_ram_alloc(s->fifo_size);
s->fifo_ptr = qemu_get_ram_ptr(s->fifo_offset);
vga_common_init(&s->vga, vga_ram_size);
vga_init(&s->vga);
vmstate_register(0, &vmstate_vga_common, &s->vga);
vga_init_vbe(&s->vga);
rom_add_vga(VGABIOS_FILENAME);
vmsvga_reset(s);
}
static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num,
@@ -1162,6 +1184,23 @@ static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num,
#endif
cpu_register_physical_memory(s->vram_base, s->vga.vram_size,
iomemtype);
s->vga.map_addr = addr;
s->vga.map_end = addr + s->vga.vram_size;
vga_dirty_log_restart(&s->vga);
}
static void pci_vmsvga_map_fifo(PCIDevice *pci_dev, int region_num,
pcibus_t addr, pcibus_t size, int type)
{
struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
struct vmsvga_state_s *s = &d->chip;
ram_addr_t iomemtype;
s->fifo_base = addr;
iomemtype = s->fifo_offset | IO_MEM_RAM;
cpu_register_physical_memory(s->fifo_base, s->fifo_size,
iomemtype);
}
static int pci_vmsvga_initfn(PCIDevice *dev)
@@ -1187,6 +1226,9 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
pci_register_bar(&s->card, 1, VGA_RAM_SIZE,
PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_mem);
pci_register_bar(&s->card, 2, SVGA_FIFO_SIZE,
PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_fifo);
vmsvga_init(&s->chip, VGA_RAM_SIZE);
return 0;
@@ -1194,11 +1236,11 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
void pci_vmsvga_init(PCIBus *bus)
{
pci_create_simple(bus, -1, "QEMUware SVGA");
pci_create_simple(bus, -1, "vmware-svga");
}
static PCIDeviceInfo vmsvga_info = {
.qdev.name = "QEMUware SVGA",
.qdev.name = "vmware-svga",
.qdev.size = sizeof(struct pci_vmsvga_state_s),
.qdev.vmsd = &vmstate_vmware_vga,
.init = pci_vmsvga_initfn,

View File

@@ -593,6 +593,7 @@ static int do_strex(CPUARMState *env)
}
rc = 0;
fail:
env->regs[15] += 4;
env->regs[(env->exclusive_info >> 4) & 0xf] = rc;
done:
end_exclusive();

View File

@@ -112,10 +112,6 @@ MigrationState *unix_start_outgoing_migration(Monitor *mon,
socket_set_nonblock(s->fd);
if (!detach) {
migrate_fd_monitor_suspend(s, mon);
}
do {
ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr));
if (ret == -1)
@@ -128,7 +124,13 @@ MigrationState *unix_start_outgoing_migration(Monitor *mon,
if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) {
dprintf("connect failed\n");
goto err_after_open;
} else if (ret >= 0)
}
if (!detach) {
migrate_fd_monitor_suspend(s, mon);
}
if (ret >= 0)
migrate_fd_connect(s);
return &s->mig_state;

View File

@@ -19,6 +19,7 @@
#include "block.h"
#include "qemu_socket.h"
#include "block-migration.h"
#include "qemu-objects.h"
//#define DEBUG_MIGRATION
@@ -105,7 +106,7 @@ void do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data)
s->cancel(s);
}
void do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data)
void do_migrate_set_speed(Monitor *mon, const QDict *qdict)
{
double d;
char *ptr;
@@ -163,37 +164,123 @@ void do_migrate_set_downtime(Monitor *mon, const QDict *qdict)
max_downtime = (uint64_t)d;
}
void do_info_migrate(Monitor *mon)
static void migrate_print_status(Monitor *mon, const char *name,
const QDict *status_dict)
{
QDict *qdict;
qdict = qobject_to_qdict(qdict_get(status_dict, name));
monitor_printf(mon, "transferred %s: %" PRIu64 " kbytes\n", name,
qdict_get_int(qdict, "transferred") >> 10);
monitor_printf(mon, "remaining %s: %" PRIu64 " kbytes\n", name,
qdict_get_int(qdict, "remaining") >> 10);
monitor_printf(mon, "total %s: %" PRIu64 " kbytes\n", name,
qdict_get_int(qdict, "total") >> 10);
}
void do_info_migrate_print(Monitor *mon, const QObject *data)
{
QDict *qdict;
qdict = qobject_to_qdict(data);
monitor_printf(mon, "Migration status: %s\n",
qdict_get_str(qdict, "status"));
if (qdict_haskey(qdict, "ram")) {
migrate_print_status(mon, "ram", qdict);
}
if (qdict_haskey(qdict, "disk")) {
migrate_print_status(mon, "disk", qdict);
}
}
static void migrate_put_status(QDict *qdict, const char *name,
uint64_t trans, uint64_t rem, uint64_t total)
{
QObject *obj;
obj = qobject_from_jsonf("{ 'transferred': %" PRId64 ", "
"'remaining': %" PRId64 ", "
"'total': %" PRId64 " }", trans, rem, total);
assert(obj != NULL);
qdict_put_obj(qdict, name, obj);
}
/**
* do_info_migrate(): Migration status
*
* Return a QDict. If migration is active there will be another
* QDict with RAM migration status and if block migration is active
* another one with block migration status.
*
* The main QDict contains the following:
*
* - "status": migration status
* - "ram": only present if "status" is "active", it is a QDict with the
* following RAM information (in bytes):
* - "transferred": amount transferred
* - "remaining": amount remaining
* - "total": total
* - "disk": only present if "status" is "active" and it is a block migration,
* it is a QDict with the following disk information (in bytes):
* - "transferred": amount transferred
* - "remaining": amount remaining
* - "total": total
*
* Examples:
*
* 1. Migration is "completed":
*
* { "status": "completed" }
*
* 2. Migration is "active" and it is not a block migration:
*
* { "status": "active",
* "ram": { "transferred": 123, "remaining": 123, "total": 246 } }
*
* 3. Migration is "active" and it is a block migration:
*
* { "status": "active",
* "ram": { "total": 1057024, "remaining": 1053304, "transferred": 3720 },
* "disk": { "total": 20971520, "remaining": 20880384, "transferred": 91136 }}
*/
void do_info_migrate(Monitor *mon, QObject **ret_data)
{
QDict *qdict;
MigrationState *s = current_migration;
if (s) {
monitor_printf(mon, "Migration status: ");
switch (s->get_status(s)) {
case MIG_STATE_ACTIVE:
monitor_printf(mon, "active\n");
monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n", ram_bytes_transferred() >> 10);
monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n", ram_bytes_remaining() >> 10);
monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n", ram_bytes_total() >> 10);
qdict = qdict_new();
qdict_put(qdict, "status", qstring_from_str("active"));
migrate_put_status(qdict, "ram", ram_bytes_transferred(),
ram_bytes_remaining(), ram_bytes_total());
if (blk_mig_active()) {
monitor_printf(mon, "transferred disk: %" PRIu64 " kbytes\n",
blk_mig_bytes_transferred() >> 10);
monitor_printf(mon, "remaining disk: %" PRIu64 " kbytes\n",
blk_mig_bytes_remaining() >> 10);
monitor_printf(mon, "total disk: %" PRIu64 " kbytes\n",
blk_mig_bytes_total() >> 10);
migrate_put_status(qdict, "disk", blk_mig_bytes_transferred(),
blk_mig_bytes_remaining(),
blk_mig_bytes_total());
}
*ret_data = QOBJECT(qdict);
break;
case MIG_STATE_COMPLETED:
monitor_printf(mon, "completed\n");
*ret_data = qobject_from_jsonf("{ 'status': 'completed' }");
break;
case MIG_STATE_ERROR:
monitor_printf(mon, "failed\n");
*ret_data = qobject_from_jsonf("{ 'status': 'failed' }");
break;
case MIG_STATE_CANCELLED:
monitor_printf(mon, "cancelled\n");
*ret_data = qobject_from_jsonf("{ 'status': 'cancelled' }");
break;
}
assert(*ret_data != NULL);
}
}

View File

@@ -56,13 +56,15 @@ void do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data);
void do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data);
void do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data);
void do_migrate_set_speed(Monitor *mon, const QDict *qdict);
uint64_t migrate_max_downtime(void);
void do_migrate_set_downtime(Monitor *mon, const QDict *qdict);
void do_info_migrate(Monitor *mon);
void do_info_migrate_print(Monitor *mon, const QObject *data);
void do_info_migrate(Monitor *mon, QObject **ret_data);
int exec_start_incoming_migration(const char *host_port);

463
monitor.c
View File

@@ -140,6 +140,9 @@ static inline int monitor_ctrl_mode(const Monitor *mon)
static void monitor_read_command(Monitor *mon, int show_prompt)
{
if (!mon->rs)
return;
readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL);
if (show_prompt)
readline_show_prompt(mon->rs);
@@ -148,7 +151,10 @@ static void monitor_read_command(Monitor *mon, int show_prompt)
static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
void *opaque)
{
if (mon->rs) {
if (monitor_ctrl_mode(mon)) {
qemu_error_new(QERR_MISSING_PARAMETER, "password");
return -EINVAL;
} else if (mon->rs) {
readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
/* prompt is printed on return from the command handler */
return 0;
@@ -171,9 +177,6 @@ static void monitor_puts(Monitor *mon, const char *str)
{
char c;
if (!mon)
return;
for(;;) {
c = *str++;
if (c == '\0')
@@ -189,6 +192,9 @@ static void monitor_puts(Monitor *mon, const char *str)
void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
{
if (!mon)
return;
if (mon->mc && !mon->mc->print_enabled) {
qemu_error_new(QERR_UNDEFINED_ERROR);
} else {
@@ -254,24 +260,6 @@ static inline int monitor_has_error(const Monitor *mon)
return mon->error != NULL;
}
static void monitor_print_qobject(Monitor *mon, const QObject *data)
{
switch (qobject_type(data)) {
case QTYPE_QSTRING:
monitor_printf(mon, "%s",qstring_get_str(qobject_to_qstring(data)));
break;
case QTYPE_QINT:
monitor_printf(mon, "%" PRId64,qint_get_int(qobject_to_qint(data)));
break;
default:
monitor_printf(mon, "ERROR: unsupported type: %d",
qobject_type(data));
break;
}
monitor_puts(mon, "\n");
}
static void monitor_json_emitter(Monitor *mon, const QObject *data)
{
QString *json;
@@ -298,10 +286,12 @@ static void monitor_protocol_emitter(Monitor *mon, QObject *data)
qobject_incref(data);
qdict_put_obj(qmp, "return", data);
} else {
qdict_put(qmp, "return", qstring_from_str("OK"));
/* return an empty QDict by default */
qdict_put(qmp, "return", qdict_new());
}
} else {
/* error response */
qdict_put(mon->error->error, "desc", qerror_human(mon->error));
qdict_put(qmp, "error", mon->error->error);
QINCREF(mon->error->error);
QDECREF(mon->error);
@@ -375,8 +365,10 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
qmp = qdict_new();
timestamp_put(qmp);
qdict_put(qmp, "event", qstring_from_str(event_name));
if (data)
if (data) {
qobject_incref(data);
qdict_put_obj(qmp, "data", data);
}
monitor_json_emitter(mon, QOBJECT(qmp));
QDECREF(qmp);
@@ -500,24 +492,91 @@ help:
help_cmd(mon, "info");
}
static void do_info_version_print(Monitor *mon, const QObject *data)
{
QDict *qdict;
qdict = qobject_to_qdict(data);
monitor_printf(mon, "%s%s\n", qdict_get_str(qdict, "qemu"),
qdict_get_str(qdict, "package"));
}
/**
* do_info_version(): Show QEMU version
*
* Return a QDict with the following information:
*
* - "qemu": QEMU's version
* - "package": package's version
*
* Example:
*
* { "qemu": "0.11.50", "package": "" }
*/
static void do_info_version(Monitor *mon, QObject **ret_data)
{
*ret_data = QOBJECT(qstring_from_str(QEMU_VERSION QEMU_PKGVERSION));
*ret_data = qobject_from_jsonf("{ 'qemu': %s, 'package': %s }",
QEMU_VERSION, QEMU_PKGVERSION);
}
static void do_info_name(Monitor *mon)
static void do_info_name_print(Monitor *mon, const QObject *data)
{
if (qemu_name)
monitor_printf(mon, "%s\n", qemu_name);
QDict *qdict;
qdict = qobject_to_qdict(data);
if (qdict_size(qdict) == 0) {
return;
}
monitor_printf(mon, "%s\n", qdict_get_str(qdict, "name"));
}
/**
* do_info_name(): Show VM name
*
* Return a QDict with the following information:
*
* - "name": VM's name (optional)
*
* Example:
*
* { "name": "qemu-name" }
*/
static void do_info_name(Monitor *mon, QObject **ret_data)
{
*ret_data = qemu_name ? qobject_from_jsonf("{'name': %s }", qemu_name) :
qobject_from_jsonf("{}");
}
static QObject *get_cmd_dict(const char *name)
{
const char *p;
/* Remove '|' from some commands */
p = strchr(name, '|');
if (p) {
p++;
} else {
p = name;
}
return qobject_from_jsonf("{ 'name': %s }", p);
}
/**
* do_info_commands(): List QMP available commands
*
* Return a QList of QStrings.
* Each command is represented by a QDict, the returned QObject is a QList
* of all commands.
*
* The QDict contains:
*
* - "name": command's name
*
* Example:
*
* { [ { "name": "query-balloon" }, { "name": "system_powerdown" } ] }
*/
static void do_info_commands(Monitor *mon, QObject **ret_data)
{
@@ -528,7 +587,7 @@ static void do_info_commands(Monitor *mon, QObject **ret_data)
for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
if (monitor_handler_ported(cmd) && !compare_cmd(cmd->name, "info")) {
qlist_append(cmd_list, qstring_from_str(cmd->name));
qlist_append_obj(cmd_list, get_cmd_dict(cmd->name));
}
}
@@ -536,7 +595,7 @@ static void do_info_commands(Monitor *mon, QObject **ret_data)
if (monitor_handler_ported(cmd)) {
char buf[128];
snprintf(buf, sizeof(buf), "query-%s", cmd->name);
qlist_append(cmd_list, qstring_from_str(buf));
qlist_append_obj(cmd_list, get_cmd_dict(buf));
}
}
@@ -544,20 +603,56 @@ static void do_info_commands(Monitor *mon, QObject **ret_data)
}
#if defined(TARGET_I386)
static void do_info_hpet(Monitor *mon)
static void do_info_hpet_print(Monitor *mon, const QObject *data)
{
monitor_printf(mon, "HPET is %s by QEMU\n",
(no_hpet) ? "disabled" : "enabled");
qdict_get_bool(qobject_to_qdict(data), "enabled") ?
"enabled" : "disabled");
}
/**
* do_info_hpet(): Show HPET state
*
* Return a QDict with the following information:
*
* - "enabled": true if hpet if enabled, false otherwise
*
* Example:
*
* { "enabled": true }
*/
static void do_info_hpet(Monitor *mon, QObject **ret_data)
{
*ret_data = qobject_from_jsonf("{ 'enabled': %i }", !no_hpet);
}
#endif
static void do_info_uuid(Monitor *mon)
static void do_info_uuid_print(Monitor *mon, const QObject *data)
{
monitor_printf(mon, UUID_FMT "\n", qemu_uuid[0], qemu_uuid[1],
monitor_printf(mon, "%s\n", qdict_get_str(qobject_to_qdict(data), "UUID"));
}
/**
* do_info_uuid(): Show VM UUID
*
* Return a QDict with the following information:
*
* - "UUID": Universally Unique Identifier
*
* Example:
*
* { "UUID": "550e8400-e29b-41d4-a716-446655440000" }
*/
static void do_info_uuid(Monitor *mon, QObject **ret_data)
{
char uuid[64];
snprintf(uuid, sizeof(uuid), UUID_FMT, qemu_uuid[0], qemu_uuid[1],
qemu_uuid[2], qemu_uuid[3], qemu_uuid[4], qemu_uuid[5],
qemu_uuid[6], qemu_uuid[7], qemu_uuid[8], qemu_uuid[9],
qemu_uuid[10], qemu_uuid[11], qemu_uuid[12], qemu_uuid[13],
qemu_uuid[14], qemu_uuid[15]);
*ret_data = qobject_from_jsonf("{ 'UUID': %s }", uuid);
}
/* get the current CPU defined by the user */
@@ -607,8 +702,9 @@ static void print_cpu_iter(QObject *obj, void *opaque)
assert(qobject_type(obj) == QTYPE_QDICT);
cpu = qobject_to_qdict(obj);
if (strcmp(qdict_get_str(cpu, "current"), "yes") == 0)
if (qdict_get_bool(cpu, "current")) {
active = '*';
}
monitor_printf(mon, "%c CPU #%d: ", active, (int)qdict_get_int(cpu, "CPU"));
@@ -628,8 +724,9 @@ static void print_cpu_iter(QObject *obj, void *opaque)
(target_long) qdict_get_int(cpu, "PC"));
#endif
if (strcmp(qdict_get_str(cpu, "halted"), "yes") == 0)
if (qdict_get_bool(cpu, "halted")) {
monitor_printf(mon, " (halted)");
}
monitor_printf(mon, "\n");
}
@@ -646,12 +743,21 @@ static void monitor_print_cpus(Monitor *mon, const QObject *data)
/**
* do_info_cpus(): Show CPU information
*
* Return a QList with a QDict for each CPU.
* Return a QList. Each CPU is represented by a QDict, which contains:
*
* For example:
* - "cpu": CPU index
* - "current": true if this is the current CPU, false otherwise
* - "halted": true if the cpu is halted, false otherwise
* - Current program counter. The key's name depends on the architecture:
* "pc": i386/x86)64
* "nip": PPC
* "pc" and "npc": sparc
* "PC": mips
*
* [ { "CPU": 0, "current": "yes", "pc": 0x..., "halted": "no" },
* { "CPU": 1, "current": "no", "pc": 0x..., "halted": "yes" } ]
* Example:
*
* [ { "CPU": 0, "current": true, "halted": false, "pc": 3227107138 },
* { "CPU": 1, "current": false, "halted": true, "pc": 7108165 } ]
*/
static void do_info_cpus(Monitor *mon, QObject **ret_data)
{
@@ -664,14 +770,17 @@ static void do_info_cpus(Monitor *mon, QObject **ret_data)
mon_get_cpu();
for(env = first_cpu; env != NULL; env = env->next_cpu) {
const char *answer;
QDict *cpu = qdict_new();
QDict *cpu;
QObject *obj;
cpu_synchronize_state(env);
qdict_put(cpu, "CPU", qint_from_int(env->cpu_index));
answer = (env == mon->mon_cpu) ? "yes" : "no";
qdict_put(cpu, "current", qstring_from_str(answer));
obj = qobject_from_jsonf("{ 'CPU': %d, 'current': %i, 'halted': %i }",
env->cpu_index, env == mon->mon_cpu,
env->halted);
assert(obj != NULL);
cpu = qobject_to_qdict(obj);
#if defined(TARGET_I386)
qdict_put(cpu, "pc", qint_from_int(env->eip + env->segs[R_CS].base));
@@ -683,8 +792,6 @@ static void do_info_cpus(Monitor *mon, QObject **ret_data)
#elif defined(TARGET_MIPS)
qdict_put(cpu, "PC", qint_from_int(env->active_tc.PC));
#endif
answer = env->halted ? "yes" : "no";
qdict_put(cpu, "halted", qstring_from_str(answer));
qlist_append(cpu_list, cpu);
}
@@ -745,11 +852,12 @@ static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
if (bdrv_is_inserted(bs)) {
if (!force) {
if (!bdrv_is_removable(bs)) {
monitor_printf(mon, "device is not removable\n");
qemu_error_new(QERR_DEVICE_NOT_REMOVABLE,
bdrv_get_device_name(bs));
return -1;
}
if (bdrv_is_locked(bs)) {
monitor_printf(mon, "device is locked\n");
qemu_error_new(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
return -1;
}
}
@@ -762,16 +870,32 @@ static void do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
BlockDriverState *bs;
int force = qdict_get_int(qdict, "force");
const char *filename = qdict_get_str(qdict, "filename");
const char *filename = qdict_get_str(qdict, "device");
bs = bdrv_find(filename);
if (!bs) {
monitor_printf(mon, "device not found\n");
qemu_error_new(QERR_DEVICE_NOT_FOUND, filename);
return;
}
eject_device(mon, bs, force);
}
static void do_block_set_passwd(Monitor *mon, const QDict *qdict,
QObject **ret_data)
{
BlockDriverState *bs;
bs = bdrv_find(qdict_get_str(qdict, "device"));
if (!bs) {
qemu_error_new(QERR_DEVICE_NOT_FOUND, qdict_get_str(qdict, "device"));
return;
}
if (bdrv_set_key(bs, qdict_get_str(qdict, "password")) < 0) {
qemu_error_new(QERR_INVALID_PASSWORD);
}
}
static void do_change_block(Monitor *mon, const char *device,
const char *filename, const char *fmt)
{
@@ -780,13 +904,13 @@ static void do_change_block(Monitor *mon, const char *device,
bs = bdrv_find(device);
if (!bs) {
monitor_printf(mon, "device not found\n");
qemu_error_new(QERR_DEVICE_NOT_FOUND, device);
return;
}
if (fmt) {
drv = bdrv_find_whitelisted_format(fmt);
if (!drv) {
monitor_printf(mon, "invalid format %s\n", fmt);
qemu_error_new(QERR_INVALID_BLOCK_FORMAT, fmt);
return;
}
}
@@ -796,12 +920,17 @@ static void do_change_block(Monitor *mon, const char *device,
monitor_read_bdrv_key_start(mon, bs, NULL, NULL);
}
static void change_vnc_password(const char *password)
{
if (vnc_display_password(NULL, password) < 0)
qemu_error_new(QERR_SET_PASSWD_FAILED);
}
static void change_vnc_password_cb(Monitor *mon, const char *password,
void *opaque)
{
if (vnc_display_password(NULL, password) < 0)
monitor_printf(mon, "could not set VNC server password\n");
change_vnc_password(password);
monitor_read_command(mon, 1);
}
@@ -813,17 +942,20 @@ static void do_change_vnc(Monitor *mon, const char *target, const char *arg)
char password[9];
strncpy(password, arg, sizeof(password));
password[sizeof(password) - 1] = '\0';
change_vnc_password_cb(mon, password, NULL);
change_vnc_password(password);
} else {
monitor_read_password(mon, change_vnc_password_cb, NULL);
}
} else {
if (vnc_display_open(NULL, target) < 0)
monitor_printf(mon, "could not start VNC server on %s\n", target);
qemu_error_new(QERR_VNC_SERVER_FAILED, target);
}
}
static void do_change(Monitor *mon, const QDict *qdict)
/**
* do_change(): Change a removable medium, or VNC configuration
*/
static void do_change(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
const char *device = qdict_get_str(qdict, "device");
const char *target = qdict_get_str(qdict, "target");
@@ -1739,16 +1871,40 @@ static void tlb_info(Monitor *mon)
#endif
static void do_info_kvm(Monitor *mon)
static void do_info_kvm_print(Monitor *mon, const QObject *data)
{
QDict *qdict;
qdict = qobject_to_qdict(data);
monitor_printf(mon, "kvm support: ");
if (qdict_get_bool(qdict, "present")) {
monitor_printf(mon, "%s\n", qdict_get_bool(qdict, "enabled") ?
"enabled" : "disabled");
} else {
monitor_printf(mon, "not compiled\n");
}
}
/**
* do_info_kvm(): Show KVM information
*
* Return a QDict with the following information:
*
* - "enabled": true if KVM support is enabled, false otherwise
* - "present": true if QEMU has KVM support, false otherwise
*
* Example:
*
* { "enabled": true, "present": true }
*/
static void do_info_kvm(Monitor *mon, QObject **ret_data)
{
#ifdef CONFIG_KVM
monitor_printf(mon, "kvm support: ");
if (kvm_enabled())
monitor_printf(mon, "enabled\n");
else
monitor_printf(mon, "disabled\n");
*ret_data = qobject_from_jsonf("{ 'enabled': %i, 'present': true }",
kvm_enabled());
#else
monitor_printf(mon, "kvm support: not compiled\n");
*ret_data = qobject_from_jsonf("{ 'enabled': false, 'present': false }");
#endif
}
@@ -1866,16 +2022,59 @@ static void do_inject_nmi(Monitor *mon, const QDict *qdict)
}
#endif
static void do_info_status(Monitor *mon)
static void do_info_status_print(Monitor *mon, const QObject *data)
{
if (vm_running) {
if (singlestep) {
monitor_printf(mon, "VM status: running (single step mode)\n");
} else {
monitor_printf(mon, "VM status: running\n");
QDict *qdict;
qdict = qobject_to_qdict(data);
monitor_printf(mon, "VM status: ");
if (qdict_get_bool(qdict, "running")) {
monitor_printf(mon, "running");
if (qdict_get_bool(qdict, "singlestep")) {
monitor_printf(mon, " (single step mode)");
}
} else
monitor_printf(mon, "VM status: paused\n");
} else {
monitor_printf(mon, "paused");
}
monitor_printf(mon, "\n");
}
/**
* do_info_status(): VM status
*
* Return a QDict with the following information:
*
* - "running": true if the VM is running, or false if it is paused
* - "singlestep": true if the VM is in single step mode, false otherwise
*
* Example:
*
* { "running": true, "singlestep": false }
*/
static void do_info_status(Monitor *mon, QObject **ret_data)
{
*ret_data = qobject_from_jsonf("{ 'running': %i, 'singlestep': %i }",
vm_running, singlestep);
}
static ram_addr_t balloon_get_value(void)
{
ram_addr_t actual;
if (kvm_enabled() && !kvm_has_sync_mmu()) {
qemu_error_new(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
return 0;
}
actual = qemu_balloon_status();
if (actual == 0) {
qemu_error_new(QERR_DEVICE_NOT_ACTIVE, "balloon");
return 0;
}
return actual;
}
/**
@@ -1883,31 +2082,42 @@ static void do_info_status(Monitor *mon)
*/
static void do_balloon(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
int value = qdict_get_int(qdict, "value");
ram_addr_t target = value;
qemu_balloon(target << 20);
if (balloon_get_value()) {
/* ballooning is active */
qemu_balloon(qdict_get_int(qdict, "value"));
}
}
static void monitor_print_balloon(Monitor *mon, const QObject *data)
{
monitor_printf(mon, "balloon: actual=%d\n",
(int)qint_get_int(qobject_to_qint(data)));
QDict *qdict;
qdict = qobject_to_qdict(data);
monitor_printf(mon, "balloon: actual=%" PRId64 "\n",
qdict_get_int(qdict, "balloon") >> 20);
}
/**
* do_info_balloon(): Balloon information
*
* Return a QDict with the following information:
*
* - "balloon": current balloon value in bytes
*
* Example:
*
* { "balloon": 1073741824 }
*/
static void do_info_balloon(Monitor *mon, QObject **ret_data)
{
ram_addr_t actual;
actual = qemu_balloon_status();
if (kvm_enabled() && !kvm_has_sync_mmu())
qemu_error_new(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
else if (actual == 0)
qemu_error_new(QERR_DEVICE_NOT_ACTIVE, "balloon");
else
*ret_data = QOBJECT(qint_from_int((int)(actual >> 20)));
actual = balloon_get_value();
if (actual != 0) {
*ret_data = qobject_from_jsonf("{ 'balloon': %" PRId64 "}",
(int64_t) actual);
}
}
static qemu_acl *find_acl(Monitor *mon, const char *name)
@@ -2043,19 +2253,21 @@ static void do_getfd(Monitor *mon, const QDict *qdict, QObject **ret_data)
fd = qemu_chr_get_msgfd(mon->chr);
if (fd == -1) {
monitor_printf(mon, "getfd: no file descriptor supplied via SCM_RIGHTS\n");
qemu_error_new(QERR_FD_NOT_SUPPLIED);
return;
}
if (qemu_isdigit(fdname[0])) {
monitor_printf(mon, "getfd: monitor names may not begin with a number\n");
qemu_error_new(QERR_INVALID_PARAMETER, "fdname");
return;
}
fd = dup(fd);
if (fd == -1) {
monitor_printf(mon, "Failed to dup() file descriptor: %s\n",
strerror(errno));
if (errno == EMFILE)
qemu_error_new(QERR_TOO_MANY_FILES);
else
qemu_error_new(QERR_UNDEFINED_ERROR);
return;
}
@@ -2093,8 +2305,7 @@ static void do_closefd(Monitor *mon, const QDict *qdict, QObject **ret_data)
return;
}
monitor_printf(mon, "Failed to find file descriptor named %s\n",
fdname);
qemu_error_new(QERR_FD_NOT_FOUND, fdname);
}
static void do_loadvm(Monitor *mon, const QDict *qdict)
@@ -2144,7 +2355,7 @@ static const mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show the version of QEMU",
.user_print = monitor_print_qobject,
.user_print = do_info_version_print,
.mhandler.info_new = do_info_version,
},
{
@@ -2167,21 +2378,24 @@ static const mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show the character devices",
.mhandler.info = qemu_chr_info,
.user_print = qemu_chr_info_print,
.mhandler.info_new = qemu_chr_info,
},
{
.name = "block",
.args_type = "",
.params = "",
.help = "show the block devices",
.mhandler.info = bdrv_info,
.user_print = bdrv_info_print,
.mhandler.info_new = bdrv_info,
},
{
.name = "blockstats",
.args_type = "",
.params = "",
.help = "show block device statistics",
.mhandler.info = bdrv_info_stats,
.user_print = bdrv_stats_print,
.mhandler.info_new = bdrv_info_stats,
},
{
.name = "registers",
@@ -2248,7 +2462,8 @@ static const mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show state of HPET",
.mhandler.info = do_info_hpet,
.user_print = do_info_hpet_print,
.mhandler.info_new = do_info_hpet,
},
#endif
{
@@ -2263,7 +2478,8 @@ static const mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show KVM information",
.mhandler.info = do_info_kvm,
.user_print = do_info_kvm_print,
.mhandler.info_new = do_info_kvm,
},
{
.name = "numa",
@@ -2312,7 +2528,8 @@ static const mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show the current VM status (running|paused)",
.mhandler.info = do_info_status,
.user_print = do_info_status_print,
.mhandler.info_new = do_info_status,
},
{
.name = "pcmcia",
@@ -2326,28 +2543,32 @@ static const mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show which guest mouse is receiving events",
.mhandler.info = do_info_mice,
.user_print = do_info_mice_print,
.mhandler.info_new = do_info_mice,
},
{
.name = "vnc",
.args_type = "",
.params = "",
.help = "show the vnc server status",
.mhandler.info = do_info_vnc,
.user_print = do_info_vnc_print,
.mhandler.info_new = do_info_vnc,
},
{
.name = "name",
.args_type = "",
.params = "",
.help = "show the current VM name",
.mhandler.info = do_info_name,
.user_print = do_info_name_print,
.mhandler.info_new = do_info_name,
},
{
.name = "uuid",
.args_type = "",
.params = "",
.help = "show the current VM UUID",
.mhandler.info = do_info_uuid,
.user_print = do_info_uuid_print,
.mhandler.info_new = do_info_uuid,
},
#if defined(TARGET_PPC)
{
@@ -2372,7 +2593,8 @@ static const mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show migration status",
.mhandler.info = do_info_migrate,
.user_print = do_info_migrate_print,
.mhandler.info_new = do_info_migrate,
},
{
.name = "balloon",
@@ -3279,6 +3501,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
break;
case 'i':
case 'l':
case 'M':
{
int64_t val;
@@ -3309,6 +3532,8 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
monitor_printf(mon, "\'%s\' has failed: ", cmdname);
monitor_printf(mon, "integer is for 32-bit values\n");
goto fail;
} else if (c == 'M') {
val <<= 20;
}
qdict_put(qdict, key, qint_from_int(val));
}
@@ -3644,7 +3869,7 @@ static int monitor_can_read(void *opaque)
{
Monitor *mon = opaque;
return (mon->suspend_cnt == 0) ? 128 : 0;
return (mon->suspend_cnt == 0) ? 1 : 0;
}
typedef struct CmdArgs {
@@ -3713,6 +3938,7 @@ static int check_arg(const CmdArgs *cmd_args, QDict *args)
}
case 'i':
case 'l':
case 'M':
if (qobject_type(value) != QTYPE_QINT) {
qemu_error_new(QERR_INVALID_PARAMETER_TYPE, name, "int");
return -1;
@@ -3850,7 +4076,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
qobject_from_jsonf("{ 'item': %s }", info_item));
} else {
cmd = monitor_find_command(cmd_name);
if (!cmd) {
if (!cmd || !monitor_handler_ported(cmd)) {
qemu_error_new(QERR_COMMAND_NOT_FOUND, cmd_name);
goto err_input;
}
@@ -4008,24 +4234,6 @@ static void monitor_event(void *opaque, int event)
* End:
*/
const char *monitor_cmdline_parse(const char *cmdline, int *flags)
{
const char *dev;
if (strstart(cmdline, "control,", &dev)) {
if (strstart(dev, "vc", NULL)) {
fprintf(stderr, "qemu: control mode is for low-level interaction ");
fprintf(stderr, "cannot be used with device 'vc'\n");
exit(1);
}
*flags &= ~MONITOR_USE_READLINE;
*flags |= MONITOR_USE_CONTROL;
return dev;
}
return cmdline;
}
void monitor_init(CharDriverState *chr, int flags)
{
static int is_first_init = 1;
@@ -4087,6 +4295,11 @@ void monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
return;
}
if (monitor_ctrl_mode(mon)) {
qemu_error_new(QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs));
return;
}
monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
bdrv_get_encrypted_filename(bs));

View File

@@ -24,7 +24,6 @@ typedef enum MonitorEvent {
} MonitorEvent;
void monitor_protocol_event(MonitorEvent event, QObject *data);
const char *monitor_cmdline_parse(const char *cmdline, int *flags);
void monitor_init(CharDriverState *chr, int flags);
int monitor_suspend(Monitor *mon);

5
net.c
View File

@@ -39,6 +39,8 @@
static QTAILQ_HEAD(, VLANState) vlans;
static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
int default_net = 1;
/***********************************************************/
/* network device redirectors */
@@ -1317,7 +1319,7 @@ static int net_init_netdev(QemuOpts *opts, void *dummy)
int net_init_clients(void)
{
if (QTAILQ_EMPTY(&qemu_net_opts.head)) {
if (default_net) {
/* if no clients, we use a default config */
qemu_opts_set(&qemu_net_opts, NULL, "type", "nic");
#ifdef CONFIG_SLIRP
@@ -1353,5 +1355,6 @@ int net_client_parse(QemuOptsList *opts_list, const char *optarg)
return -1;
}
default_net = 0;
return 0;
}

1
net.h
View File

@@ -139,6 +139,7 @@ struct NICInfo {
extern int nb_nics;
extern NICInfo nd_table[MAX_NICS];
extern int default_net;
/* BT HCI info */

18
osdep.c
View File

@@ -262,13 +262,15 @@ int qemu_pipe(int pipefd[2])
#ifdef CONFIG_PIPE2
ret = pipe2(pipefd, O_CLOEXEC);
#else
if (ret != -1 || errno != ENOSYS) {
return ret;
}
#endif
ret = pipe(pipefd);
if (ret == 0) {
qemu_set_cloexec(pipefd[0]);
qemu_set_cloexec(pipefd[1]);
}
#endif
return ret;
}
@@ -283,12 +285,14 @@ int qemu_socket(int domain, int type, int protocol)
#ifdef SOCK_CLOEXEC
ret = socket(domain, type | SOCK_CLOEXEC, protocol);
#else
if (ret != -1 || errno != EINVAL) {
return ret;
}
#endif
ret = socket(domain, type, protocol);
if (ret >= 0) {
qemu_set_cloexec(ret);
}
#endif
return ret;
}
@@ -302,12 +306,14 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
#ifdef CONFIG_ACCEPT4
ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
#else
if (ret != -1 || errno != ENOSYS) {
return ret;
}
#endif
ret = accept(s, addr, addrlen);
if (ret >= 0) {
qemu_set_cloexec(ret);
}
#endif
return ret;
}

View File

@@ -1,4 +1,5 @@
- The PC BIOS comes from the Bochs project (http://bochs.sourceforge.net/).
- SeaBIOS (bios.bin) is the successor of pc bios.
See http://www.seabios.org/ for more information.
- The VGA BIOS and the Cirrus VGA BIOS come from the LGPL VGA bios
project (http://www.nongnu.org/vgabios/).

Binary file not shown.

BIN
pc-bios/openbios-ppc Executable file → Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -79,24 +79,21 @@ copy_kernel:
mode, so let's get into 32 bit mode, write the kernel and jump
back again. */
/* Set DS to SS+SP - 0x10, so we can write our GDT descriptor there */
mov %ss, %eax
shl $4, %eax
add %esp, %eax
sub $0x10, %eax
shr $4, %eax
/* Reserve space on the stack for our GDT descriptor. */
mov %esp, %ebp
sub $16, %esp
/* Now create the GDT descriptor */
movw $((3 * 8) - 1), -16(%bp)
mov %cs, %eax
movzwl %ax, %eax
shl $4, %eax
movw $((3 * 8) - 1), %bx
movw %bx, %gs:0
movl $gdt, %ebx
add %eax, %ebx
movl %ebx, %gs:2
addl $gdt, %eax
movl %eax, -14(%bp)
/* And load the GDT */
data32 lgdt %gs:0
data32 lgdt -16(%bp)
mov %ebp, %esp
/* Get us to protected mode now */
mov $1, %eax

Binary file not shown.

31
qdict.c
View File

@@ -12,6 +12,7 @@
#include "qint.h"
#include "qdict.h"
#include "qbool.h"
#include "qstring.h"
#include "qobject.h"
#include "qemu-queue.h"
@@ -121,9 +122,8 @@ void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
/* allocate a new entry */
entry = alloc_entry(key, value);
QLIST_INSERT_HEAD(&qdict->table[hash], entry, next);
qdict->size++;
}
qdict->size++;
}
/**
@@ -188,6 +188,33 @@ int64_t qdict_get_int(const QDict *qdict, const char *key)
return qint_get_int(qobject_to_qint(obj));
}
/**
* qdict_get_bool(): Get a bool mapped by 'key'
*
* This function assumes that 'key' exists and it stores a
* QBool object.
*
* Return bool mapped by 'key'.
*/
int qdict_get_bool(const QDict *qdict, const char *key)
{
QObject *obj = qdict_get_obj(qdict, key, QTYPE_QBOOL);
return qbool_get_int(qobject_to_qbool(obj));
}
/**
* qdict_get_qlist(): Get the QList mapped by 'key'
*
* This function assumes that 'key' exists and it stores a
* QList object.
*
* Return QList mapped by 'key'.
*/
QList *qdict_get_qlist(const QDict *qdict, const char *key)
{
return qobject_to_qlist(qdict_get_obj(qdict, key, QTYPE_QLIST));
}
/**
* qdict_get_str(): Get a pointer to the stored string mapped
* by 'key'

View File

@@ -2,6 +2,7 @@
#define QDICT_H
#include "qobject.h"
#include "qlist.h"
#include "qemu-queue.h"
#include <stdint.h>
@@ -37,6 +38,8 @@ void qdict_iter(const QDict *qdict,
/* High level helpers */
int64_t qdict_get_int(const QDict *qdict, const char *key);
int qdict_get_bool(const QDict *qdict, const char *key);
QList *qdict_get_qlist(const QDict *qdict, const char *key);
const char *qdict_get_str(const QDict *qdict, const char *key);
int64_t qdict_get_try_int(const QDict *qdict, const char *key,
int64_t err_value);

View File

@@ -32,6 +32,7 @@
#include "hw/usb.h"
#include "hw/baum.h"
#include "hw/msmouse.h"
#include "qemu-objects.h"
#include <unistd.h>
#include <fcntl.h>
@@ -2231,7 +2232,7 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
return NULL;
}
static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
{
char host[65], port[33], width[8], height[8];
int pos;
@@ -2469,13 +2470,51 @@ void qemu_chr_close(CharDriverState *chr)
qemu_free(chr);
}
void qemu_chr_info(Monitor *mon)
static void qemu_chr_qlist_iter(QObject *obj, void *opaque)
{
QDict *chr_dict;
Monitor *mon = opaque;
chr_dict = qobject_to_qdict(obj);
monitor_printf(mon, "%s: filename=%s\n", qdict_get_str(chr_dict, "label"),
qdict_get_str(chr_dict, "filename"));
}
void qemu_chr_info_print(Monitor *mon, const QObject *ret_data)
{
qlist_iter(qobject_to_qlist(ret_data), qemu_chr_qlist_iter, mon);
}
/**
* qemu_chr_info(): Character devices information
*
* Each device is represented by a QDict. The returned QObject is a QList
* of all devices.
*
* The QDict contains the following:
*
* - "label": device's label
* - "filename": device's file
*
* Example:
*
* [ { "label": "monitor", "filename", "stdio" },
* { "label": "serial0", "filename": "vc" } ]
*/
void qemu_chr_info(Monitor *mon, QObject **ret_data)
{
QList *chr_list;
CharDriverState *chr;
chr_list = qlist_new();
QTAILQ_FOREACH(chr, &chardevs, next) {
monitor_printf(mon, "%s: filename=%s\n", chr->label, chr->filename);
QObject *obj = qobject_from_jsonf("{ 'label': %s, 'filename': %s }",
chr->label, chr->filename);
qlist_append_obj(chr_list, obj);
}
*ret_data = QOBJECT(chr_list);
}
CharDriverState *qemu_chr_find(const char *name)

View File

@@ -5,6 +5,7 @@
#include "qemu-queue.h"
#include "qemu-option.h"
#include "qemu-config.h"
#include "qobject.h"
/* character device */
@@ -69,6 +70,7 @@ struct CharDriverState {
QTAILQ_ENTRY(CharDriverState) next;
};
QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
void (*init)(struct CharDriverState *s));
CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
@@ -87,7 +89,8 @@ int qemu_chr_can_read(CharDriverState *s);
void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
int qemu_chr_get_msgfd(CharDriverState *s);
void qemu_chr_accept_input(CharDriverState *s);
void qemu_chr_info(Monitor *mon);
void qemu_chr_info_print(Monitor *mon, const QObject *ret_data);
void qemu_chr_info(Monitor *mon, QObject **ret_data);
CharDriverState *qemu_chr_find(const char *name);
extern int term_escape_char;

View File

@@ -2,6 +2,7 @@
#include "qemu-option.h"
#include "qemu-config.h"
#include "sysemu.h"
#include "hw/qdev.h"
QemuOptsList qemu_drive_opts = {
.name = "drive",
@@ -205,6 +206,42 @@ QemuOptsList qemu_rtc_opts = {
},
};
QemuOptsList qemu_global_opts = {
.name = "global",
.head = QTAILQ_HEAD_INITIALIZER(qemu_global_opts.head),
.desc = {
{
.name = "driver",
.type = QEMU_OPT_STRING,
},{
.name = "property",
.type = QEMU_OPT_STRING,
},{
.name = "value",
.type = QEMU_OPT_STRING,
},
{ /* end if list */ }
},
};
QemuOptsList qemu_mon_opts = {
.name = "mon",
.head = QTAILQ_HEAD_INITIALIZER(qemu_mon_opts.head),
.desc = {
{
.name = "mode",
.type = QEMU_OPT_STRING,
},{
.name = "chardev",
.type = QEMU_OPT_STRING,
},{
.name = "default",
.type = QEMU_OPT_BOOL,
},
{ /* end if list */ }
},
};
static QemuOptsList *lists[] = {
&qemu_drive_opts,
&qemu_chardev_opts,
@@ -212,6 +249,8 @@ static QemuOptsList *lists[] = {
&qemu_netdev_opts,
&qemu_net_opts,
&qemu_rtc_opts,
&qemu_global_opts,
&qemu_mon_opts,
NULL,
};
@@ -260,6 +299,42 @@ int qemu_set_option(const char *str)
return 0;
}
int qemu_global_option(const char *str)
{
char driver[64], property[64];
QemuOpts *opts;
int rc, offset;
rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset);
if (rc < 2 || str[offset] != '=') {
qemu_error("can't parse: \"%s\"\n", str);
return -1;
}
opts = qemu_opts_create(&qemu_global_opts, NULL, 0);
qemu_opt_set(opts, "driver", driver);
qemu_opt_set(opts, "property", property);
qemu_opt_set(opts, "value", str+offset+1);
return 0;
}
static int qemu_add_one_global(QemuOpts *opts, void *opaque)
{
GlobalProperty *g;
g = qemu_mallocz(sizeof(*g));
g->driver = qemu_opt_get(opts, "driver");
g->property = qemu_opt_get(opts, "property");
g->value = qemu_opt_get(opts, "value");
qdev_prop_register_global(g);
return 0;
}
void qemu_add_globals(void)
{
qemu_opts_foreach(&qemu_global_opts, qemu_add_one_global, NULL, 0);
}
struct ConfigWriteData {
QemuOptsList *list;
FILE *fp;

View File

@@ -7,8 +7,12 @@ extern QemuOptsList qemu_device_opts;
extern QemuOptsList qemu_netdev_opts;
extern QemuOptsList qemu_net_opts;
extern QemuOptsList qemu_rtc_opts;
extern QemuOptsList qemu_global_opts;
extern QemuOptsList qemu_mon_opts;
int qemu_set_option(const char *str);
int qemu_global_option(const char *str);
void qemu_add_globals(void);
void qemu_config_write(FILE *fp);
int qemu_config_parse(FILE *fp);

View File

@@ -129,7 +129,8 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
{
size_t *sizes = calloc(nr_iov, sizeof(size_t));
size_t count = 0;
void *buf, *p;
void *buf = NULL;
void *p;
int i;
for (i = 0; i < nr_iov; i++) {
@@ -139,19 +140,19 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
len = cvtnum(arg);
if (len < 0) {
printf("non-numeric length argument -- %s\n", arg);
return NULL;
goto fail;
}
/* should be SIZE_T_MAX, but that doesn't exist */
if (len > UINT_MAX) {
printf("too large length argument -- %s\n", arg);
return NULL;
goto fail;
}
if (len & 0x1ff) {
printf("length argument %lld is not sector aligned\n",
len);
return NULL;
goto fail;
}
sizes[i] = len;
@@ -167,6 +168,7 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
p += sizes[i];
}
fail:
free(sizes);
return buf;
}

View File

@@ -42,22 +42,29 @@ void qemu_free(void *ptr)
free(ptr);
}
static int allow_zero_malloc(void)
{
#if defined(CONFIG_ZERO_MALLOC)
return 1;
#else
return 0;
#endif
}
void *qemu_malloc(size_t size)
{
if (!size) {
if (!size && !allow_zero_malloc()) {
abort();
}
return oom_check(malloc(size));
return oom_check(malloc(size ? size : 1));
}
void *qemu_realloc(void *ptr, size_t size)
{
if (size) {
return oom_check(realloc(ptr, size));
} else {
if (ptr) {
return realloc(ptr, size);
}
} else if (allow_zero_malloc()) {
return oom_check(realloc(ptr, size ? size : 1));
}
abort();
}

View File

@@ -130,7 +130,7 @@ ETEXI
{
.name = "eject",
.args_type = "force:-f,filename:B",
.args_type = "force:-f,device:B",
.params = "[-f] device",
.help = "eject a removable medium (use -f to force it)",
.user_print = monitor_user_noop,
@@ -147,7 +147,8 @@ ETEXI
.args_type = "device:B,target:F,arg:s?",
.params = "device filename [format]",
.help = "change a removable medium, optional format",
.mhandler.cmd = do_change,
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_change,
},
STEXI
@@ -762,8 +763,7 @@ ETEXI
.args_type = "value:s",
.params = "value",
.help = "set maximum speed (in bytes) for migrations",
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_migrate_set_speed,
.mhandler.cmd = do_migrate_set_speed,
},
STEXI
@@ -809,7 +809,8 @@ ETEXI
.args_type = "pci_addr:s,type:s,opts:s?",
.params = "auto|[[<domain>:]<bus>:]<slot> nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]...",
.help = "hot-add PCI device",
.mhandler.cmd = pci_device_hot_add,
.user_print = pci_device_hot_add_print,
.mhandler.cmd_new = pci_device_hot_add,
},
#endif
@@ -885,7 +886,7 @@ ETEXI
{
.name = "balloon",
.args_type = "value:i",
.args_type = "value:M",
.params = "target",
.help = "request VM to change it's memory allocation (in MB)",
.user_print = monitor_user_noop,
@@ -1045,6 +1046,20 @@ STEXI
Close the file descriptor previously assigned to @var{fdname} using the
@code{getfd} command. This is only needed if the file descriptor was never
used by another monitor command.
ETEXI
{
.name = "block_passwd",
.args_type = "device:B,password:s",
.params = "block_passwd device password",
.help = "set the password of encrypted block devices",
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_block_set_passwd,
},
STEXI
@item block_passwd @var{device} @var{password}
Set the encrypted device @var{device} password to @var{password}
ETEXI
STEXI

24
qemu-objects.h Normal file
View File

@@ -0,0 +1,24 @@
/*
* Include all QEMU objects.
*
* Copyright (C) 2009 Red Hat Inc.
*
* Authors:
* Luiz Capitulino <lcapitulino@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*/
#ifndef QEMU_OBJECTS_H
#define QEMU_OBJECTS_H
#include "qobject.h"
#include "qint.h"
#include "qfloat.h"
#include "qbool.h"
#include "qstring.h"
#include "qdict.h"
#include "qlist.h"
#include "qjson.h"
#endif /* QEMU_OBJECTS_H */

View File

@@ -705,7 +705,7 @@ int qemu_opts_print(QemuOpts *opts, void *dummy)
int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
{
char option[128], value[128];
char option[128], value[1024];
const char *p,*pe,*pc;
for (p = params; *p != '\0'; p++) {
@@ -751,7 +751,7 @@ int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname)
{
char value[128], *id = NULL;
char value[1024], *id = NULL;
const char *p;
QemuOpts *opts;

View File

@@ -109,6 +109,9 @@ DEF("set", HAS_ARG, QEMU_OPTION_set,
"-set group.id.arg=value\n"
" set <arg> parameter for item <id> of type <group>\n"
" i.e. -set drive.$id.file=/path/to/image\n")
DEF("global", HAS_ARG, QEMU_OPTION_global,
"-global driver.property=value\n"
" set a global default for a driver property\n")
STEXI
@item -drive @var{option}[,@var{option}[,@var{option}[,...]]]
@@ -1577,14 +1580,22 @@ Use @code{-parallel none} to disable all parallel ports.
ETEXI
DEF("monitor", HAS_ARG, QEMU_OPTION_monitor, \
"-monitor [control,]dev redirect the monitor to char device 'dev'\n")
"-monitor dev redirect the monitor to char device 'dev'\n")
STEXI
@item -monitor [@var{control},]@var{dev}
@item -monitor @var{dev}
Redirect the monitor to host device @var{dev} (same devices as the
serial port).
The default device is @code{vc} in graphical mode and @code{stdio} in
non graphical mode.
The option @var{control} enables the QEMU Monitor Protocol.
ETEXI
DEF("qmp", HAS_ARG, QEMU_OPTION_qmp, \
"-qmp dev like -monitor but opens in 'control' mode.\n")
DEF("mon", HAS_ARG, QEMU_OPTION_mon, \
"-mon chardev=[name][,mode=readline|control][,default]\n")
STEXI
@item -mon chardev=[name][,mode=readline|control][,default]
Setup monitor on chardev @var{name}.
ETEXI
DEF("pidfile", HAS_ARG, QEMU_OPTION_pidfile, \
@@ -1879,6 +1890,11 @@ DEF("incoming", HAS_ARG, QEMU_OPTION_incoming, \
STEXI
ETEXI
DEF("nodefaults", 0, QEMU_OPTION_nodefaults, \
"-nodefaults don't create default devices.\n")
STEXI
ETEXI
#ifndef _WIN32
DEF("chroot", HAS_ARG, QEMU_OPTION_chroot, \
"-chroot dir Chroot to dir just before starting the VM.\n")
@@ -1920,4 +1936,4 @@ DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig,
"-readconfig <file>\n")
DEF("writeconfig", HAS_ARG, QEMU_OPTION_writeconfig,
"-writeconfig <file>\n"
" read/write config file")
" read/write config file\n")

View File

@@ -41,20 +41,56 @@ static const QType qerror_type = {
*/
static const QErrorStringTable qerror_table[] = {
{
.error_fmt = QERR_COMMAND_NOT_FOUND,
.desc = "The command %(name) has not been found",
.error_fmt = QERR_COMMAND_NOT_FOUND,
.desc = "The command %(name) has not been found",
},
{
.error_fmt = QERR_DEVICE_NOT_FOUND,
.desc = "The %(device) device has not been found",
.error_fmt = QERR_DEVICE_ENCRYPTED,
.desc = "The %(device) is encrypted",
},
{
.error_fmt = QERR_DEVICE_LOCKED,
.desc = "Device %(device) is locked",
},
{
.error_fmt = QERR_DEVICE_NOT_ACTIVE,
.desc = "The %(device) device has not been activated by the guest",
},
{
.error_fmt = QERR_INVALID_PARAMETER_TYPE,
.desc = "Invalid parameter type, expected: %(expected)",
.error_fmt = QERR_DEVICE_NOT_FOUND,
.desc = "The %(device) device has not been found",
},
{
.error_fmt = QERR_DEVICE_NOT_REMOVABLE,
.desc = "Device %(device) is not removable",
},
{
.error_fmt = QERR_FD_NOT_FOUND,
.desc = "Failed to find file descriptor named %(name)",
},
{
.error_fmt = QERR_FD_NOT_SUPPLIED,
.desc = "No file descriptor supplied via SCM_RIGHTS",
},
{
.error_fmt = QERR_INVALID_BLOCK_FORMAT,
.desc = "Invalid block format %(name)",
},
{
.error_fmt = QERR_INVALID_PARAMETER,
.desc = "Invalid parameter %(name)",
},
{
.error_fmt = QERR_INVALID_PARAMETER_TYPE,
.desc = "Invalid parameter type, expected: %(expected)",
},
{
.error_fmt = QERR_INVALID_PASSWORD,
.desc = "The entered password is invalid",
},
{
.error_fmt = QERR_JSON_PARSING,
.desc = "Invalid JSON syntax",
},
{
.error_fmt = QERR_KVM_MISSING_CAP,
@@ -69,12 +105,20 @@ static const QErrorStringTable qerror_table[] = {
.desc = "Bad QMP input object",
},
{
.error_fmt = QERR_JSON_PARSING,
.desc = "Invalid JSON synaxt",
.error_fmt = QERR_SET_PASSWD_FAILED,
.desc = "Could not set password",
},
{
.error_fmt = QERR_UNDEFINED_ERROR,
.desc = "An undefined error has ocurred",
.error_fmt = QERR_TOO_MANY_FILES,
.desc = "Too many open files",
},
{
.error_fmt = QERR_UNDEFINED_ERROR,
.desc = "An undefined error has ocurred",
},
{
.error_fmt = QERR_VNC_SERVER_FAILED,
.desc = "Could not start VNC server on %(target)",
},
{}
};
@@ -239,13 +283,11 @@ static const char *append_field(QString *outstr, const QError *qerror,
}
/**
* qerror_print(): Print QError data
* qerror_human(): Format QError data into human-readable string.
*
* This function will print the member 'desc' of the specified QError object,
* it uses qemu_error() for this, so that the output is routed to the right
* place (ie. stderr or Monitor's device).
* Formats according to member 'desc' of the specified QError object.
*/
void qerror_print(const QError *qerror)
QString *qerror_human(const QError *qerror)
{
const char *p;
QString *qstring;
@@ -265,6 +307,19 @@ void qerror_print(const QError *qerror)
}
}
return qstring;
}
/**
* qerror_print(): Print QError data
*
* This function will print the member 'desc' of the specified QError object,
* it uses qemu_error() for this, so that the output is routed to the right
* place (ie. stderr or Monitor's device).
*/
void qerror_print(const QError *qerror)
{
QString *qstring = qerror_human(qerror);
qemu_error("%s\n", qstring_get_str(qstring));
QDECREF(qstring);
}

View File

@@ -13,6 +13,7 @@
#define QERROR_H
#include "qdict.h"
#include "qstring.h"
#include <stdarg.h>
typedef struct QErrorStringTable {
@@ -32,6 +33,7 @@ typedef struct QError {
QError *qerror_new(void);
QError *qerror_from_info(const char *file, int linenr, const char *func,
const char *fmt, va_list *va);
QString *qerror_human(const QError *qerror);
void qerror_print(const QError *qerror);
QError *qobject_to_qerror(const QObject *obj);
@@ -39,30 +41,63 @@ QError *qobject_to_qerror(const QObject *obj);
* QError class list
*/
#define QERR_COMMAND_NOT_FOUND \
"{ 'class': 'CommandNotFound', 'data': { 'name': %s } }"
"{ 'class': 'CommandNotFound', 'data': { 'name': %s } }"
#define QERR_DEVICE_NOT_FOUND \
"{ 'class': 'DeviceNotFound', 'data': { 'device': %s } }"
#define QERR_DEVICE_ENCRYPTED \
"{ 'class': 'DeviceEncrypted', 'data': { 'device': %s } }"
#define QERR_DEVICE_LOCKED \
"{ 'class': 'DeviceLocked', 'data': { 'device': %s } }"
#define QERR_DEVICE_NOT_ACTIVE \
"{ 'class': 'DeviceNotActive', 'data': { 'device': %s } }"
"{ 'class': 'DeviceNotActive', 'data': { 'device': %s } }"
#define QERR_DEVICE_NOT_FOUND \
"{ 'class': 'DeviceNotFound', 'data': { 'device': %s } }"
#define QERR_DEVICE_NOT_REMOVABLE \
"{ 'class': 'DeviceNotRemovable', 'data': { 'device': %s } }"
#define QERR_FD_NOT_FOUND \
"{ 'class': 'FdNotFound', 'data': { 'name': %s } }"
#define QERR_FD_NOT_SUPPLIED \
"{ 'class': 'FdNotSupplied', 'data': {} }"
#define QERR_INVALID_BLOCK_FORMAT \
"{ 'class': 'InvalidBlockFormat', 'data': { 'name': %s } }"
#define QERR_INVALID_PARAMETER \
"{ 'class': 'InvalidParameter', 'data': { 'name': %s } }"
#define QERR_INVALID_PARAMETER_TYPE \
"{ 'class': 'InvalidParameterType', 'data': { 'name': %s,'expected': %s } }"
"{ 'class': 'InvalidParameterType', 'data': { 'name': %s,'expected': %s } }"
#define QERR_KVM_MISSING_CAP \
"{ 'class': 'KVMMissingCap', 'data': { 'capability': %s, 'feature': %s } }"
#define QERR_MISSING_PARAMETER \
"{ 'class': 'MissingParameter', 'data': { 'name': %s } }"
#define QERR_QMP_BAD_INPUT_OBJECT \
"{ 'class': 'QMPBadInputObject', 'data': { 'expected': %s } }"
#define QERR_INVALID_PASSWORD \
"{ 'class': 'InvalidPassword', 'data': {} }"
#define QERR_JSON_PARSING \
"{ 'class': 'JSONParsing', 'data': {} }"
"{ 'class': 'JSONParsing', 'data': {} }"
#define QERR_KVM_MISSING_CAP \
"{ 'class': 'KVMMissingCap', 'data': { 'capability': %s, 'feature': %s } }"
#define QERR_MISSING_PARAMETER \
"{ 'class': 'MissingParameter', 'data': { 'name': %s } }"
#define QERR_QMP_BAD_INPUT_OBJECT \
"{ 'class': 'QMPBadInputObject', 'data': { 'expected': %s } }"
#define QERR_SET_PASSWD_FAILED \
"{ 'class': 'SetPasswdFailed', 'data': {} }"
#define QERR_UNDEFINED_ERROR \
"{ 'class': 'UndefinedError', 'data': {} }"
"{ 'class': 'UndefinedError', 'data': {} }"
#define QERR_TOO_MANY_FILES \
"{ 'class': 'TooManyFiles', 'data': {} }"
#define QERR_VNC_SERVER_FAILED \
"{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }"
#endif /* QERROR_H */

View File

@@ -47,3 +47,6 @@ cc-option = $(if $(shell $(CC) $1 $2 -S -o /dev/null -xc /dev/null \
%.h-timestamp: %.mak
$(call quiet-command, sh $(SRC_PATH)/create_config < $< > $@, " GEN $*.h")
@cmp $@ $*.h >/dev/null 2>&1 || cp $@ $*.h
# will delete the target of a rule if commands exit with a nonzero exit status
.DELETE_ON_ERROR:

View File

@@ -264,6 +264,12 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
size_t prefix_len;
char *req_fname;
/* check if a session already exists and if so terminate it */
s = tftp_session_find(slirp, tp);
if (s >= 0) {
tftp_session_terminate(&slirp->tftp_sessions[s]);
}
s = tftp_session_allocate(slirp, tp);
if (s < 0) {
@@ -362,6 +368,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
}
tftp_send_oack(spt, "tsize", tsize, tp);
return;
}
}
@@ -385,6 +392,19 @@ static void tftp_handle_ack(Slirp *slirp, struct tftp_t *tp, int pktlen)
}
}
static void tftp_handle_error(Slirp *slirp, struct tftp_t *tp, int pktlen)
{
int s;
s = tftp_session_find(slirp, tp);
if (s < 0) {
return;
}
tftp_session_terminate(&slirp->tftp_sessions[s]);
}
void tftp_input(struct mbuf *m)
{
struct tftp_t *tp = (struct tftp_t *)m->m_data;
@@ -397,5 +417,9 @@ void tftp_input(struct mbuf *m)
case TFTP_ACK:
tftp_handle_ack(m->slirp, tp, m->m_len);
break;
case TFTP_ERROR:
tftp_handle_error(m->slirp, tp, m->m_len);
break;
}
}

View File

@@ -212,7 +212,8 @@ extern DriveInfo *drive_init(QemuOpts *arg, void *machine, int *fatal_error);
DriveInfo *add_init_drive(const char *opts);
/* pci-hotplug */
void pci_device_hot_add(Monitor *mon, const QDict *qdict);
void pci_device_hot_add_print(Monitor *mon, const QObject *data);
void pci_device_hot_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
void drive_hot_add(Monitor *mon, const QDict *qdict);
void pci_device_hot_remove(Monitor *mon, const char *pci_addr);
void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict,

View File

@@ -46,10 +46,10 @@ uint64_t helper_load_fpcr (void)
{
uint64_t ret = 0;
#ifdef CONFIG_SOFTFLOAT
ret |= env->fp_status.float_exception_flags << 52;
ret |= (uint64_t)env->fp_status.float_exception_flags << 52;
if (env->fp_status.float_exception_flags)
ret |= 1ULL << 63;
env->ipr[IPR_EXC_SUM] &= ~0x3E:
env->ipr[IPR_EXC_SUM] &= ~0x3E;
env->ipr[IPR_EXC_SUM] |= env->fp_status.float_exception_flags << 1;
#endif
switch (env->fp_status.float_rounding_mode) {

View File

@@ -651,6 +651,8 @@ typedef struct CPUX86State {
target_ulong fmask;
target_ulong kernelgsbase;
#endif
uint64_t system_time_msr;
uint64_t wall_clock_msr;
uint64_t tsc;
@@ -692,6 +694,7 @@ typedef struct CPUX86State {
/* For KVM */
uint32_t mp_state;
int32_t exception_injected;
int32_t interrupt_injected;
uint8_t soft_interrupt;
uint8_t nmi_injected;
@@ -832,12 +835,12 @@ static inline int hw_breakpoint_enabled(unsigned long dr7, int index)
static inline int hw_breakpoint_type(unsigned long dr7, int index)
{
return (dr7 >> (DR7_TYPE_SHIFT + (index * 2))) & 3;
return (dr7 >> (DR7_TYPE_SHIFT + (index * 4))) & 3;
}
static inline int hw_breakpoint_len(unsigned long dr7, int index)
{
int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 2))) & 3);
int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 4))) & 3);
return (len == 2) ? 8 : len + 1;
}

View File

@@ -131,10 +131,11 @@ static x86_def_t x86_defs[] = {
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
/* this feature is needed for Solaris and isn't fully implemented */
CPUID_PSE36,
.ext_features = CPUID_EXT_SSE3,
.ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
.ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
.ext3_features = CPUID_EXT3_SVM,
.ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
.xlevel = 0x8000000A,
.model_id = "QEMU Virtual CPU version " QEMU_VERSION,
},
@@ -151,18 +152,19 @@ static x86_def_t x86_defs[] = {
.features = PPRO_FEATURES |
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
CPUID_PSE36,
/* Missing: CPUID_EXT_CX16, CPUID_EXT_POPCNT */
.ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
.ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
CPUID_EXT_POPCNT,
/* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
.ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
CPUID_EXT2_FFXSR,
/* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
/* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
CPUID_EXT3_CR8LEG,
CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
.ext3_features = CPUID_EXT3_SVM,
.ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
.xlevel = 0x8000001A,
.model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
},
@@ -183,7 +185,7 @@ static x86_def_t x86_defs[] = {
CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
.ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
.ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
/* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
.ext3_features = CPUID_EXT3_LAHF_LM,
.xlevel = 0x80000008,
.model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
},
@@ -221,7 +223,7 @@ static x86_def_t x86_defs[] = {
.model = 3,
.stepping = 3,
.features = PPRO_FEATURES,
.ext_features = CPUID_EXT_SSE3,
.ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
.xlevel = 0,
.model_id = "QEMU Virtual CPU version " QEMU_VERSION,
},
@@ -615,6 +617,8 @@ void cpu_reset(CPUX86State *env)
env->dr[7] = DR7_FIXED_1;
cpu_breakpoint_remove_all(env, BP_CPU);
cpu_watchpoint_remove_all(env, BP_CPU);
env->mcg_status = 0;
}
void cpu_x86_close(CPUX86State *env)
@@ -1638,6 +1642,24 @@ static void host_cpuid(uint32_t function, uint32_t count,
#endif
}
static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
{
*ebx = env->cpuid_vendor1;
*edx = env->cpuid_vendor2;
*ecx = env->cpuid_vendor3;
/* sysenter isn't supported on compatibility mode on AMD, syscall
* isn't supported in compatibility mode on Intel.
* Normally we advertise the actual cpu vendor, but you can override
* this if you want to use KVM's sysenter/syscall emulation
* in compatibility mode and when doing cross vendor migration
*/
if (kvm_enabled() && env->cpuid_vendor_override) {
host_cpuid(0, 0, NULL, ebx, ecx, edx);
}
}
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
@@ -1654,16 +1676,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
switch(index) {
case 0:
*eax = env->cpuid_level;
*ebx = env->cpuid_vendor1;
*edx = env->cpuid_vendor2;
*ecx = env->cpuid_vendor3;
/* sysenter isn't supported on compatibility mode on AMD. and syscall
* isn't supported in compatibility mode on Intel. so advertise the
* actuall cpu, and say goodbye to migration between different vendors
* is you use compatibility mode. */
if (kvm_enabled() && !env->cpuid_vendor_override)
host_cpuid(0, 0, NULL, ebx, ecx, edx);
get_cpuid_vendor(env, ebx, ecx, edx);
break;
case 1:
*eax = env->cpuid_version;
@@ -1759,19 +1772,23 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*ecx = env->cpuid_ext3_features;
*edx = env->cpuid_ext2_features;
if (env->nr_cores * env->nr_threads > 1 &&
env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
*ecx |= 1 << 1; /* CmpLegacy bit */
/* The Linux kernel checks for the CMPLegacy bit and
* discards multiple thread information if it is set.
* So dont set it here for Intel to make Linux guests happy.
*/
if (env->nr_cores * env->nr_threads > 1) {
uint32_t tebx, tecx, tedx;
get_cpuid_vendor(env, &tebx, &tecx, &tedx);
if (tebx != CPUID_VENDOR_INTEL_1 ||
tedx != CPUID_VENDOR_INTEL_2 ||
tecx != CPUID_VENDOR_INTEL_3) {
*ecx |= 1 << 1; /* CmpLegacy bit */
}
}
if (kvm_enabled()) {
/* Nested SVM not yet supported in KVM */
/* Nested SVM not yet supported in upstream QEMU */
*ecx &= ~CPUID_EXT3_SVM;
} else {
/* AMD 3DNow! is not supported in QEMU */
*edx &= ~(CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT);
}
break;
case 0x80000002:

View File

@@ -35,6 +35,9 @@
do { } while (0)
#endif
#define MSR_KVM_WALL_CLOCK 0x11
#define MSR_KVM_SYSTEM_TIME 0x12
#ifdef KVM_CAP_EXT_CPUID
static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
@@ -224,6 +227,7 @@ int kvm_arch_init_vcpu(CPUState *env)
void kvm_arch_reset_vcpu(CPUState *env)
{
env->exception_injected = -1;
env->interrupt_injected = -1;
env->nmi_injected = 0;
env->nmi_pending = 0;
@@ -244,9 +248,9 @@ static int kvm_has_msr_star(CPUState *env)
* save/restore */
msr_list.nmsrs = 0;
ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, &msr_list);
if (ret < 0)
if (ret < 0 && ret != -E2BIG) {
return 0;
}
/* Old kernel modules had a bug and could write beyond the provided
memory. Allocate at least a safe amount of 1K. */
kvm_msr_list = qemu_mallocz(MAX(1024, sizeof(msr_list) +
@@ -494,6 +498,9 @@ static int kvm_put_msrs(CPUState *env)
kvm_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask);
kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar);
#endif
kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME, env->system_time_msr);
kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr);
msr_data.info.nmsrs = n;
return kvm_vcpu_ioctl(env, KVM_SET_MSRS, &msr_data);
@@ -634,6 +641,9 @@ static int kvm_get_msrs(CPUState *env)
msrs[n++].index = MSR_FMASK;
msrs[n++].index = MSR_LSTAR;
#endif
msrs[n++].index = MSR_KVM_SYSTEM_TIME;
msrs[n++].index = MSR_KVM_WALL_CLOCK;
msr_data.info.nmsrs = n;
ret = kvm_vcpu_ioctl(env, KVM_GET_MSRS, &msr_data);
if (ret < 0)
@@ -670,6 +680,12 @@ static int kvm_get_msrs(CPUState *env)
case MSR_IA32_TSC:
env->tsc = msrs[i].data;
break;
case MSR_KVM_SYSTEM_TIME:
env->system_time_msr = msrs[i].data;
break;
case MSR_KVM_WALL_CLOCK:
env->wall_clock_msr = msrs[i].data;
break;
}
}
@@ -705,8 +721,8 @@ static int kvm_put_vcpu_events(CPUState *env)
return 0;
}
events.exception.injected = (env->exception_index >= 0);
events.exception.nr = env->exception_index;
events.exception.injected = (env->exception_injected >= 0);
events.exception.nr = env->exception_injected;
events.exception.has_error_code = env->has_error_code;
events.exception.error_code = env->error_code;
@@ -740,7 +756,7 @@ static int kvm_get_vcpu_events(CPUState *env)
if (ret < 0) {
return ret;
}
env->exception_index =
env->exception_injected =
events.exception.injected ? events.exception.nr : -1;
env->has_error_code = events.exception.has_error_code;
env->error_code = events.exception.error_code;

View File

@@ -448,6 +448,7 @@ static const VMStateDescription vmstate_cpu = {
VMSTATE_INT32_V(interrupt_injected, CPUState, 9),
VMSTATE_UINT32_V(mp_state, CPUState, 9),
VMSTATE_UINT64_V(tsc, CPUState, 9),
VMSTATE_INT32_V(exception_injected, CPUState, 11),
VMSTATE_UINT8_V(soft_interrupt, CPUState, 11),
VMSTATE_UINT8_V(nmi_injected, CPUState, 11),
VMSTATE_UINT8_V(nmi_pending, CPUState, 11),
@@ -460,6 +461,9 @@ static const VMStateDescription vmstate_cpu = {
VMSTATE_UINT64_ARRAY_V(mce_banks, CPUState, MCE_BANKS_DEF *4, 10),
/* rdtscp */
VMSTATE_UINT64_V(tsc_aux, CPUState, 11),
/* KVM pvclock msr */
VMSTATE_UINT64_V(system_time_msr, CPUState, 11),
VMSTATE_UINT64_V(wall_clock_msr, CPUState, 11),
VMSTATE_END_OF_LIST()
/* The above list is not sorted /wrt version numbers, watch out! */
}

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