Compare commits

..

176 Commits

Author SHA1 Message Date
Gonglei
54086fe5d2 bootindex: change fprintf to error_report
The function may be called by qmp command, we should
report error message to the caller.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 10:46:01 +02:00
Gonglei
4aca8a8178 bootindex: delete bootindex when device is removed
Device should be removed from global boot list when
it is hot-unplugged.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 10:46:01 +02:00
Gonglei
d749e10c4f bootindex: move calling add_boot_device_patch to bootindex setter function
On this way, we can assure the new bootindex take effect
during vm rebooting.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 10:46:01 +02:00
Gonglei
d2b186f96d ide: add calling add_boot_device_patch in bootindex setter function
On this way, we can assure the new bootindex take effect
during vm rebooting. Meanwhile set the initial value of
bootindex to -1.

Because ide devcies's unit property maybe
do not initialize when set_bootindex function is called,
so that we don't know its suffix. So we have to save the
call add_boot_device_path() on ide realize/init function.
When we want to change bootindex during vm rebooting, we
can call it in setter function.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 10:45:51 +02:00
Gonglei
33739c7129 nvma: ide: add bootindex to qom property
At present, nvma cannot boot. However, it provides already
a bootindex property, so change bootindex to qom for nvma
device, but not call add_boot_device_path.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 10:27:52 +02:00
Gonglei
89f0762dde usb-storage: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Because usb-storage rely on scsi-disk which is created
in usb_msg_realize_storage(), so we should store the SCSIDevice
pointer in MSDState struct. Only in this way, we can change
the global boot_order_list when we want to change the bootindex
during vm rebooting by calling object_property_set_int(Object(SCSIDevice),).

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 10:27:07 +02:00
Gonglei
aeb98ddc50 virtio-blk: alias bootindex property explicitly for virt-blk-pci/ccw/s390
Since the "bootindex" property is a QOM property and not a qdev property
now, we must alias it explicitly for virtio-blk-pci, as well as CCW and
s390-virtio.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
8dece34f26 block: remove bootindex property from qdev to qom
Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
3342ec324a virtio-blk: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
4556363087 ide: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
44fb6337b9 scsi: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
81782b6a78 isa-fdc: remove bootindexA/B property from qdev to qom
Remove bootindexA/B form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
295857994c redirect: remove bootindex property from qdev to qom
Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
abc5b3bfe1 vfio: remove bootindex property from qdev to qom
Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
7f6014af27 pci-assign: remove bootindex property from qdev to qom
Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
e6adae52b1 host-libusb: remove bootindex property from qdev to qom
Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
0cf63c3e35 virtio-net: alias bootindex property explicitly for virt-net-pci/ccw/s390
Since the "bootindex" property is a QOM property and not a qdev property
now, we must alias it explicitly for virtio-net-pci, as well as CCW and
s390-virtio.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
45e8a9e123 net: remove bootindex property from qdev to qom
Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
c11f4bc9ff usb-net: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
e25524efb0 vmxnet3: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
dfe79cf268 spapr_lian: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
afd7c850f5 rtl8139: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
ea3b3511cd pcnet: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
6cb0851d62 ne2000: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

At present, isa_ne2000 device does not support to boot
os, so we register two seprate qom getter/setter functions.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
7317bb1782 eepro100: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
5df3bf623d e1000: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
aa4197c323 virtio-net: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:53 +02:00
Gonglei
12da309778 bootindex: add a setter/getter functions wrapper for bootindex property
when we remove bootindex form qdev.property to qom.property,
we can use those functions set/get bootindex property for all
correlative devices. Meanwhile set the initial value of
bootindex to -1.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:47 +02:00
Gonglei
a598f2ffc2 bootindex: support to set a existent device's bootindex to -1
When set a device's bootindex to -1, we remove it from global
fw_boot_order list.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:47 +02:00
Gonglei
e614b54b93 bootindex: rework add_boot_device_path function
Add the function of updating bootindex about fw_boot_order list
in add_boot_device_path(). We should delete the old one if a
device has existed in global fw_boot_order list.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:47 +02:00
Gonglei
bdbb5b1706 fw_cfg: add fw_cfg_machine_reset function
We must assure that the changed bootindex can take effect
when guest is rebooted. So we introduce fw_cfg_machine_reset(),
which change the fw_cfg file's bootindex data using the new
global fw_boot_order list.

Signed-off-by: Chenliang <chenliang88@huawei.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:15 +02:00
Gonglei
9d27572d62 bootindex: add del_boot_device_path function
Introduce del_boot_device_path() to clean up fw_cfg content when
hot-unplugging a device that refers to a bootindex or update a
existent devcie's bootindex.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Chenliang <chenliang88@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:49:48 +02:00
Gonglei
694fb857ab bootindex: add check bootindex function
Determine whether a given bootindex exists or not.
If exists, we report an error.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:49:48 +02:00
Gonglei
bc74112f7e bootdevice: move bootdevice related code to new file bootdevice.c
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:49:48 +02:00
Peter Maydell
b1d28ec6a7 Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20141010' into staging
various s390x updates:
- cpu state handling in qemu and migration
- vhost-scsi-ccw bugfix

# gpg: Signature made Fri 10 Oct 2014 14:01:34 BST using RSA key ID C6F02FAF
# gpg: Can't check signature: public key not found

* remotes/cohuck/tags/s390x-20141010:
  s390x/virtio-ccw: fix vhost-scsi intialization
  s390x/migration: migrate CPU state
  s390x/kvm: synchronize the cpu state after SIGP (INITIAL) CPU RESET
  s390x/kvm: reuse kvm_s390_reset_vcpu() to get rid of ifdefs
  s390x/kvm: propagate s390 cpu state to kvm
  s390x/kvm: proper use of the cpu states OPERATING and STOPPED
  s390x/kvm: introduce proper states for s390 cpus
  linux-headers: update to 3.17-rc7

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-10-10 14:55:29 +01:00
Paolo Bonzini
9d1c35dfc9 kvm fix compilation with GCC 4.3.4
As usual, SLES11's GCC complained about double typedefs:

/home/cohuck/git/qemu/kvm-all.c:110: error: redefinition of typedef ‘KVMState’
/home/cohuck/git/qemu/include/sysemu/kvm.h:161: error: previous declaration of ‘KVMState’ was here

Reported-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Tested-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-10-10 14:07:08 +01:00
Cornelia Huck
4b7757bae7 s390x/virtio-ccw: fix vhost-scsi intialization
The vhost-scsi-ccw backend is of type VHostSCSICcw, not VirtIOSCSICcw.

This fixes a segfault when invoking

    qemu-system-s390x -device vhost-scsi-ccw,?

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-10-10 13:32:39 +02:00
Thomas Huth
ef1df13087 s390x/migration: migrate CPU state
This patch provides the cpu save information for dumps and later life
migration and enables migration of the CPU state. The code is based on
earlier work from Christian Borntraeger and Jason Herne.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
[provide cpu_post_load()]
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
CC: Andreas Faerber <afaerber@suse.de>
CC: Christian Borntraeger <borntraeger@de.ibm.com>
CC: Jason J. Herne <jjherne@us.ibm.com>
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
[Cornelia Huck: tweaked cpu_post_load() comment]
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-10-10 13:31:51 +02:00
David Hildenbrand
71dd7e69b3 s390x/kvm: synchronize the cpu state after SIGP (INITIAL) CPU RESET
We need to synchronize registers after a reset has been performed. The
current code does that in qemu_system_reset(), load_normal_reset() and
modified_clear_reset() for all vcpus. After SIGP (INITIAL) CPU RESET,
this needs to be done for the targeted vcpu as well, so let's call
cpu_synchronize_post_reset() in the respective handlers.

Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
CC: Andreas Faerber <afaerber@suse.de>
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-10-10 10:37:47 +02:00
David Hildenbrand
99607144a4 s390x/kvm: reuse kvm_s390_reset_vcpu() to get rid of ifdefs
This patch reuses kvm_s390_reset_vcpu() to get rid of some CONFIG_KVM and
CONFIG_USER_ONLY ifdefs in cpu.c.

In order to get rid of CONFIG_USER_ONLY, kvm_s390_reset_vcpu() has to provide a
dummy implementation - the two definitions are moved to the proper section in
cpu.h.

Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
CC: Andreas Faerber <afaerber@suse.de>
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-10-10 10:37:47 +02:00
David Hildenbrand
c9e659c9ee s390x/kvm: propagate s390 cpu state to kvm
Let QEMU propagate the cpu state to kvm. If kvm doesn't yet support it, it is
silently ignored as kvm will still handle the cpu state itself in that case.

The state is not synced back, thus kvm won't have a chance to actively modify
the cpu state. To do so, control has to be given back to QEMU (which is already
done so in all relevant cases).

Setting of the cpu state can fail either because kvm doesn't support the
interface yet, or because the state is invalid/not supported. Failed attempts
will be traced

Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
CC: Andreas Faerber <afaerber@suse.de>
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-10-10 10:37:47 +02:00
David Hildenbrand
eb24f7c689 s390x/kvm: proper use of the cpu states OPERATING and STOPPED
This patch makes sure that halting a cpu and stopping a cpu are two different
things. Stopping a cpu will also set the cpu halted - this is needed for common
infrastructure to work (note that the stop and stopped flag cannot be used for
our purpose because they are already used by other mechanisms).

A cpu can be halted ("waiting") when it is operating. If interrupts are
disabled, this is called a "disabled wait", as it can't be woken up anymore. A
stopped cpu is treated like a "disabled wait" cpu, but in order to prepare for a
proper cpu state synchronization with the kvm part, we need to track the real
logical state of a cpu.

Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
CC: Andreas Faerber <afaerber@suse.de>
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-10-10 10:37:47 +02:00
David Hildenbrand
75973bfe41 s390x/kvm: introduce proper states for s390 cpus
Until now, when a s390 cpu was stopped or halted, the number of running
CPUs was tracked in a global variable. This was problematic for migration,
so Jason came up with a per-cpu running state.
As it turns out, we want to track the full logical state of a target vcpu,
so we need real s390 cpu states.

This patch is based on an initial patch by Jason Herne, but was heavily
rewritten when adding the cpu states STOPPED and OPERATING. On the way we
move add_del_running to cpu.c (the declaration is already in cpu.h) and
modify the users where appropriate.

Please note that the cpu is still set to be stopped when it is
halted, which is wrong. This will be fixed in the next patch. The LOAD and
CHECK-STOP state will not be used in the first step.

Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
[folded Jason's patch into David's patch to avoid add/remove same lines]
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
CC: Andreas Faerber <afaerber@suse.de>
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-10-10 10:37:47 +02:00
Jens Freimann
a9fd16544d linux-headers: update to 3.17-rc7
Sync headers with 3.17-rc7

Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-10-10 10:37:47 +02:00
Peter Maydell
fcb2cd928f Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
Four changes here.  Polling for reconnection of character devices,
the QOMification of accelerators, a fix for -kernel support on x86, and one
for a recently-introduced virtio-scsi optimization.

# gpg: Signature made Thu 09 Oct 2014 14:36:50 BST using RSA key ID 4E6B09D7
# gpg: Good signature from "Paolo Bonzini <pbonzini@redhat.com>"
# gpg:                 aka "Paolo Bonzini <bonzini@gnu.org>"

* remotes/bonzini/tags/for-upstream: (28 commits)
  qemu-char: Fix reconnect socket error reporting
  qemu-sockets: Add error to non-blocking connect handler
  qemu-error: Add error_vreport()
  virtio-scsi: fix use-after-free of VirtIOSCSIReq
  linuxboot: compute initrd loading address
  kvm: Make KVMState be the TYPE_KVM_ACCEL instance struct
  accel: Create accel object when initializing machine
  accel: Pass MachineState object to accel init functions
  accel: Rename 'init' method to 'init_machine'
  accel: Move accel init/allowed code to separate function
  accel: Remove tcg_available() function
  accel: Move qtest accel registration to qtest.c
  accel: Move Xen registration code to xen-common.c
  accel: Move KVM accel registration to kvm-all.c
  accel: Report unknown accelerator as "not found" instead of "does not exist"
  accel: Make AccelClass.available() optional
  accel: Use QOM classes for accel types
  accel: Move accel name lookup to separate function
  accel: Simplify configure_accelerator() using AccelType *acc variable
  accel: Create AccelType typedef
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-10-09 15:09:05 +01:00
Corey Minyard
5008e5b7b8 qemu-char: Fix reconnect socket error reporting
If reconnect was set, errors wouldn't always be reported.
Fix that and also only report a connect error once until a
connection has been made.

The primary purpose of this is to tell the user that a
connection failed so they can know they need to figure out
what went wrong.  So we don't want to spew too much
out here, just enough so they know.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-09 15:36:15 +02:00
Corey Minyard
5179502918 qemu-sockets: Add error to non-blocking connect handler
An error value here would be quite handy and more consistent
with the rest of the code.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
[Make sure SO_ERROR value is passed to error_setg_errno. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-09 15:36:15 +02:00
Corey Minyard
5748e4c2be qemu-error: Add error_vreport()
Needed to nicely print socket error reports.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-09 15:36:15 +02:00
Paolo Bonzini
35e4e96c4d virtio-scsi: fix use-after-free of VirtIOSCSIReq
scsi_req_continue can complete the request and cause the VirtIOSCSIReq
to be freed.  Fetch req->sreq just once to avoid the bug.

Reported-by: Richard Jones <rjones@redhat.com>
Tested-by: Richard Jones <rjones@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-09 15:36:15 +02:00
Paolo Bonzini
cdebec5e40 linuxboot: compute initrd loading address
Even though hw/i386/pc.c tries to compute a valid loading address for the
initrd, close to the top of RAM, this does not take into account other
data that is malloced into that memory by SeaBIOS.

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

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

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

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

Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-09 15:36:15 +02:00
Eduardo Habkost
fc02086b5a kvm: Make KVMState be the TYPE_KVM_ACCEL instance struct
Now that we create an accel object before calling machine_init, we can
simply use the accel object to save all KVMState data, instead of
allocationg KVMState manually.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-09 15:36:15 +02:00
Eduardo Habkost
ac2da55e01 accel: Create accel object when initializing machine
Create an actual TYPE_ACCEL object when initializing a machine. This
will allow accelerator classes to implement some initialization on
instance_init, and to save state on the TYPE_ACCEL object.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-09 15:36:14 +02:00
Eduardo Habkost
f6a1ef6440 accel: Pass MachineState object to accel init functions
Most of the machine options and machine state information is in the
MachineState object, not on the MachineClass. This will allow init
functions to use the MachineState object directly instead of
qemu_get_machine_opts() or the current_machine global.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-09 12:57:10 +02:00
Peter Maydell
b6011bd8a5 Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20141006-2' into staging
linux-user pull for 2.2

Clearest linux-user patches sent to the list since august,
Apart from Mikhails patch, the rest are quite trivial.

v2: check for CONFIG_TIMERFD only after it has been defined

# gpg: Signature made Mon 06 Oct 2014 20:08:10 BST using RSA key ID DE3C9BC0
# gpg: Good signature from "Riku Voipio <riku.voipio@iki.fi>"
# gpg:                 aka "Riku Voipio <riku.voipio@linaro.org>"

* remotes/riku/tags/pull-linux-user-20141006-2:
  translate-all.c: memory walker initial address miscalculation
  linux-user: don't include timerfd if not needed
  linux-user: Simplify timerid checks on g_posix_timers range
  linux-user: Convert blkpg to use a special subop handler
  linux-user: Enable epoll_pwait syscall for ARM

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-10-07 10:41:48 +01:00
Mikhail Ilyin
1a1c4db9b2 translate-all.c: memory walker initial address miscalculation
The initial base address is miscalculated in walk_memory_regions().
It has to be shifted TARGET_PAGE_BITS more. Holder variables are
extended to target_ulong size otherwise they don't fit for MIPS N32
(a 32-bit ABI with a 64-bit address space) and qemu won't compile.
The issue led to incorrect debug output of memory maps and a
mis-formed coredumped file.

Signed-off-by: Mikhail Ilyin <m.ilin@samsung.com>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-10-06 21:53:35 +03:00
Riku Voipio
d80a190594 linux-user: don't include timerfd if not needed
Without this, builds on older systems fail with:

qemu/linux-user/syscall.c:61:25: warning: sys/timerfd.h: No such file or directory

v2: fix the usual case where CONFIG_TIMERFD is enabled..

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-10-06 21:52:46 +03:00
Alexander Graf
e52a99f756 linux-user: Simplify timerid checks on g_posix_timers range
We check whether the passed in timer id is negative on all calls
that involve g_posix_timers.

However, these checks are bogus. First off we limit the timer_id to
16 bits which is not what Linux does. Then we check whether it's negative
which it can't be because we masked it.

We can safely remove the masking. For the negativity check we can just
treat the timerid as unsigned and only check for upper boundaries.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-10-06 21:52:45 +03:00
Alexander Graf
a59b5e35d1 linux-user: Convert blkpg to use a special subop handler
The blkpg ioctl can take different payloads depending on the opcode in
its payload structure. Create a new special ioctl handler that can only
deal with partition style ones for now.

This patch fixes running parted for me.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-10-06 21:52:45 +03:00
Peter Maydell
40645c7bfd linux-user: Enable epoll_pwait syscall for ARM
We have support for the epoll_pwait syscall, but it wasn't enabled for
ARM guests because we hadn't defined the syscall number; correct this
deficiency.

Reported-by: Dave Flogeras <dflogeras2@gmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-10-06 21:52:45 +03:00
Peter Maydell
2472b6c07b gdbstub: Allow target CPUs to specify watchpoint STOP_BEFORE_ACCESS flag
GDB assumes that watchpoint set via the gdbstub remote protocol will
behave in the same way as hardware watchpoints for the target. In
particular, whether the CPU stops with the PC before or after the insn
which triggers the watchpoint is target dependent. Allow guest CPU
code to specify which behaviour to use. This fixes a bug where with
guest CPUs which stop before the accessing insn GDB would manually
step forward over what it thought was the insn and end up one insn
further forward than it should be.

We set this flag for the CPU architectures which set
gdbarch_have_nonsteppable_watchpoint in gdb 7.7:
ARM, CRIS, LM32, MIPS and Xtensa.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Tested-by: Max Filippov <jcmvbkbc@gmail.com>
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Tested-by: Michael Walle <michael@walle.cc> (for lm32)
Message-id: 1410545057-14014-1-git-send-email-peter.maydell@linaro.org
2014-10-06 14:25:43 +01:00
Peter Maydell
507ef2f9fa Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
# gpg: Signature made Sat 04 Oct 2014 21:24:46 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/block-pull-request: (23 commits)
  blockdev-test: Test device_del after drive_del
  blockdev-test: Factor out some common code into helpers
  blockdev-test: Simplify by using g_assert_cmpstr()
  blockdev-test: Clean up bogus drive_add argument
  blockdev-test: Use single rather than double quotes in QMP
  drive_del-test: Merge of qdev-monitor-test, blockdev-test
  iotests: qemu-img info output for corrupt image
  qapi: Add corrupt field to ImageInfoSpecificQCow2
  iotests: Use _img_info
  util: Emancipate id_wellformed() from QemuOpts
  q35/ahci: Pick up -cdrom and -hda options
  qtest/bios-tables: Correct Q35 command line
  ide: Update ide_drive_get to be HBA agnostic
  pc/vl: Add units-per-default-bus property
  blockdev: Allow overriding if_max_dev property
  blockdev: Orphaned drive search
  qemu-iotests: Fix supported cache modes for 052
  make check-block: Use default cache modes
  Modify qemu_opt_rename to realize renaming all items in opts
  vmdk: Fix integer overflow in offset calculation
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-10-06 10:59:56 +01:00
Markus Armbruster
767c86d3e7 blockdev-test: Test device_del after drive_del
Executed in this order, drive_del and device_del's automatic drive
deletion take notoriously tricky special paths.

[Fixed "an device" -> "a device" typo as requested by Eric Blake.
--Stefan]

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1412261496-24455-7-git-send-email-armbru@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-04 19:28:39 +01:00
Markus Armbruster
2eea5cd452 blockdev-test: Factor out some common code into helpers
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1412261496-24455-6-git-send-email-armbru@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-04 19:28:14 +01:00
Markus Armbruster
37e153fe45 blockdev-test: Simplify by using g_assert_cmpstr()
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1412261496-24455-5-git-send-email-armbru@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-04 19:28:14 +01:00
Markus Armbruster
e319df669d blockdev-test: Clean up bogus drive_add argument
The first argument should be a PCI address, which pci-addr=auto isn't.
Doesn't really matter, as drive_add ignores its first argument when
its second argument has if=none.  Clean it up anyway.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1412261496-24455-4-git-send-email-armbru@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-04 19:28:13 +01:00
Markus Armbruster
d0e3866837 blockdev-test: Use single rather than double quotes in QMP
QMP accepts both single and double quotes.  This is the only test
using double quotes.  They need to be quoted in C strings.  Replace
them by single quotes.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1412261496-24455-3-git-send-email-armbru@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-04 19:28:13 +01:00
Markus Armbruster
e2f3f22188 drive_del-test: Merge of qdev-monitor-test, blockdev-test
Each of qdev-monitor-test and blockdev-test has just one test case,
and both are about drive_del.

[Extended copyright from 2013 to 2013-2014 as requested by Eric Blake.
--Stefan]

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1412261496-24455-2-git-send-email-armbru@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-04 19:27:29 +01:00
Max Reitz
f383611a0a iotests: qemu-img info output for corrupt image
The "corrupt" entry in the format-specific information section should be
"true".

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1412105489-7681-4-git-send-email-mreitz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-04 19:18:17 +01:00
Max Reitz
9009b1963c qapi: Add corrupt field to ImageInfoSpecificQCow2
Just like lazy-refcounts, this field will be present iff the qcow2
compat level is 1.1 (or probably any future revision).

As expected, this breaks some tests due to the new field present in
qemu-img info output; so fix their output accordingly.

Suggested-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1412105489-7681-3-git-send-email-mreitz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-04 19:18:17 +01:00
Max Reitz
1b53eab270 iotests: Use _img_info
qemu-img info should only be used directly if the format-specific
information or the name of the format is relevant (some tests explicitly
test format-specific information; test 082 uses qcow2-specific settings
to test the qemu-img interface); otherwise, tests should always use
_img_info instead.

Test 082 was touched only partially. It does test the qemu-img
interface; however, its invocations of qemu-img info are not real tests
but rather verifications, so if format-specific information is not
important for the test, there is no reason not to use _img_info. In
contrast to directly invoking qemu-img info, "qcow2" is replaced by
"IMGFMT"; but as "qcow2" is only mentioned once in test 082 (in
_supported_fmt), I consider this an improvement.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1412105489-7681-2-git-send-email-mreitz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-04 19:18:17 +01:00
Eduardo Habkost
0d15da8e6f accel: Rename 'init' method to 'init_machine'
Today, all accelerator init functions affect some global state:
* tcg_init() calls tcg_exec_init() and affects globals such as tcg_tcx,
  page size globals, and possibly others;
* kvm_init() changes the kvm_state global, cpu_interrupt_handler, and possibly
  others;
* xen_init() changes the xen_xc global, and registers a change state handler.

With the new accelerator QOM classes, initialization may now be split in two
steps:
* instance_init() will do basic initialization that doesn't affect any global
  state and don't need MachineState or MachineClass data. This will allow
  probing code to safely create multiple accelerator objects on the fly just
  for reporting host/accelerator capabilities, for example.
* accel_init_machine()/init_machine() will save the accelerator object in
  MachineState, and do initialization steps which still affect global state,
  machine state, or that need data from MachineClass or MachineState.

To clarify the difference between those two steps, rename init() to
init_machine().

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:16 +02:00
Eduardo Habkost
d95c8527e9 accel: Move accel init/allowed code to separate function
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:16 +02:00
Eduardo Habkost
32592e112f accel: Remove tcg_available() function
As the function always return 1, it is not needed anymore.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:15 +02:00
Eduardo Habkost
3a6ce5147f accel: Move qtest accel registration to qtest.c
As qtest_availble() returns 1 only when CONFIG_POSIX is set, keep
setting AccelClass.available to keep current behavior (this is different
from what we did for KVM and Xen).

This also allows us to make qtest_init_accel() static.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:15 +02:00
Eduardo Habkost
b152b05a35 accel: Move Xen registration code to xen-common.c
Note that this has an user-visible side-effect: instead of reporting
"Xen is not supported for this target", QEMU binaries not supporting Xen
will report "xen accelerator does not exist".

As xen_available() always return 1 when CONFIG_XEN is enabled, we don't
need to set AccelClass.available anymore. xen_enabled() is not being
removed yet, but only because vl.c is still using it.

This also allows us to make xen_init() static.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:15 +02:00
Eduardo Habkost
782c3f2939 accel: Move KVM accel registration to kvm-all.c
Note that this has an user-visible side-effect: instead of reporting
"KVM is not supported for this target", QEMU binaries not supporting KVM
will report "kvm accelerator does not exist".

As kvm_availble() always return 1 when CONFIG_KVM is enabled, we don't
need to set AccelClass.available anymore. kvm_enabled() is not being
completely removed yet only because qmp_query_kvm() still uses it.

This also allows us to make kvm_init() static.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:15 +02:00
Eduardo Habkost
b31f9acaaa accel: Report unknown accelerator as "not found" instead of "does not exist"
As the accelerator classes won't be registered anymore if they are not
enabled at compile time, saying "does not exist" may be misleading, as
the accelerator may be simply disabled. Change the wording to just say
"not found".

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:15 +02:00
Eduardo Habkost
f6dfb83547 accel: Make AccelClass.available() optional
When we move accel classes outside accel.c, the available() function
won't be necessary anymore, because the classes will be registered only
if the accelerator code is really enabled at build time.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:15 +02:00
Eduardo Habkost
b14a0b7469 accel: Use QOM classes for accel types
Instead of having a static AccelType array, register a class for each
accelerator type, and use class name lookup to find accelerator
information.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:15 +02:00
Eduardo Habkost
a224655200 accel: Move accel name lookup to separate function
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:15 +02:00
Eduardo Habkost
e8b466ef95 accel: Simplify configure_accelerator() using AccelType *acc variable
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:15 +02:00
Eduardo Habkost
e54adde615 accel: Create AccelType typedef
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:15 +02:00
Eduardo Habkost
a1a9cb0ccd accel: Move accel code to accel.c
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:15 +02:00
Eduardo Habkost
2067444945 vl.c: Small coding style fix
Just to make checkpatch.pl happy when moving the code.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:14 +02:00
Corey Minyard
01ca519f24 qemu-char: Print the remote and local addresses for a socket
It seems that it might be a good idea to know what is at the remote
end of a socket for tracking down issues.  So add that to the
socket filename.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:14 +02:00
Corey Minyard
5dd1f02b4b qemu-char: Add reconnecting to client sockets
Adds a "reconnect" option to socket backends that gives a reconnect
timeout.  This only applies to client sockets.  If the other end
of a socket closes the connection, qemu will attempt to reconnect
after the given number of seconds.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:14 +02:00
Corey Minyard
16cc4ffe34 qemu-char: set socket filename to disconnected when not connected
This way we can tell if the socket is connected or not.  It also splits
the string conversions out into separate functions to make this more
convenient.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:14 +02:00
Corey Minyard
cfb429cb1a qemu-char: Move some items into TCPCharDriver
This keeps them from having to be passed around and makes them
available for later functions, like printing and reconnecting.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:14 +02:00
Corey Minyard
43ded1a0d2 qemu-char: Rework qemu_chr_open_socket() for reconnect
Move all socket configuration to qmp_chardev_open_socket().
qemu_chr_open_socket_fd() just opens the socket.  This is getting ready
for the reconnect code, which will call open_sock_fd() on a reconnect
attempt.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:14 +02:00
Corey Minyard
9f781168c5 qemu-char: Make the filename size for a chardev a #define
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-04 08:59:14 +02:00
Markus Armbruster
f5bebbbb28 util: Emancipate id_wellformed() from QemuOpts
IDs have long spread beyond QemuOpts: not everything with an ID
necessarily goes through QemuOpts.  Commit 9aebf3b is about such a
case: block layer names are meant to be well-formed IDs, but some of
them don't go through QemuOpts, and thus weren't checked.  The commit
fixed that the straightforward way: rename the internal QemuOpts
helper id_wellformed() to qemu_opts_id_wellformed() and give it
external linkage.

Instead of using it directly in block.c, the commit adds wrapper
bdrv_is_valid_name(), probably to hide the connection to QemuOpts.

Go one logical step further: emancipate IDs from QemuOpts.  Rename the
function back to id_wellformed(), and put it in another file.  While
there, clean up its value to bool.  Peel off the bdrv_is_valid_name()
wrapper.

[Replaced stray return 0 with return false to match bool returns used
elsewhere in id_wellformed().
--Stefan]

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
John Snow
d93162e13c q35/ahci: Pick up -cdrom and -hda options
This patch implements the backend for the Q35 board
for us to be able to pick up and use drives defined
by the -cdrom, -hda, or -drive if=ide shorthand options.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-id: 1412187569-23452-7-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
John Snow
6b9e03a4e7 qtest/bios-tables: Correct Q35 command line
If the Q35 board types are to begin recognizing
and decoding syntactic sugar for drive/device
declarations, then workarounds found within
the qtests suite need to be adjusted to prevent
any test failures after the fix.

bios-tables-test improperly uses this cli:
-drive file=etc,id=hd -device ide-hd,drive=hd

Which will create a drive and device due to
the lack of specifying if=none. Then, it will
attempt to create a second device and fail.

This patch corrects this test to always use
the full, non-sugared -device/-drive syntax
for both PC and Q35.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-id: 1412187569-23452-6-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
John Snow
d8f94e1bb2 ide: Update ide_drive_get to be HBA agnostic
Instead of duplicating the logic for the if_ide
(bus,unit) mappings, rely on the blockdev layer
for managing those mappings for us, and use the
drive_get_by_index call instead.

This allows ide_drive_get to work for AHCI HBAs
as well, and can be used in the Q35 initialization.

Lastly, change the nature of the argument to
ide_drive_get so that represents the number of
total drives we can support, and not the total
number of buses. This will prevent array overflows
if the units-per-default-bus property ever needs
to be adjusted for compatibility reasons.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-id: 1412187569-23452-5-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
John Snow
1602651833 pc/vl: Add units-per-default-bus property
This patch adds the 'units_per_default_bus' property which
allows individual boards to declare their desired
index => (bus,unit) mapping for their default HBA, so that
boards such as Q35 can specify that its default if_ide HBA,
AHCI, only accepts one unit per bus.

This property only overrides the mapping for drives matching
the block_default_type interface.

This patch also adds this property to *all* past and present
Q35 machine types. This retroactive addition is justified
because the previous erroneous index=>(bus,unit) mappings
caused by lack of such a property were not utilized due to
lack of initialization code in the Q35 init routine.

Further, semantically, the Q35 board type has always had the
property that its default HBA, AHCI, only accepts one unit per
bus. The new code added to add devices to drives relies upon
the accuracy of this mapping. Thus, the property is applied
retroactively to reduce complexity of allowing IDE HBAs with
different units per bus.

Examples:

Prior to this patch, all IDE HBAs were assumed to use 2 units
per bus (Master, Slave). When using Q35 and AHCI, however, we
only allow one unit per bus.

-hdb foo.qcow2 would become index=1, or bus=0,unit=1.
-hdd foo.qcow2 would become index=3, or bus=1,unit=1.
-drive file=foo.qcow2,index=5 becomes bus=2,unit=1.

These are invalid for AHCI. They now become, under Q35 only:

-hdb foo.qcow2 --> index=1, bus=1, unit=0.
-hdd foo.qcow2 --> index=3, bus=3, unit=0.
-drive file=foo.qcow2,index=5 --> bus=5,unit=0.

The mapping is adjusted based on the fact that the default IF
for the Q35 machine type is IF_IDE, and units-per-default-bus
overrides the IDE mapping from its default of 2 units per bus
to just 1 unit per bus.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-id: 1412187569-23452-4-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
John Snow
21dff8cf38 blockdev: Allow overriding if_max_dev property
The if_max_devs table as in the past been an immutable
default that controls the mapping of index => (bus,unit)
for all boards and all HBAs for each interface type.

Since adding this mapping information to the HBA device
itself is currently unwieldly from the perspective of
retrieving this information at option parsing time
(e.g, within drive_new), we consider the alternative
of marking the if_max_devs table mutable so that
later configuration and initialization can adjust the
mapping at will, but only up until a drive is added,
at which point the mapping is finalized.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-id: 1412187569-23452-3-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
John Snow
a66c9dc734 blockdev: Orphaned drive search
When users use command line options like -hda, -cdrom,
or even -drive if=ide, it is up to the board initialization
routines to pick up these drives and create backing
devices for them.

Some boards, like Q35, have not been doing this.
However, there is no warning explaining why certain
drive specifications are just silently ignored,
so this function adds a check to print some warnings
to assist users in debugging these sorts of issues
in the future.

This patch will not warn about drives added with if_none,
for which it is not possible to tell in advance if
the omission of a backing device is an issue.

A warning in these cases is considered appropriate.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-id: 1412187569-23452-2-git-send-email-jsnow@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
Kevin Wolf
cf77b2d25e qemu-iotests: Fix supported cache modes for 052
The requirement for this test case is really "no O_DIRECT", because the
temporary snapshot for BDRV_O_SNAPSHOT is created in /tmp, which often
is a tmpfs.

Commit f210a83c ('qemu-iotests: Add _default_cache_mode and
_supported_cache_modes') turned the restriction into writethrough-only,
but that's not really necessary.

Allow to run the test for any non-O_DIRECT cache modes, and use the
global default of writeback if no cache mode is specified.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-id: 1412076430-11623-3-git-send-email-kwolf@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
Kevin Wolf
d9323e9b20 make check-block: Use default cache modes
When qemu-iotests only gave a choice between cache=none and
cache=writethrough, we picked cache=none because it was the option that
would complete the test in finite time. Some tests could only work for
one of the two options and would be skipped with cache=none, but that
was an acceptable trade-off at the time.

Today, however, qemu-iotests is a bit more flexible than that and you
can specify any of the cache modes supported by qemu. The default is
writeback, like in qemu, which is fast and (unlike cache=none) compatible
with any host filesystem. Test cases that have specific requirements for
the cache mode can also specify a different default.

In order to get a fast test run that works everywhere and doesn't skip
tests that need a different cache mode, not specifying any cache mode
and instead relying on the default is the best we can do today.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-id: 1412076430-11623-2-git-send-email-kwolf@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
Jun Li
20d6cd47d0 Modify qemu_opt_rename to realize renaming all items in opts
Add realization of rename all items in opts for qemu_opt_rename.
e.g:
When add bps twice in command line, need to rename all bps to
throttling.bps-total.

This patch solved following bug:
Bug 1145586 - qemu-kvm will give strange hint when add bps twice for a drive
ref:https://bugzilla.redhat.com/show_bug.cgi?id=1145586

[Resolved conflict with commit 5abbf0ee4d
("block: Catch simultaneous usage of options and their aliases").  Check
for simultaneous use first, and then loop over all options.
--Stefan]

Signed-off-by: Jun Li <junmuzi@gmail.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1411537527-16715-1-git-send-email-junmuzi@gmail.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
Fam Zheng
d1319b077a vmdk: Fix integer overflow in offset calculation
This fixes the bug introduced by commit c6ac36e (vmdk: Optimize cluster
allocation).

$ ~/build/master/qemu-io /stor/vm/arch.vmdk -c 'write 2G 1k'
write failed: Invalid argument

Reported-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Message-id: 1411437381-11234-1-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
Markus Armbruster
fbf28a4328 block: Drop superfluous conditionals around qemu_opts_del()
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1411999675-14533-1-git-send-email-armbru@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
Richard W.M. Jones
18fe46d79a ssh: Don't crash if either host or path is not specified.
$ ./qemu-img create -f qcow2 overlay \
    -b 'json: { "file.driver":"ssh",
                "file.host":"localhost",
                "file.host_key_check":"no" }'
qemu-img: qobject/qdict.c:193: qdict_get_obj: Assertion `obj != ((void *)0)' failed.
Aborted

A similar crash also happens if the file.host field is omitted.

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

Bug found and reported by Jun Li.

Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
Zhang Haoyu
af95738754 snapshot: fix referencing wrong variable in while loop in do_delvm
The while loop variabal is "bs1",
but "bs" is always passed to bdrv_snapshot_delete_by_id_or_name.
Broken in commit a89d89d, v1.7.0.

Signed-off-by: Zhang Haoyu <zhanghy@sangfor.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-10-03 10:30:33 +01:00
Peter Maydell
b00a0ddb31 Merge remote-tracking branch 'remotes/kraxel/tags/pull-input-20141002-1' into staging
input monitor patches: fix send-key release ordering
and new input-send-event command

# gpg: Signature made Thu 02 Oct 2014 09:10:44 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-input-20141002-1:
  add input-send-event command
  input: fix send-key monitor command release event ordering

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-10-02 15:01:48 +01:00
Peter Maydell
53b98718f1 Merge remote-tracking branch 'remotes/kraxel/tags/pull-console-20141002-1' into staging
pixman: fix qemu_default_pixman_format (32bpp non-native endian)

# gpg: Signature made Thu 02 Oct 2014 08:47:20 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-console-20141002-1:
  pixman: fix qemu_default_pixman_format (32bpp non-native endian)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-10-02 13:23:56 +01:00
Peter Maydell
fbcaca994d Merge remote-tracking branch 'remotes/kraxel/tags/pull-vga-20141002-1' into staging
vga: cleanups, prepare for endianness switching

# gpg: Signature made Thu 02 Oct 2014 08:10:49 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-vga-20141002-1:
  vga: Add endian to vmstate
  vga: Make fb endian a common state variable
  vga: Rename vga_template.h to vga-helpers.h
  vga: Remove some "should be done in BIOS" comments
  cirrus: Remove non-32bpp cursor drawing
  vga: Simplify vga_draw_blank() a bit
  vga: Remove rgb_to_pixel indirection
  vga: Separate LE and BE conversion functions
  vga: Remove remainder of old conversion cruft
  vga: Start cutting out non-32bpp conversion support

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-10-02 12:28:50 +01:00
Peter Maydell
1831e15060 Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
This update brings dataplane to virtio-scsi (NOT
yet 100% thread-safe, though, which makes it really, really
experimental.  It also brings asynchronous cancellation to
the SCSI subsystem and implements it in virtio-scsi.  This
is a pretty important feature.  Almost all the work here
was done by Fam Zheng.

I also included the virtio refcount fixes from Gonglei,
because they had a small conflict with virtio-scsi dataplane.

This pull request is using the new subkey 4E6B09D7.

# gpg: Signature made Tue 30 Sep 2014 12:31:02 BST using RSA key ID 4E6B09D7
# gpg: Good signature from "Paolo Bonzini <pbonzini@redhat.com>"
# gpg:                 aka "Paolo Bonzini <bonzini@gnu.org>"

* remotes/bonzini/tags/for-upstream: (39 commits)
  block/iscsi: handle failure on malloc of the allocationmap
  util: introduce bitmap_try_new
  virtio-scsi: Handle TMF request cancellation asynchronously
  scsi: Introduce scsi_req_cancel_async
  scsi: Introduce scsi_req_cancel_complete
  scsi: Drop SCSIReqOps.cancel_io
  scsi: Unify request unref in scsi_req_cancel
  scsi-generic: Handle canceled request in scsi_command_complete
  scsi: Drop scsi_req_abort
  virtio-scsi: Process ".iothread" property
  virtio-scsi: Call bdrv_io_plug/bdrv_io_unplug in cmd request handling
  virtio-scsi: Batched prepare for cmd reqs
  virtio-scsi: Two stages processing of cmd request
  virtio-scsi: Add migration state notifier for dataplane code
  virtio-scsi: Hook up with dataplane
  virtio-scsi-dataplane: Code to run virtio-scsi on iothread
  virtio-scsi: Add VirtIOSCSIVring in VirtIOSCSIReq
  virtio-scsi: Add 'iothread' property to virtio-scsi
  virtio: add a wrapper for virtio-backend initialization
  virtio-9p: fix virtio-9p child refcount in transports
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-09-30 16:45:35 +01:00
Peter Maydell
7be3c1408a Merge remote-tracking branch 'remotes/kraxel/tags/pull-audio-20140930-1' into staging
ac97: register reset via qom

# gpg: Signature made Tue 30 Sep 2014 12:32:29 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-audio-20140930-1:
  ac97: register reset via qom

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-09-30 15:03:27 +01:00
Peter Maydell
2e456b2b60 Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pci, pc, virtio, misc bugfixes

A bunch of bugfixes.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Mon 29 Sep 2014 17:59:57 BST using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"

* remotes/mst/tags/for_upstream:
  vl: Adjust the place of calling mlockall to speedup VM's startup
  pc-dimm: Don't check dimm->node when there is non-NUMA config
  pci-hotplug-old: avoid losing error message
  Revert "virtio-pci: fix migration for pci bus master"
  loader: g_realloc(p, 0) frees and returns NULL, simplify

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-09-30 13:09:40 +01:00
Benjamin Herrenschmidt
c3b1060514 vga: Add endian to vmstate
Include the endian state in the migration stream as an optional
subsection which we only include when the endian isn't the default,
thus enabling backward compatibility of the common case.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Changes by kraxel:
 * Remove bochs dispi interface changes.  We'll do that in
   a different way to make sure we don't conflict with
   possible future bochs dispi interface changes.
 * keep live migration bits.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2014-09-30 13:34:09 +02:00
Benjamin Herrenschmidt
2c7d8736af vga: Make fb endian a common state variable
And initialize it based on target endian

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2014-09-30 13:34:09 +02:00
Benjamin Herrenschmidt
e657d8ef3c vga: Rename vga_template.h to vga-helpers.h
It's no longer a template, we only instanciate the file once.

Keep it a #included file so the functions remain static.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2014-09-30 13:34:09 +02:00
Benjamin Herrenschmidt
ace89b8ff2 vga: Remove some "should be done in BIOS" comments
Not all platforms have a VGA BIOS, powerpc typically relies on
using the DISPI interface to initialize the card.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2014-09-30 13:34:09 +02:00
Benjamin Herrenschmidt
70a041fe2c cirrus: Remove non-32bpp cursor drawing
We only draw cursor on non-shared surfaces (so it seems...) and
these are always 32bpp

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2014-09-30 13:34:09 +02:00
Benjamin Herrenschmidt
2c79f2a2ec vga: Simplify vga_draw_blank() a bit
The test for surface_bits_per_pixel() isn't necessary anymore,
the 8bpp case never happens.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2014-09-30 13:34:09 +02:00
Benjamin Herrenschmidt
d3c2343af0 vga: Remove rgb_to_pixel indirection
We always use rgb_to_pixel32 nowadays.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2014-09-30 13:34:09 +02:00
Benjamin Herrenschmidt
46c3a8c8eb vga: Separate LE and BE conversion functions
Provide different functions for converting from an LE vs a BE
framebuffer. We cannot rely on the simple cases always being
shared surfaces since cirrus will need to always shadow for
cursor emulation, so we need the full set of functions to
be able to later handle runtime switching.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>\
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2014-09-30 13:34:09 +02:00
Benjamin Herrenschmidt
d2e043a804 vga: Remove remainder of old conversion cruft
All the macros used to generate different versions of vga_template.h
are now unnecessary, take them all out and remove the _32 suffix from
most functions.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2014-09-30 13:34:09 +02:00
Benjamin Herrenschmidt
9e057c0b09 vga: Start cutting out non-32bpp conversion support
Nowadays, we either share a surface with the host, or we create
a 32bpp ARGB console surface.

So we only need to draw/convert to 32bpp, enabling us to remove
all but one instance of vga_template.h inclusion (to be further
cleaned up), rgb_to_pixel_* etc...

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2014-09-30 13:34:09 +02:00
Gerd Hoffmann
89ec031b09 pixman: fix qemu_default_pixman_format (32bpp non-native endian)
Bug breaks SDL display of bigendian guests on little endian hosts.

Reported-by: BALATON Zoltan <balaton@eik.bme.hu>
Reported-by: Valentin Manea <valentin.manea@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-09-30 13:34:04 +02:00
Peter Lieven
a9fe4c957b block/iscsi: handle failure on malloc of the allocationmap
Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 13:30:51 +02:00
Peter Lieven
be4d57c1ea util: introduce bitmap_try_new
regular bitmap_new simply aborts if the memory allocation fails.
bitmap_try_new returns NULL on failure and allows for proper
error handling.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 13:30:51 +02:00
Fam Zheng
49e7e31aa0 virtio-scsi: Handle TMF request cancellation asynchronously
For VIRTIO_SCSI_T_TMF_ABORT_TASK and VIRTIO_SCSI_T_TMF_ABORT_TASK_SET,
use scsi_req_cancel_async to start the cancellation.

Because each tmf command may cancel multiple requests, we need to use a
counter to track the number of remaining requests we still need to wait
for.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 13:30:51 +02:00
Fam Zheng
8e0a9320e9 scsi: Introduce scsi_req_cancel_async
Devices will call this function to start an asynchronous cancellation. The
bus->info->cancel will be called after the request is canceled.

Devices will probably need to track a separate TMF request that triggers this
cancellation, and wait until the cancellation is done before completing it. So
we store a notifier list in SCSIRequest and in scsi_req_cancel_complete we
notify them.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 13:30:51 +02:00
Fam Zheng
d5776465ee scsi: Introduce scsi_req_cancel_complete
Let the aio cb do the clean up and notification job after scsi_req_cancel, in
preparation for asynchronous cancellation.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 13:30:51 +02:00
Fam Zheng
a83cfd12d9 scsi: Drop SCSIReqOps.cancel_io
The only two implementations are identical to each other, with nothing specific
to device: they only call bdrv_aio_cancel with the SCSIRequest.aiocb.

Let's move it to scsi-bus.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 13:30:51 +02:00
Fam Zheng
3df9caf88f scsi: Unify request unref in scsi_req_cancel
Before, scsi_req_cancel will take ownership of the canceled request and unref
it. We did this because we didn't know whether AIO CB will be called or not
during the cancelling, so we set the io_canceled flag before calling it, and
skip unref in the potentially called callbacks, which is not very nice.

Now, bdrv_aio_cancel has a stricter contract that the completion callbacks are
always called, so we can remove the checks of req->io_canceled and just unref
it in callbacks.

It will also make implementing asynchronous cancellation easier.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 13:30:51 +02:00
Fam Zheng
6c25fa6cf8 scsi-generic: Handle canceled request in scsi_command_complete
Now that we always called the cb in bdrv_aio_cancel, let's make scsi-generic
callbacks check io_canceled flag similarly to scsi-disk.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 13:30:51 +02:00
Fam Zheng
eda470e41a scsi: Drop scsi_req_abort
The only user of this function is spapr_vscsi.c. We can convert to
scsi_req_cancel plus adding a check in vscsi_request_cancelled.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
[Drop prototype. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 13:30:50 +02:00
Peter Maydell
45c270b1ea Merge remote-tracking branch 'remotes/rth/tags/tcg-next-201400729' into staging
tcg updates

# gpg: Signature made Mon 29 Sep 2014 19:58:04 BST using RSA key ID 4DD0279B
# gpg: Good signature from "Richard Henderson <rth7680@gmail.com>"
# gpg:                 aka "Richard Henderson <rth@redhat.com>"
# gpg:                 aka "Richard Henderson <rth@twiddle.net>"

* remotes/rth/tags/tcg-next-201400729:
  tcg: Always enable TCGv type checking
  qemu/compiler: Define QEMU_ARTIFICIAL
  tcg-aarch64: Use 32-bit loads for qemu_ld_i32
  tcg-sparc: Use UMULXHI instruction
  tcg-sparc: Rename ADDX/SUBX insns
  tcg-sparc: Use ADDXC in setcond_i64
  tcg-sparc: Fix setcond_i32 uninitialized value
  tcg-sparc: Use ADDXC in addsub2_i64
  tcg-sparc: Support addsub2_i64

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-09-30 11:52:41 +01:00
Fam Zheng
9786b592a9 virtio-scsi: Process ".iothread" property
We are ready, now let's effectively enable dataplane.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:11:20 +02:00
Fam Zheng
5170f40b10 virtio-scsi: Call bdrv_io_plug/bdrv_io_unplug in cmd request handling
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:11:20 +02:00
Fam Zheng
1880ad4f4e virtio-scsi: Batched prepare for cmd reqs
Queue the popped requests while calling
virtio_scsi_handle_cmd_req_prepare(), then submit them after all
prepared.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:11:20 +02:00
Fam Zheng
359eea71d9 virtio-scsi: Two stages processing of cmd request
Mechanical change, in preparation for bdrv_io_plug/bdrv_io_unplug.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:11:20 +02:00
Fam Zheng
dfb37cf7fa virtio-scsi: Add migration state notifier for dataplane code
Similar to virtio-blk-dataplane, we stop the iothread while migration
starts and restart it when migration finishes.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:11:20 +02:00
Fam Zheng
63c7e54268 virtio-scsi: Hook up with dataplane
This enables the virtio-scsi-dataplane code by setting the iothread
in virtio-scsi device, and makes any function that is called by
back from dataplane to cooperate with the caller: they need to be
vring/iothread aware when handling the requests and using scsi devices
on the bus.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:11:20 +02:00
Fam Zheng
91cb1c9b56 virtio-scsi-dataplane: Code to run virtio-scsi on iothread
This implements the core part of dataplane feature of virtio-scsi.

A few fields are added in VirtIOSCSICommon to maintain the dataplane
status. These fields are managed by a new source file:
virtio-scsi-dataplane.c.

Most code in this file will run on an iothread, unless otherwise
commented as in a global mutex context, such as those functions to
start, stop and setting the iothread property.

Upon start, we set up guest/host event notifiers, in a same way as
virtio-blk does. The handlers then pop request from vring and call into
virtio-scsi.c functions to process it. So we need to make sure make all
those called functions work with iothread, too.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:11:20 +02:00
Fam Zheng
244e2898b7 virtio-scsi: Add VirtIOSCSIVring in VirtIOSCSIReq
Move VirtIOSCSIReq to header and add one field "vring" as a wrapper
structure of Vring, VirtIOSCSIVring.

This is necessary for coming dataplane code that runs uses vring on
iothread.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:11:20 +02:00
Fam Zheng
19d339f11d virtio-scsi: Add 'iothread' property to virtio-scsi
Similar to this property in virtio-blk for dataplane, add it as a QOM
link in virtio-scsi and an alias in virtio-scsi-pci and virtio-scsi-ccw,
in order to assign an iothread to the device.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:11:20 +02:00
Gonglei
c8075caf19 virtio: add a wrapper for virtio-backend initialization
For better code sharing, add a helper function that handles
reference counting of the virtio backend for virtio proxy devices.

Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:09:59 +02:00
Gonglei
8f3d60e568 virtio-9p: fix virtio-9p child refcount in transports
object_initialize() leaves the object with a refcount of 1.
object_property_add_child() adds its own reference which is
dropped again when the property is deleted.

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

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

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:09:59 +02:00
Gonglei
48833071d9 virtio-9p: use aliases instead of duplicate qdev properties
virtio-9p-pci all duplicate the qdev properties of their
V9fsState child. This approach does not work well with
string or pointer properties since we must be careful
about leaking or double-freeing them.

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

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:09:56 +02:00
Gonglei
91ba212088 virtio-balloon: fix virtio-balloon child refcount in transports
object_initialize() leaves the object with a refcount of 1.
object_property_add_child() adds its own reference which is dropped
again when the property is deleted.

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

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

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:09:31 +02:00
Gonglei
352fa88dfb virtio-rng: fix virtio-rng child refcount in transports
object_initialize() leaves the object with a refcount of 1.
object_property_add_child() adds its own reference which is dropped
again when the property is deleted.

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

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

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:09:24 +02:00
Gonglei
8ee486ae33 virtio-rng: use aliases instead of duplicate qdev properties
virtio-rng-{pci, s390, ccw} all duplicate the
qdev properties of their VirtIORNG child.
This approach does not work well with string or pointer
properties since we must be careful about leaking or
double-freeing them.

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

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:09:21 +02:00
Gonglei
e77ca8b92a virtio-serial: fix virtio-serial child refcount in transports
object_initialize() leaves the object with a refcount of 1.
object_property_add_child() adds its own reference which is dropped
again when the property is deleted.

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

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

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:09:12 +02:00
Gonglei
4f456d8025 virtio-serial: use aliases instead of duplicate qdev properties
virtio-serial-{pci, s390, ccw} all duplicate the
qdev properties of their VirtIOSerial child.
This approach does not work well with string or pointer
properties since we must be careful about leaking or
double-freeing them.

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

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:09:03 +02:00
Gonglei
1312f12bcc virtio/vhost-scsi: fix virtio-scsi/vhost-scsi child refcount in transports
object_initialize() leaves the object with a refcount of 1.
object_property_add_child() adds its own reference which is dropped
again when the property is deleted.

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

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

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:08:56 +02:00
Gonglei
c39343fd81 virtio/vhost-scsi: use aliases instead of duplicate qdev properties
{virtio, vhost}-scsi-{pci, s390, ccw} all duplicate the
qdev properties of their VirtIOSCSI/VHostSCSI child.
This approach does not work well with string or pointer
properties since we must be careful about leaking or
double-freeing them.

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

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:08:41 +02:00
Gonglei
6a0c6b5978 virtio-net: fix virtio-net child refcount in transports
object_initialize() leaves the object with a refcount of 1.
object_property_add_child() adds its own reference which is dropped
again when the property is deleted.

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

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

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:08:38 +02:00
Gonglei
7779edfeb1 virtio-net: use aliases instead of duplicate qdev properties
virtio-net-pci, virtio-net-s390, and virtio-net-ccw all duplicate the
qdev properties of their VirtIONet child. This approach does not work
well with string or pointer properties since we must be careful about
leaking or double-freeing them.

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

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-30 11:08:16 +02:00
Richard Henderson
b6c73a6d45 tcg: Always enable TCGv type checking
Instead of using structures, which imply some amount of overhead
on certain ABIs, use pointer types.

This actually reduces the size of the binaries vs a NON-debug
build on ppc64 and x86_64, due to a reduction in the number of
sign-extension insns.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-09-29 14:55:28 -04:00
Richard Henderson
58099c8066 qemu/compiler: Define QEMU_ARTIFICIAL
The combination of always_inline + artificial allows tiny inline
functions to be written that do not interfere with debugging.
In particular, gdb will not step into an artificial function.

The always_inline attribute was introduced in gcc 4.2,
and the artificial attribute was introduced in gcc 4.3.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-09-29 14:55:28 -04:00
Richard Henderson
9c53889ba3 tcg-aarch64: Use 32-bit loads for qemu_ld_i32
The "old" qemu_ld opcode did not specify the size of the result,
and so we had to assume full register width.  With the new opcodes,
we can narrow the result.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-09-29 14:55:28 -04:00
Richard Henderson
de8301e542 tcg-sparc: Use UMULXHI instruction
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-09-29 14:55:27 -04:00
Richard Henderson
c470b663f7 tcg-sparc: Rename ADDX/SUBX insns
The pre-v9 ADDX/SUBX insns were renamed ADDC/SUBC for v9.
Standardizing on the v9 name makes things less confusing.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-09-29 14:55:27 -04:00
Richard Henderson
9d6a7a8542 tcg-sparc: Use ADDXC in setcond_i64
Similar to the ADDC tricks we use in setcond_i32.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-09-29 14:55:27 -04:00
Richard Henderson
321b6c0585 tcg-sparc: Fix setcond_i32 uninitialized value
We failed to swap c1 and c2 correctly for NE c2 == 0.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-09-29 14:55:27 -04:00
Richard Henderson
90379ca84e tcg-sparc: Use ADDXC in addsub2_i64
On T4 and newer Sparc chips we have an add-with-carry insn
that takes its input from %xcc instead of %icc.

Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-09-29 14:55:27 -04:00
Richard Henderson
609ac1e164 tcg-sparc: Support addsub2_i64
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-09-29 14:55:26 -04:00
zhanghailiang
28d16f38d0 vl: Adjust the place of calling mlockall to speedup VM's startup
If we configure mlock=on and memory policy=bind at the same time,
It will consume lots of time for system to treat with memory,
especially when call mbind behind mlockall.

Adjust the place of calling mlockall, calling mbind before mlockall
can remarkably reduce the time of VM's startup.

Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-09-29 19:44:04 +03:00
zhanghailiang
fc50ff0666 pc-dimm: Don't check dimm->node when there is non-NUMA config
It should not break memory hotplug feature if there is non-NUMA option.

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

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

Reviewed-By: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-09-29 19:44:04 +03:00
Gonglei
22b80e85ff pci-hotplug-old: avoid losing error message
When scsi_bus_legacy_add_drive() produces an error,
we will lose the error message. Using error_report
to report it.

Cc: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-09-29 19:44:04 +03:00
Michael S. Tsirkin
45363e46ae Revert "virtio-pci: fix migration for pci bus master"
This reverts commit 4d43d3f3c8.

Reported to break PPC guests.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-09-29 19:44:04 +03:00
Markus Armbruster
8ce3c44c92 loader: g_realloc(p, 0) frees and returns NULL, simplify
Once upon a time, it was decided that qemu_realloc(ptr, 0) should
abort.  Switching to glib retired that bright idea.  A bit of code
that was added to cope with it (commit 3e372cf) is still around.  Bury
it.

See also commit 6528499.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-09-29 19:44:04 +03:00
Gerd Hoffmann
133771477c ac97: register reset via qom
So it gets properly unregistered on hot-unplug.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-09-29 10:20:05 +02:00
Fam Zheng
20e6dca1df virtio-scsi: Make virtio_scsi_push_event public
Later this will be called by dataplane code.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-23 15:41:11 +02:00
Fam Zheng
aa8e8f83d0 virtio-scsi: Make virtio_scsi_free_req public
To share with dataplane code later.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-23 15:41:11 +02:00
Fam Zheng
c505333dab virtio-scsi: Make virtio_scsi_init_req public
To share with datplane code later.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-23 15:41:11 +02:00
Fam Zheng
dc56b7c4fb virtio-scsi: Split virtio_scsi_handle_ctrl_req from virtio_scsi_handle_ctrl
To share with dataplane code.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-23 15:41:11 +02:00
Fam Zheng
bf359a445e virtio-scsi: Split virtio_scsi_handle_cmd_req from virtio_scsi_handle_cmd
This is the "common part" to handle one cmd request. Refactor out for
later usage of dataplane iothread code.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-23 15:41:11 +02:00
Paolo Bonzini
9df7bfddcc virtio-scsi: clean up virtio_scsi_parse_cdb
The command direction according to the guest-passed buffers
is already stored in the VirtIOSCSIReq.  We can use it instead
of computing it again from req->elem.

Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-23 15:40:51 +02:00
Paolo Bonzini
7ce0425575 vhost-scsi: use virtio_ldl_p
This helps for cross-endian configurations.

Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-23 15:40:51 +02:00
Fam Zheng
faf1e1fb4c virtio-scsi: Optimize virtio_scsi_init_req
The VirtQueueElement is a very big structure (>48k!), since it will be
initialzed by virtqueue_pop, we can save the expensive zeroing here.

This saves a few microseconds per request in my test:

[fio-test]      rw         bs         iodepth    jobs       bw         iops       latency
--------------------------------------------------------------------------------------------
Before          read       4k         1          1          110        28269      34
After           read       4k         1          1          131        33745      28

Whereas,

virtio-blk      read       4k         1          1          217        55673      16

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-23 15:40:51 +02:00
Fam Zheng
61e68b3fbd scsi: Optimize scsi_req_alloc
Zeroing sense buffer for each scsi request is not efficient, we can just
leave it uninitialized because sense_len is set to 0.

Move the implicitly zeroed fields to the end of the structure and use a
partial memset.

The explicitly initialized fields (by scsi_req_alloc or scsi_req_new)
are moved to the beginning of the structure, before sense buffer, to
skip the memset.

Also change g_malloc0 to g_slice_alloc.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-09-23 15:40:51 +02:00
173 changed files with 3690 additions and 1893 deletions

View File

@@ -62,6 +62,7 @@ common-obj-$(CONFIG_SPICE) += spice-qemu-char.o
common-obj-y += audio/
common-obj-y += hw/
common-obj-y += accel.o
common-obj-y += ui/
common-obj-y += bt-host.o bt-vhci.o

View File

@@ -127,7 +127,7 @@ endif #CONFIG_BSD_USER
# System emulator target
ifdef CONFIG_SOFTMMU
obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o
obj-y += qtest.o
obj-y += qtest.o bootdevice.o
obj-y += hw/
obj-$(CONFIG_FDT) += device_tree.o
obj-$(CONFIG_KVM) += kvm-all.o

157
accel.c Normal file
View File

@@ -0,0 +1,157 @@
/*
* QEMU System Emulator, accelerator interfaces
*
* Copyright (c) 2003-2008 Fabrice Bellard
* Copyright (c) 2014 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "sysemu/accel.h"
#include "hw/boards.h"
#include "qemu-common.h"
#include "sysemu/arch_init.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "sysemu/qtest.h"
#include "hw/xen/xen.h"
#include "qom/object.h"
#include "hw/boards.h"
int tcg_tb_size;
static bool tcg_allowed = true;
static int tcg_init(MachineState *ms)
{
tcg_exec_init(tcg_tb_size * 1024 * 1024);
return 0;
}
static const TypeInfo accel_type = {
.name = TYPE_ACCEL,
.parent = TYPE_OBJECT,
.class_size = sizeof(AccelClass),
.instance_size = sizeof(AccelState),
};
/* Lookup AccelClass from opt_name. Returns NULL if not found */
static AccelClass *accel_find(const char *opt_name)
{
char *class_name = g_strdup_printf(ACCEL_CLASS_NAME("%s"), opt_name);
AccelClass *ac = ACCEL_CLASS(object_class_by_name(class_name));
g_free(class_name);
return ac;
}
static int accel_init_machine(AccelClass *acc, MachineState *ms)
{
ObjectClass *oc = OBJECT_CLASS(acc);
const char *cname = object_class_get_name(oc);
AccelState *accel = ACCEL(object_new(cname));
int ret;
ms->accelerator = accel;
*(acc->allowed) = true;
ret = acc->init_machine(ms);
if (ret < 0) {
ms->accelerator = NULL;
*(acc->allowed) = false;
object_unref(OBJECT(accel));
}
return ret;
}
int configure_accelerator(MachineState *ms)
{
const char *p;
char buf[10];
int ret;
bool accel_initialised = false;
bool init_failed = false;
AccelClass *acc = NULL;
p = qemu_opt_get(qemu_get_machine_opts(), "accel");
if (p == NULL) {
/* Use the default "accelerator", tcg */
p = "tcg";
}
while (!accel_initialised && *p != '\0') {
if (*p == ':') {
p++;
}
p = get_opt_name(buf, sizeof(buf), p, ':');
acc = accel_find(buf);
if (!acc) {
fprintf(stderr, "\"%s\" accelerator not found.\n", buf);
continue;
}
if (acc->available && !acc->available()) {
printf("%s not supported for this target\n",
acc->name);
continue;
}
ret = accel_init_machine(acc, ms);
if (ret < 0) {
init_failed = true;
fprintf(stderr, "failed to initialize %s: %s\n",
acc->name,
strerror(-ret));
} else {
accel_initialised = true;
}
}
if (!accel_initialised) {
if (!init_failed) {
fprintf(stderr, "No accelerator found!\n");
}
exit(1);
}
if (init_failed) {
fprintf(stderr, "Back to %s accelerator.\n", acc->name);
}
return !accel_initialised;
}
static void tcg_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
ac->name = "tcg";
ac->init_machine = tcg_init;
ac->allowed = &tcg_allowed;
}
#define TYPE_TCG_ACCEL ACCEL_CLASS_NAME("tcg")
static const TypeInfo tcg_accel_type = {
.name = TYPE_TCG_ACCEL,
.parent = TYPE_ACCEL,
.class_init = tcg_accel_class_init,
};
static void register_accel_types(void)
{
type_register_static(&accel_type);
type_register_static(&tcg_accel_type);
}
type_init(register_accel_types);

View File

@@ -1337,11 +1337,6 @@ void cpudef_init(void)
#endif
}
int tcg_available(void)
{
return 1;
}
int kvm_available(void)
{
#ifdef CONFIG_KVM

View File

@@ -335,18 +335,13 @@ void bdrv_register(BlockDriver *bdrv)
QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
}
static bool bdrv_is_valid_name(const char *name)
{
return qemu_opts_id_wellformed(name);
}
/* create a new block device (by default it is empty) */
BlockDriverState *bdrv_new(const char *device_name, Error **errp)
{
BlockDriverState *bs;
int i;
if (*device_name && !bdrv_is_valid_name(device_name)) {
if (*device_name && !id_wellformed(device_name)) {
error_setg(errp, "Invalid device name");
return NULL;
}
@@ -874,7 +869,7 @@ static void bdrv_assign_node_name(BlockDriverState *bs,
}
/* Check for empty string or invalid characters */
if (!bdrv_is_valid_name(node_name)) {
if (!id_wellformed(node_name)) {
error_setg(errp, "Invalid node name");
return;
}

View File

@@ -316,6 +316,13 @@ static bool is_request_lun_aligned(int64_t sector_num, int nb_sectors,
return 1;
}
static unsigned long *iscsi_allocationmap_init(IscsiLun *iscsilun)
{
return bitmap_try_new(DIV_ROUND_UP(sector_lun2qemu(iscsilun->num_blocks,
iscsilun),
iscsilun->cluster_sectors));
}
static void iscsi_allocationmap_set(IscsiLun *iscsilun, int64_t sector_num,
int nb_sectors)
{
@@ -1402,9 +1409,10 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
iscsilun->cluster_sectors = (iscsilun->bl.opt_unmap_gran *
iscsilun->block_size) >> BDRV_SECTOR_BITS;
if (iscsilun->lbprz && !(bs->open_flags & BDRV_O_NOCACHE)) {
iscsilun->allocationmap =
bitmap_new(DIV_ROUND_UP(bs->total_sectors,
iscsilun->cluster_sectors));
iscsilun->allocationmap = iscsi_allocationmap_init(iscsilun);
if (iscsilun->allocationmap == NULL) {
ret = -ENOMEM;
}
}
}
@@ -1497,10 +1505,7 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
if (iscsilun->allocationmap != NULL) {
g_free(iscsilun->allocationmap);
iscsilun->allocationmap =
bitmap_new(DIV_ROUND_UP(sector_lun2qemu(iscsilun->num_blocks,
iscsilun),
iscsilun->cluster_sectors));
iscsilun->allocationmap = iscsi_allocationmap_init(iscsilun);
}
return 0;

View File

@@ -2282,6 +2282,9 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
.lazy_refcounts = s->compatible_features &
QCOW2_COMPAT_LAZY_REFCOUNTS,
.has_lazy_refcounts = true,
.corrupt = s->incompatible_features &
QCOW2_INCOMPAT_CORRUPT,
.has_corrupt = true,
};
}

View File

@@ -517,6 +517,11 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
const char *host, *user, *path, *host_key_check;
int port;
if (!qdict_haskey(options, "host")) {
ret = -EINVAL;
error_setg(errp, "No hostname was specified");
goto err;
}
host = qdict_get_str(options, "host");
if (qdict_haskey(options, "port")) {
@@ -525,6 +530,11 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
port = 22;
}
if (!qdict_haskey(options, "path")) {
ret = -EINVAL;
error_setg(errp, "No path was specified");
goto err;
}
path = qdict_get_str(options, "path");
if (qdict_haskey(options, "user")) {

View File

@@ -1113,7 +1113,7 @@ static int get_cluster_offset(BlockDriverState *bs,
uint32_t min_count, *l2_table;
bool zeroed = false;
int64_t ret;
int32_t cluster_sector;
int64_t cluster_sector;
if (m_data) {
m_data->valid = 0;

View File

@@ -60,7 +60,7 @@ static const char *const if_name[IF_COUNT] = {
[IF_XEN] = "xen",
};
static const int if_max_devs[IF_COUNT] = {
static int if_max_devs[IF_COUNT] = {
/*
* Do not change these numbers! They govern how drive option
* index maps to unit and bus. That mapping is ABI.
@@ -79,6 +79,30 @@ static const int if_max_devs[IF_COUNT] = {
[IF_SCSI] = 7,
};
/**
* Boards may call this to offer board-by-board overrides
* of the default, global values.
*/
void override_max_devs(BlockInterfaceType type, int max_devs)
{
DriveInfo *dinfo;
if (max_devs <= 0) {
return;
}
QTAILQ_FOREACH(dinfo, &drives, next) {
if (dinfo->type == type) {
fprintf(stderr, "Cannot override units-per-bus property of"
" the %s interface, because a drive of that type has"
" already been added.\n", if_name[type]);
g_assert_not_reached();
}
}
if_max_devs[type] = max_devs;
}
/*
* We automatically delete the drive when a device using it gets
* unplugged. Questionable feature, but we can't just drop it.
@@ -111,6 +135,23 @@ void blockdev_auto_del(BlockDriverState *bs)
}
}
/**
* Returns the current mapping of how many units per bus
* a particular interface can support.
*
* A positive integer indicates n units per bus.
* 0 implies the mapping has not been established.
* -1 indicates an invalid BlockInterfaceType was given.
*/
int drive_get_max_devs(BlockInterfaceType type)
{
if (type >= IF_IDE && type < IF_COUNT) {
return if_max_devs[type];
}
return -1;
}
static int drive_index_to_bus_id(BlockInterfaceType type, int index)
{
int max_devs = if_max_devs[type];
@@ -166,6 +207,27 @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
return NULL;
}
bool drive_check_orphaned(void)
{
DriveInfo *dinfo;
bool rs = false;
QTAILQ_FOREACH(dinfo, &drives, next) {
/* If dinfo->bdrv->dev is NULL, it has no device attached. */
/* Unless this is a default drive, this may be an oversight. */
if (!dinfo->bdrv->dev && !dinfo->is_default &&
dinfo->type != IF_NONE) {
fprintf(stderr, "Warning: Orphaned drive without device: "
"id=%s,file=%s,if=%s,bus=%d,unit=%d\n",
dinfo->id, dinfo->bdrv->filename, if_name[dinfo->type],
dinfo->bus, dinfo->unit);
rs = true;
}
}
return rs;
}
DriveInfo *drive_get_by_index(BlockInterfaceType type, int index)
{
return drive_get(type,
@@ -224,9 +286,7 @@ void drive_info_del(DriveInfo *dinfo)
if (!dinfo) {
return;
}
if (dinfo->opts) {
qemu_opts_del(dinfo->opts);
}
g_free(dinfo->id);
QTAILQ_REMOVE(&drives, dinfo, next);
g_free(dinfo->serial);
@@ -550,6 +610,10 @@ static void qemu_opt_rename(QemuOpts *opts, const char *from, const char *to,
"same time", to, from);
return;
}
}
/* rename all items in opts */
while ((value = qemu_opt_get(opts, from))) {
qemu_opt_set(opts, to, value);
qemu_opt_unset(opts, from);
}

258
bootdevice.c Normal file
View File

@@ -0,0 +1,258 @@
/*
* QEMU Boot Device Implement
*
* Copyright (c) 2014 HUAWEI TECHNOLOGIES CO.,LTD.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "sysemu/sysemu.h"
#include "qapi/visitor.h"
#include "qemu/error-report.h"
typedef struct FWBootEntry FWBootEntry;
struct FWBootEntry {
QTAILQ_ENTRY(FWBootEntry) link;
int32_t bootindex;
DeviceState *dev;
char *suffix;
};
static QTAILQ_HEAD(, FWBootEntry) fw_boot_order =
QTAILQ_HEAD_INITIALIZER(fw_boot_order);
void check_boot_index(int32_t bootindex, Error **errp)
{
FWBootEntry *i;
if (bootindex >= 0) {
QTAILQ_FOREACH(i, &fw_boot_order, link) {
if (i->bootindex == bootindex) {
error_setg(errp, "The bootindex %d has already been used",
bootindex);
return;
}
}
}
}
void del_boot_device_path(DeviceState *dev, const char *suffix)
{
FWBootEntry *i;
if (dev == NULL) {
return;
}
QTAILQ_FOREACH(i, &fw_boot_order, link) {
if ((!suffix || !g_strcmp0(i->suffix, suffix)) &&
i->dev == dev) {
QTAILQ_REMOVE(&fw_boot_order, i, link);
g_free(i->suffix);
g_free(i);
break;
}
}
}
void add_boot_device_path(int32_t bootindex, DeviceState *dev,
const char *suffix)
{
FWBootEntry *node, *i;
if (bootindex < 0) {
del_boot_device_path(dev, suffix);
return;
}
assert(dev != NULL || suffix != NULL);
del_boot_device_path(dev, suffix);
node = g_malloc0(sizeof(FWBootEntry));
node->bootindex = bootindex;
node->suffix = g_strdup(suffix);
node->dev = dev;
QTAILQ_FOREACH(i, &fw_boot_order, link) {
if (i->bootindex == bootindex) {
error_report("Two devices with same boot index %d", bootindex);
exit(1);
} else if (i->bootindex < bootindex) {
continue;
}
QTAILQ_INSERT_BEFORE(i, node, link);
return;
}
QTAILQ_INSERT_TAIL(&fw_boot_order, node, link);
}
DeviceState *get_boot_device(uint32_t position)
{
uint32_t counter = 0;
FWBootEntry *i = NULL;
DeviceState *res = NULL;
if (!QTAILQ_EMPTY(&fw_boot_order)) {
QTAILQ_FOREACH(i, &fw_boot_order, link) {
if (counter == position) {
res = i->dev;
break;
}
counter++;
}
}
return res;
}
/*
* This function returns null terminated string that consist of new line
* separated device paths.
*
* memory pointed by "size" is assigned total length of the array in bytes
*
*/
char *get_boot_devices_list(size_t *size, bool ignore_suffixes)
{
FWBootEntry *i;
size_t total = 0;
char *list = NULL;
QTAILQ_FOREACH(i, &fw_boot_order, link) {
char *devpath = NULL, *bootpath;
size_t len;
if (i->dev) {
devpath = qdev_get_fw_dev_path(i->dev);
assert(devpath);
}
if (i->suffix && !ignore_suffixes && devpath) {
size_t bootpathlen = strlen(devpath) + strlen(i->suffix) + 1;
bootpath = g_malloc(bootpathlen);
snprintf(bootpath, bootpathlen, "%s%s", devpath, i->suffix);
g_free(devpath);
} else if (devpath) {
bootpath = devpath;
} else if (!ignore_suffixes) {
assert(i->suffix);
bootpath = g_strdup(i->suffix);
} else {
bootpath = g_strdup("");
}
if (total) {
list[total-1] = '\n';
}
len = strlen(bootpath) + 1;
list = g_realloc(list, total + len);
memcpy(&list[total], bootpath, len);
total += len;
g_free(bootpath);
}
*size = total;
if (boot_strict && *size > 0) {
list[total-1] = '\n';
list = g_realloc(list, total + 5);
memcpy(&list[total], "HALT", 5);
*size = total + 5;
}
return list;
}
typedef struct {
int32_t *bootindex;
const char *suffix;
DeviceState *dev;
} BootIndexProperty;
static void device_get_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
BootIndexProperty *prop = opaque;
visit_type_int32(v, prop->bootindex, name, errp);
}
static void device_set_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
BootIndexProperty *prop = opaque;
int32_t boot_index;
Error *local_err = NULL;
visit_type_int32(v, &boot_index, name, &local_err);
if (local_err) {
goto out;
}
/* check whether bootindex is present in fw_boot_order list */
check_boot_index(boot_index, &local_err);
if (local_err) {
goto out;
}
/* change bootindex to a new one */
*prop->bootindex = boot_index;
add_boot_device_path(*prop->bootindex, prop->dev, prop->suffix);
out:
if (local_err) {
error_propagate(errp, local_err);
}
}
static void property_release_bootindex(Object *obj, const char *name,
void *opaque)
{
BootIndexProperty *prop = opaque;
del_boot_device_path(prop->dev, prop->suffix);
g_free(prop);
}
void device_add_bootindex_property(Object *obj, int32_t *bootindex,
const char *name, const char *suffix,
DeviceState *dev, Error **errp)
{
Error *local_err = NULL;
BootIndexProperty *prop = g_malloc0(sizeof(*prop));
prop->bootindex = bootindex;
prop->suffix = suffix;
prop->dev = dev;
object_property_add(obj, name, "int32",
device_get_bootindex,
device_set_bootindex,
property_release_bootindex,
prop, &local_err);
if (local_err) {
error_propagate(errp, local_err);
g_free(prop);
return;
}
/* initialize devices' bootindex property to -1 */
object_property_set_int(obj, -1, name, NULL);
}

View File

@@ -1175,15 +1175,11 @@ static const struct sparc_opcode sparc_opcodes[] = {
{ "subcc", F3(2, 0x14, 0), F3(~2, ~0x14, ~0)|ASI(~0), "1,2,d", 0, v6 },
{ "subcc", F3(2, 0x14, 1), F3(~2, ~0x14, ~1), "1,i,d", 0, v6 },
{ "subx", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", 0, v6notv9 },
{ "subx", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", 0, v6notv9 },
{ "subc", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", 0, v9 },
{ "subc", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", 0, v9 },
{ "subc", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", 0, v6 },
{ "subc", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", 0, v6 },
{ "subxcc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", 0, v6notv9 },
{ "subxcc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", 0, v6notv9 },
{ "subccc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", 0, v9 },
{ "subccc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", 0, v9 },
{ "subccc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", 0, v6 },
{ "subccc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", 0, v6 },
{ "and", F3(2, 0x01, 0), F3(~2, ~0x01, ~0)|ASI(~0), "1,2,d", 0, v6 },
{ "and", F3(2, 0x01, 1), F3(~2, ~0x01, ~1), "1,i,d", 0, v6 },
@@ -1215,19 +1211,13 @@ static const struct sparc_opcode sparc_opcodes[] = {
{ "addcc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "1,i,d", 0, v6 },
{ "addcc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "i,1,d", 0, v6 },
{ "addx", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", 0, v6notv9 },
{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", 0, v6notv9 },
{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", 0, v6notv9 },
{ "addc", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", 0, v9 },
{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", 0, v9 },
{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", 0, v9 },
{ "addc", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", 0, v6 },
{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", 0, v6 },
{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", 0, v6 },
{ "addxcc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", 0, v6notv9 },
{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", 0, v6notv9 },
{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", 0, v6notv9 },
{ "addccc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", 0, v9 },
{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", 0, v9 },
{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", 0, v9 },
{ "addccc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", 0, v6 },
{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", 0, v6 },
{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", 0, v6 },
{ "smul", F3(2, 0x0b, 0), F3(~2, ~0x0b, ~0)|ASI(~0), "1,2,d", 0, v8 },
{ "smul", F3(2, 0x0b, 1), F3(~2, ~0x0b, ~1), "1,i,d", 0, v8 },
@@ -2042,6 +2032,10 @@ IMPDEP ("impdep2", 0x37),
#undef IMPDEP
{ "addxc", F3F(2, 0x36, 0x011), F3F(~2, ~0x36, ~0x011), "1,2,d", 0, v9b },
{ "addxccc", F3F(2, 0x36, 0x013), F3F(~2, ~0x36, ~0x013), "1,2,d", 0, v9b },
{ "umulxhi", F3F(2, 0x36, 0x016), F3F(~2, ~0x36, ~0x016), "1,2,d", 0, v9b },
};
static const int sparc_num_opcodes = ((sizeof sparc_opcodes)/(sizeof sparc_opcodes[0]));

View File

@@ -625,11 +625,23 @@ void gdb_register_coprocessor(CPUState *cpu,
}
#ifndef CONFIG_USER_ONLY
static const int xlat_gdb_type[] = {
/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */
static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
{
static const int xlat[] = {
[GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
[GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
[GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
};
CPUClass *cc = CPU_GET_CLASS(cpu);
int cputype = xlat[gdbtype];
if (cc->gdb_stop_before_watchpoint) {
cputype |= BP_STOP_BEFORE_ACCESS;
}
return cputype;
}
#endif
static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
@@ -656,11 +668,12 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS:
CPU_FOREACH(cpu) {
err = cpu_watchpoint_insert(cpu, addr, len, xlat_gdb_type[type],
NULL);
if (err)
err = cpu_watchpoint_insert(cpu, addr, len,
xlat_gdb_type(cpu, type), NULL);
if (err) {
break;
}
}
return err;
#endif
default:
@@ -692,7 +705,8 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS:
CPU_FOREACH(cpu) {
err = cpu_watchpoint_remove(cpu, addr, len, xlat_gdb_type[type]);
err = cpu_watchpoint_remove(cpu, addr, len,
xlat_gdb_type(cpu, type));
if (err)
break;
}

View File

@@ -97,7 +97,7 @@ static void clipper_init(MachineState *machine)
/* IDE disk setup. */
{
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
ide_drive_get(hd, MAX_IDE_BUS);
ide_drive_get(hd, ARRAY_SIZE(hd));
pci_cmd646_ide_init(pci_bus, hd, 0);
}

View File

@@ -1321,9 +1321,9 @@ static const MemoryRegionOps ac97_io_nabm_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
static void ac97_on_reset (void *opaque)
static void ac97_on_reset (DeviceState *dev)
{
AC97LinkState *s = opaque;
AC97LinkState *s = container_of(dev, AC97LinkState, dev.qdev);
reset_bm_regs (s, &s->bm_regs[0]);
reset_bm_regs (s, &s->bm_regs[1]);
@@ -1382,9 +1382,8 @@ static int ac97_initfn (PCIDevice *dev)
"ac97-nabm", 256);
pci_register_bar (&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nam);
pci_register_bar (&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm);
qemu_register_reset (ac97_on_reset, s);
AUD_register_card ("ac97", &s->card);
ac97_on_reset (s);
ac97_on_reset (&s->dev.qdev);
return 0;
}
@@ -1413,6 +1412,7 @@ static void ac97_class_init (ObjectClass *klass, void *data)
dc->desc = "Intel 82801AA AC97 Audio";
dc->vmsd = &vmstate_ac97;
dc->props = ac97_properties;
dc->reset = ac97_on_reset;
}
static const TypeInfo ac97_info = {

View File

@@ -2216,9 +2216,6 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp)
error_propagate(errp, err);
return;
}
add_boot_device_path(isa->bootindexA, dev, "/floppy@0");
add_boot_device_path(isa->bootindexB, dev, "/floppy@1");
}
static void sysbus_fdc_initfn(Object *obj)
@@ -2291,8 +2288,6 @@ static Property isa_fdc_properties[] = {
DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs),
DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].bs),
DEFINE_PROP_INT32("bootindexA", FDCtrlISABus, bootindexA, -1),
DEFINE_PROP_INT32("bootindexB", FDCtrlISABus, bootindexB, -1),
DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
0, true),
DEFINE_PROP_END_OF_LIST(),
@@ -2310,11 +2305,24 @@ static void isabus_fdc_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static void isabus_fdc_instance_init(Object *obj)
{
FDCtrlISABus *isa = ISA_FDC(obj);
device_add_bootindex_property(obj, &isa->bootindexA,
"bootindexA", "/floppy@0",
DEVICE(obj), NULL);
device_add_bootindex_property(obj, &isa->bootindexB,
"bootindexB", "/floppy@1",
DEVICE(obj), NULL);
}
static const TypeInfo isa_fdc_info = {
.name = TYPE_ISA_FDC,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(FDCtrlISABus),
.class_init = isabus_fdc_class_init,
.instance_init = isabus_fdc_instance_init,
};
static const VMStateDescription vmstate_sysbus_fdc ={

View File

@@ -24,6 +24,8 @@
#include <hw/hw.h>
#include <hw/pci/msix.h>
#include <hw/pci/pci.h>
#include "sysemu/sysemu.h"
#include "qapi/visitor.h"
#include "nvme.h"
@@ -871,11 +873,53 @@ static void nvme_class_init(ObjectClass *oc, void *data)
dc->vmsd = &nvme_vmstate;
}
static void nvme_get_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
NvmeCtrl *s = NVME(obj);
visit_type_int32(v, &s->conf.bootindex, name, errp);
}
static void nvme_set_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
NvmeCtrl *s = NVME(obj);
int32_t boot_index;
Error *local_err = NULL;
visit_type_int32(v, &boot_index, name, &local_err);
if (local_err) {
goto out;
}
/* check whether bootindex is present in fw_boot_order list */
check_boot_index(boot_index, &local_err);
if (local_err) {
goto out;
}
/* change bootindex to a new one */
s->conf.bootindex = boot_index;
out:
if (local_err) {
error_propagate(errp, local_err);
}
}
static void nvme_instance_init(Object *obj)
{
object_property_add(obj, "bootindex", "int32",
nvme_get_bootindex,
nvme_set_bootindex, NULL, NULL, NULL);
object_property_set_int(obj, -1, "bootindex", NULL);
}
static const TypeInfo nvme_info = {
.name = "nvme",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(NvmeCtrl),
.class_init = nvme_class_init,
.instance_init = nvme_instance_init,
};
static void nvme_register_types(void)

View File

@@ -768,8 +768,6 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
bdrv_set_guest_block_size(s->bs, s->conf->logical_block_size);
bdrv_iostatus_enable(s->bs);
add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0");
}
static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
@@ -794,6 +792,9 @@ static void virtio_blk_instance_init(Object *obj)
(Object **)&s->blk.iothread,
qdev_prop_allow_set_link_before_realize,
OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
device_add_bootindex_property(obj, &s->blk.conf.bootindex,
"bootindex", "/disk@0,0",
DEVICE(obj), NULL);
}
static Property virtio_blk_properties[] = {

View File

@@ -29,6 +29,7 @@
#include "hw/hw.h"
#include "hw/pci/pci.h"
#include "ui/console.h"
#include "ui/pixel_ops.h"
#include "vga_int.h"
#include "hw/loader.h"
@@ -2170,20 +2171,44 @@ static void cirrus_cursor_invalidate(VGACommonState *s1)
}
}
#define DEPTH 8
#include "cirrus_vga_template.h"
static void vga_draw_cursor_line(uint8_t *d1,
const uint8_t *src1,
int poffset, int w,
unsigned int color0,
unsigned int color1,
unsigned int color_xor)
{
const uint8_t *plane0, *plane1;
int x, b0, b1;
uint8_t *d;
#define DEPTH 16
#include "cirrus_vga_template.h"
#define DEPTH 32
#include "cirrus_vga_template.h"
d = d1;
plane0 = src1;
plane1 = src1 + poffset;
for (x = 0; x < w; x++) {
b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
switch (b0 | (b1 << 1)) {
case 0:
break;
case 1:
((uint32_t *)d)[0] ^= color_xor;
break;
case 2:
((uint32_t *)d)[0] = color0;
break;
case 3:
((uint32_t *)d)[0] = color1;
break;
}
d += 4;
}
}
static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
{
CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
DisplaySurface *surface = qemu_console_surface(s->vga.con);
int w, h, bpp, x1, x2, poffset;
int w, h, x1, x2, poffset;
unsigned int color0, color1;
const uint8_t *palette, *src;
uint32_t content;
@@ -2212,6 +2237,8 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
} else {
src += (s->vga.sr[0x13] & 0x3f) * 256;
src += (scr_y - s->hw_cursor_y) * 4;
poffset = 128;
content = ((uint32_t *)src)[0] |
((uint32_t *)(src + 128))[0];
@@ -2229,30 +2256,14 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
x2 = s->vga.last_scr_width;
w = x2 - x1;
palette = s->cirrus_hidden_palette;
color0 = s->vga.rgb_to_pixel(c6_to_8(palette[0x0 * 3]),
color0 = rgb_to_pixel32(c6_to_8(palette[0x0 * 3]),
c6_to_8(palette[0x0 * 3 + 1]),
c6_to_8(palette[0x0 * 3 + 2]));
color1 = s->vga.rgb_to_pixel(c6_to_8(palette[0xf * 3]),
color1 = rgb_to_pixel32(c6_to_8(palette[0xf * 3]),
c6_to_8(palette[0xf * 3 + 1]),
c6_to_8(palette[0xf * 3 + 2]));
bpp = surface_bytes_per_pixel(surface);
d1 += x1 * bpp;
switch (surface_bits_per_pixel(surface)) {
default:
break;
case 8:
vga_draw_cursor_line_8(d1, src, poffset, w, color0, color1, 0xff);
break;
case 15:
vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0x7fff);
break;
case 16:
vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0xffff);
break;
case 32:
vga_draw_cursor_line_32(d1, src, poffset, w, color0, color1, 0xffffff);
break;
}
d1 += x1 * 4;
vga_draw_cursor_line(d1, src, poffset, w, color0, color1, 0xffffff);
}
/***************************************

View File

@@ -1,102 +0,0 @@
/*
* QEMU Cirrus VGA Emulator templates
*
* Copyright (c) 2003 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#if DEPTH == 8
#define BPP 1
#elif DEPTH == 15 || DEPTH == 16
#define BPP 2
#elif DEPTH == 32
#define BPP 4
#else
#error unsupported depth
#endif
static void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1,
const uint8_t *src1,
int poffset, int w,
unsigned int color0,
unsigned int color1,
unsigned int color_xor)
{
const uint8_t *plane0, *plane1;
int x, b0, b1;
uint8_t *d;
d = d1;
plane0 = src1;
plane1 = src1 + poffset;
for (x = 0; x < w; x++) {
b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
#if DEPTH == 8
switch (b0 | (b1 << 1)) {
case 0:
break;
case 1:
d[0] ^= color_xor;
break;
case 2:
d[0] = color0;
break;
case 3:
d[0] = color1;
break;
}
#elif DEPTH == 16
switch (b0 | (b1 << 1)) {
case 0:
break;
case 1:
((uint16_t *)d)[0] ^= color_xor;
break;
case 2:
((uint16_t *)d)[0] = color0;
break;
case 3:
((uint16_t *)d)[0] = color1;
break;
}
#elif DEPTH == 32
switch (b0 | (b1 << 1)) {
case 0:
break;
case 1:
((uint32_t *)d)[0] ^= color_xor;
break;
case 2:
((uint32_t *)d)[0] = color0;
break;
case 3:
((uint32_t *)d)[0] = color1;
break;
}
#else
#error unsupported depth
#endif
d += BPP;
}
}
#undef DEPTH
#undef BPP

View File

@@ -22,41 +22,9 @@
* THE SOFTWARE.
*/
#if DEPTH == 8
#define BPP 1
#define PIXEL_TYPE uint8_t
#elif DEPTH == 15 || DEPTH == 16
#define BPP 2
#define PIXEL_TYPE uint16_t
#elif DEPTH == 32
#define BPP 4
#define PIXEL_TYPE uint32_t
#else
#error unsupport depth
#endif
#ifdef BGR_FORMAT
#define PIXEL_NAME glue(DEPTH, bgr)
#else
#define PIXEL_NAME DEPTH
#endif /* BGR_FORMAT */
#if DEPTH != 15 && !defined(BGR_FORMAT)
static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d,
uint32_t font_data,
uint32_t xorcol,
uint32_t bgcol)
static inline void vga_draw_glyph_line(uint8_t *d, uint32_t font_data,
uint32_t xorcol, uint32_t bgcol)
{
#if BPP == 1
((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
#elif BPP == 2
((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
#else
((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
@@ -65,10 +33,9 @@ static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d,
((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
#endif
}
static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize,
static void vga_draw_glyph8(uint8_t *d, int linesize,
const uint8_t *font_ptr, int h,
uint32_t fgcol, uint32_t bgcol)
{
@@ -77,13 +44,13 @@ static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize,
xorcol = bgcol ^ fgcol;
do {
font_data = font_ptr[0];
glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol);
vga_draw_glyph_line(d, font_data, xorcol, bgcol);
font_ptr += 4;
d += linesize;
} while (--h);
}
static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
static void vga_draw_glyph16(uint8_t *d, int linesize,
const uint8_t *font_ptr, int h,
uint32_t fgcol, uint32_t bgcol)
{
@@ -92,18 +59,16 @@ static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
xorcol = bgcol ^ fgcol;
do {
font_data = font_ptr[0];
glue(vga_draw_glyph_line_, DEPTH)(d,
expand4to8[font_data >> 4],
vga_draw_glyph_line(d, expand4to8[font_data >> 4],
xorcol, bgcol);
glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP,
expand4to8[font_data & 0x0f],
vga_draw_glyph_line(d + 32, expand4to8[font_data & 0x0f],
xorcol, bgcol);
font_ptr += 4;
d += linesize;
} while (--h);
}
static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
static void vga_draw_glyph9(uint8_t *d, int linesize,
const uint8_t *font_ptr, int h,
uint32_t fgcol, uint32_t bgcol, int dup9)
{
@@ -112,28 +77,6 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
xorcol = bgcol ^ fgcol;
do {
font_data = font_ptr[0];
#if BPP == 1
stl_p((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
stl_p(((uint32_t *)d)+1, v);
if (dup9)
((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
else
((uint8_t *)d)[8] = bgcol;
#elif BPP == 2
stl_p(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
stl_p(((uint32_t *)d)+1,
(dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
stl_p(((uint32_t *)d)+2,
(dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
stl_p(((uint32_t *)d)+3, v);
if (dup9)
((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
else
((uint16_t *)d)[8] = bgcol;
#else
((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
@@ -147,7 +90,6 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
((uint32_t *)d)[8] = v;
else
((uint32_t *)d)[8] = bgcol;
#endif
font_ptr += 4;
d += linesize;
} while (--h);
@@ -156,7 +98,7 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
/*
* 4 color mode
*/
static void glue(vga_draw_line2_, DEPTH)(VGACommonState *s1, uint8_t *d,
static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
uint32_t plane_mask, *palette, data, v;
@@ -170,35 +112,29 @@ static void glue(vga_draw_line2_, DEPTH)(VGACommonState *s1, uint8_t *d,
data &= plane_mask;
v = expand2[GET_PLANE(data, 0)];
v |= expand2[GET_PLANE(data, 2)] << 2;
((PIXEL_TYPE *)d)[0] = palette[v >> 12];
((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf];
((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf];
((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf];
((uint32_t *)d)[0] = palette[v >> 12];
((uint32_t *)d)[1] = palette[(v >> 8) & 0xf];
((uint32_t *)d)[2] = palette[(v >> 4) & 0xf];
((uint32_t *)d)[3] = palette[(v >> 0) & 0xf];
v = expand2[GET_PLANE(data, 1)];
v |= expand2[GET_PLANE(data, 3)] << 2;
((PIXEL_TYPE *)d)[4] = palette[v >> 12];
((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
d += BPP * 8;
((uint32_t *)d)[4] = palette[v >> 12];
((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
d += 32;
s += 4;
}
}
#if BPP == 1
#define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v)
#elif BPP == 2
#define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v)
#else
#define PUT_PIXEL2(d, n, v) \
((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
#endif
/*
* 4 color mode, dup2 horizontal
*/
static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
uint32_t plane_mask, *palette, data, v;
@@ -223,7 +159,7 @@ static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
d += BPP * 16;
d += 64;
s += 4;
}
}
@@ -231,7 +167,7 @@ static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
/*
* 16 color mode
*/
static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d,
static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
uint32_t plane_mask, data, v, *palette;
@@ -247,15 +183,15 @@ static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d,
v |= expand4[GET_PLANE(data, 1)] << 1;
v |= expand4[GET_PLANE(data, 2)] << 2;
v |= expand4[GET_PLANE(data, 3)] << 3;
((PIXEL_TYPE *)d)[0] = palette[v >> 28];
((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf];
((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf];
((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf];
((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf];
((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
d += BPP * 8;
((uint32_t *)d)[0] = palette[v >> 28];
((uint32_t *)d)[1] = palette[(v >> 24) & 0xf];
((uint32_t *)d)[2] = palette[(v >> 20) & 0xf];
((uint32_t *)d)[3] = palette[(v >> 16) & 0xf];
((uint32_t *)d)[4] = palette[(v >> 12) & 0xf];
((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
d += 32;
s += 4;
}
}
@@ -263,7 +199,7 @@ static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d,
/*
* 16 color mode, dup2 horizontal
*/
static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
uint32_t plane_mask, data, v, *palette;
@@ -287,7 +223,7 @@ static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
d += BPP * 16;
d += 64;
s += 4;
}
}
@@ -297,7 +233,7 @@ static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
*
* XXX: add plane_mask support (never used in standard VGA modes)
*/
static void glue(vga_draw_line8d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
uint32_t *palette;
@@ -310,7 +246,7 @@ static void glue(vga_draw_line8d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
PUT_PIXEL2(d, 1, palette[s[1]]);
PUT_PIXEL2(d, 2, palette[s[2]]);
PUT_PIXEL2(d, 3, palette[s[3]]);
d += BPP * 8;
d += 32;
s += 4;
}
}
@@ -320,7 +256,7 @@ static void glue(vga_draw_line8d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
*
* XXX: add plane_mask support (never used in standard VGA modes)
*/
static void glue(vga_draw_line8_, DEPTH)(VGACommonState *s1, uint8_t *d,
static void vga_draw_line8(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
uint32_t *palette;
@@ -329,78 +265,101 @@ static void glue(vga_draw_line8_, DEPTH)(VGACommonState *s1, uint8_t *d,
palette = s1->last_palette;
width >>= 3;
for(x = 0; x < width; x++) {
((PIXEL_TYPE *)d)[0] = palette[s[0]];
((PIXEL_TYPE *)d)[1] = palette[s[1]];
((PIXEL_TYPE *)d)[2] = palette[s[2]];
((PIXEL_TYPE *)d)[3] = palette[s[3]];
((PIXEL_TYPE *)d)[4] = palette[s[4]];
((PIXEL_TYPE *)d)[5] = palette[s[5]];
((PIXEL_TYPE *)d)[6] = palette[s[6]];
((PIXEL_TYPE *)d)[7] = palette[s[7]];
d += BPP * 8;
((uint32_t *)d)[0] = palette[s[0]];
((uint32_t *)d)[1] = palette[s[1]];
((uint32_t *)d)[2] = palette[s[2]];
((uint32_t *)d)[3] = palette[s[3]];
((uint32_t *)d)[4] = palette[s[4]];
((uint32_t *)d)[5] = palette[s[5]];
((uint32_t *)d)[6] = palette[s[6]];
((uint32_t *)d)[7] = palette[s[7]];
d += 32;
s += 8;
}
}
#endif /* DEPTH != 15 */
/* XXX: optimize */
/*
* 15 bit color
*/
static void glue(vga_draw_line15_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
#if DEPTH == 15 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
memcpy(d, s, width * 2);
#else
int w;
uint32_t v, r, g, b;
w = width;
do {
v = lduw_p((void *)s);
v = lduw_le_p((void *)s);
r = (v >> 7) & 0xf8;
g = (v >> 2) & 0xf8;
b = (v << 3) & 0xf8;
((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
s += 2;
d += BPP;
d += 4;
} while (--w != 0);
}
static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
int w;
uint32_t v, r, g, b;
w = width;
do {
v = lduw_be_p((void *)s);
r = (v >> 7) & 0xf8;
g = (v >> 2) & 0xf8;
b = (v << 3) & 0xf8;
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
s += 2;
d += 4;
} while (--w != 0);
#endif
}
/*
* 16 bit color
*/
static void glue(vga_draw_line16_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
memcpy(d, s, width * 2);
#else
int w;
uint32_t v, r, g, b;
w = width;
do {
v = lduw_p((void *)s);
v = lduw_le_p((void *)s);
r = (v >> 8) & 0xf8;
g = (v >> 3) & 0xfc;
b = (v << 3) & 0xf8;
((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
s += 2;
d += BPP;
d += 4;
} while (--w != 0);
}
static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
int w;
uint32_t v, r, g, b;
w = width;
do {
v = lduw_be_p((void *)s);
r = (v >> 8) & 0xf8;
g = (v >> 3) & 0xfc;
b = (v << 3) & 0xf8;
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
s += 2;
d += 4;
} while (--w != 0);
#endif
}
/*
* 24 bit color
*/
static void glue(vga_draw_line24_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
int w;
@@ -408,28 +367,39 @@ static void glue(vga_draw_line24_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
w = width;
do {
#if defined(TARGET_WORDS_BIGENDIAN)
r = s[0];
g = s[1];
b = s[2];
#else
b = s[0];
g = s[1];
r = s[2];
#endif
((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
s += 3;
d += BPP;
d += 4;
} while (--w != 0);
}
static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
int w;
uint32_t r, g, b;
w = width;
do {
r = s[0];
g = s[1];
b = s[2];
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
s += 3;
d += 4;
} while (--w != 0);
}
/*
* 32 bit color
*/
static void glue(vga_draw_line32_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
#if DEPTH == 32 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) && !defined(BGR_FORMAT)
#ifndef HOST_WORDS_BIGENDIAN
memcpy(d, s, width * 4);
#else
int w;
@@ -437,25 +407,33 @@ static void glue(vga_draw_line32_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d,
w = width;
do {
#if defined(TARGET_WORDS_BIGENDIAN)
r = s[1];
g = s[2];
b = s[3];
#else
b = s[0];
g = s[1];
r = s[2];
#endif
((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
s += 4;
d += BPP;
d += 4;
} while (--w != 0);
#endif
}
#undef PUT_PIXEL2
#undef DEPTH
#undef BPP
#undef PIXEL_TYPE
#undef PIXEL_NAME
#undef BGR_FORMAT
static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width)
{
#ifdef HOST_WORDS_BIGENDIAN
memcpy(d, s, width * 4);
#else
int w;
uint32_t r, g, b;
w = width;
do {
r = s[1];
g = s[2];
b = s[3];
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
s += 4;
d += 4;
} while (--w != 0);
#endif
}

View File

@@ -761,14 +761,13 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
vbe_fixup_regs(s);
/* clear the screen (should be done in BIOS) */
/* clear the screen */
if (!(val & VBE_DISPI_NOCLEARMEM)) {
memset(s->vram_ptr, 0,
s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
}
/* we initialize the VGA graphic mode (should be done
in BIOS) */
/* we initialize the VGA graphic mode */
/* graphic mode + memory map 1 */
s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
VGA_GR06_GRAPHICS_MODE;
@@ -801,7 +800,6 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
(shift_control << 5);
s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
} else {
/* XXX: the bios should do that */
s->bank_offset = 0;
}
s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
@@ -1006,95 +1004,10 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
}
}
typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
const uint8_t *font_ptr, int h,
uint32_t fgcol, uint32_t bgcol);
typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
const uint8_t *font_ptr, int h,
uint32_t fgcol, uint32_t bgcol, int dup9);
typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width);
#define DEPTH 8
#include "vga_template.h"
#define DEPTH 15
#include "vga_template.h"
#define BGR_FORMAT
#define DEPTH 15
#include "vga_template.h"
#define DEPTH 16
#include "vga_template.h"
#define BGR_FORMAT
#define DEPTH 16
#include "vga_template.h"
#define DEPTH 32
#include "vga_template.h"
#define BGR_FORMAT
#define DEPTH 32
#include "vga_template.h"
static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
{
unsigned int col;
col = rgb_to_pixel8(r, g, b);
col |= col << 8;
col |= col << 16;
return col;
}
static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b)
{
unsigned int col;
col = rgb_to_pixel15(r, g, b);
col |= col << 16;
return col;
}
static unsigned int rgb_to_pixel15bgr_dup(unsigned int r, unsigned int g,
unsigned int b)
{
unsigned int col;
col = rgb_to_pixel15bgr(r, g, b);
col |= col << 16;
return col;
}
static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b)
{
unsigned int col;
col = rgb_to_pixel16(r, g, b);
col |= col << 16;
return col;
}
static unsigned int rgb_to_pixel16bgr_dup(unsigned int r, unsigned int g,
unsigned int b)
{
unsigned int col;
col = rgb_to_pixel16bgr(r, g, b);
col |= col << 16;
return col;
}
static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b)
{
unsigned int col;
col = rgb_to_pixel32(r, g, b);
return col;
}
static unsigned int rgb_to_pixel32bgr_dup(unsigned int r, unsigned int g, unsigned b)
{
unsigned int col;
col = rgb_to_pixel32bgr(r, g, b);
return col;
}
#include "vga-helpers.h"
/* return true if the palette was modified */
static int update_palette16(VGACommonState *s)
@@ -1112,7 +1025,7 @@ static int update_palette16(VGACommonState *s)
v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f);
}
v = v * 3;
col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
col = rgb_to_pixel32(c6_to_8(s->palette[v]),
c6_to_8(s->palette[v + 1]),
c6_to_8(s->palette[v + 2]));
if (col != palette[i]) {
@@ -1134,11 +1047,11 @@ static int update_palette256(VGACommonState *s)
v = 0;
for(i = 0; i < 256; i++) {
if (s->dac_8bit) {
col = s->rgb_to_pixel(s->palette[v],
col = rgb_to_pixel32(s->palette[v],
s->palette[v + 1],
s->palette[v + 2]);
} else {
col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
col = rgb_to_pixel32(c6_to_8(s->palette[v]),
c6_to_8(s->palette[v + 1]),
c6_to_8(s->palette[v + 2]));
}
@@ -1202,56 +1115,6 @@ static int update_basic_params(VGACommonState *s)
return full_update;
}
#define NB_DEPTHS 7
static inline int get_depth_index(DisplaySurface *s)
{
switch (surface_bits_per_pixel(s)) {
default:
case 8:
return 0;
case 15:
return 1;
case 16:
return 2;
case 32:
if (is_surface_bgr(s)) {
return 4;
} else {
return 3;
}
}
}
static vga_draw_glyph8_func * const vga_draw_glyph8_table[NB_DEPTHS] = {
vga_draw_glyph8_8,
vga_draw_glyph8_16,
vga_draw_glyph8_16,
vga_draw_glyph8_32,
vga_draw_glyph8_32,
vga_draw_glyph8_16,
vga_draw_glyph8_16,
};
static vga_draw_glyph8_func * const vga_draw_glyph16_table[NB_DEPTHS] = {
vga_draw_glyph16_8,
vga_draw_glyph16_16,
vga_draw_glyph16_16,
vga_draw_glyph16_32,
vga_draw_glyph16_32,
vga_draw_glyph16_16,
vga_draw_glyph16_16,
};
static vga_draw_glyph9_func * const vga_draw_glyph9_table[NB_DEPTHS] = {
vga_draw_glyph9_8,
vga_draw_glyph9_16,
vga_draw_glyph9_16,
vga_draw_glyph9_32,
vga_draw_glyph9_32,
vga_draw_glyph9_16,
vga_draw_glyph9_16,
};
static const uint8_t cursor_glyph[32 * 4] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -1303,18 +1166,6 @@ static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight
*pcheight = cheight;
}
typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
static rgb_to_pixel_dup_func * const rgb_to_pixel_dup_table[NB_DEPTHS] = {
rgb_to_pixel8_dup,
rgb_to_pixel15_dup,
rgb_to_pixel16_dup,
rgb_to_pixel32_dup,
rgb_to_pixel32bgr_dup,
rgb_to_pixel15bgr_dup,
rgb_to_pixel16bgr_dup,
};
/*
* Text mode update
* Missing:
@@ -1331,11 +1182,9 @@ static void vga_draw_text(VGACommonState *s, int full_update)
uint32_t offset, fgcol, bgcol, v, cursor_offset;
uint8_t *d1, *d, *src, *dest, *cursor_ptr;
const uint8_t *font_ptr, *font_base[2];
int dup9, line_offset, depth_index;
int dup9, line_offset;
uint32_t *palette;
uint32_t *ch_attr_ptr;
vga_draw_glyph8_func *vga_draw_glyph8;
vga_draw_glyph9_func *vga_draw_glyph9;
int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
/* compute font data address (in plane 2) */
@@ -1387,8 +1236,6 @@ static void vga_draw_text(VGACommonState *s, int full_update)
s->last_cw = cw;
full_update = 1;
}
s->rgb_to_pixel =
rgb_to_pixel_dup_table[get_depth_index(surface)];
full_update |= update_palette16(s);
palette = s->last_palette;
x_incr = cw * surface_bytes_per_pixel(surface);
@@ -1422,13 +1269,6 @@ static void vga_draw_text(VGACommonState *s, int full_update)
s->cursor_visible_phase = !s->cursor_visible_phase;
}
depth_index = get_depth_index(surface);
if (cw == 16)
vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
else
vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];
dest = surface_data(surface);
linesize = surface_stride(surface);
ch_attr_ptr = s->last_ch_attr;
@@ -1458,7 +1298,10 @@ static void vga_draw_text(VGACommonState *s, int full_update)
font_ptr += 32 * 4 * ch;
bgcol = palette[cattr >> 4];
fgcol = palette[cattr & 0x0f];
if (cw != 9) {
if (cw == 16) {
vga_draw_glyph16(d1, linesize,
font_ptr, cheight, fgcol, bgcol);
} else if (cw != 9) {
vga_draw_glyph8(d1, linesize,
font_ptr, cheight, fgcol, bgcol);
} else {
@@ -1483,7 +1326,10 @@ static void vga_draw_text(VGACommonState *s, int full_update)
if (line_last >= line_start && line_start < cheight) {
h = line_last - line_start + 1;
d = d1 + linesize * line_start;
if (cw != 9) {
if (cw == 16) {
vga_draw_glyph16(d, linesize,
cursor_glyph, h, fgcol, bgcol);
} else if (cw != 9) {
vga_draw_glyph8(d, linesize,
cursor_glyph, h, fgcol, bgcol);
} else {
@@ -1518,93 +1364,32 @@ enum {
VGA_DRAW_LINE4D2,
VGA_DRAW_LINE8D2,
VGA_DRAW_LINE8,
VGA_DRAW_LINE15,
VGA_DRAW_LINE16,
VGA_DRAW_LINE24,
VGA_DRAW_LINE32,
VGA_DRAW_LINE15_LE,
VGA_DRAW_LINE16_LE,
VGA_DRAW_LINE24_LE,
VGA_DRAW_LINE32_LE,
VGA_DRAW_LINE15_BE,
VGA_DRAW_LINE16_BE,
VGA_DRAW_LINE24_BE,
VGA_DRAW_LINE32_BE,
VGA_DRAW_LINE_NB,
};
static vga_draw_line_func * const vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
vga_draw_line2_8,
vga_draw_line2_16,
vga_draw_line2_16,
vga_draw_line2_32,
vga_draw_line2_32,
vga_draw_line2_16,
vga_draw_line2_16,
vga_draw_line2d2_8,
vga_draw_line2d2_16,
vga_draw_line2d2_16,
vga_draw_line2d2_32,
vga_draw_line2d2_32,
vga_draw_line2d2_16,
vga_draw_line2d2_16,
vga_draw_line4_8,
vga_draw_line4_16,
vga_draw_line4_16,
vga_draw_line4_32,
vga_draw_line4_32,
vga_draw_line4_16,
vga_draw_line4_16,
vga_draw_line4d2_8,
vga_draw_line4d2_16,
vga_draw_line4d2_16,
vga_draw_line4d2_32,
vga_draw_line4d2_32,
vga_draw_line4d2_16,
vga_draw_line4d2_16,
vga_draw_line8d2_8,
vga_draw_line8d2_16,
vga_draw_line8d2_16,
vga_draw_line8d2_32,
vga_draw_line8d2_32,
vga_draw_line8d2_16,
vga_draw_line8d2_16,
vga_draw_line8_8,
vga_draw_line8_16,
vga_draw_line8_16,
vga_draw_line8_32,
vga_draw_line8_32,
vga_draw_line8_16,
vga_draw_line8_16,
vga_draw_line15_8,
vga_draw_line15_15,
vga_draw_line15_16,
vga_draw_line15_32,
vga_draw_line15_32bgr,
vga_draw_line15_15bgr,
vga_draw_line15_16bgr,
vga_draw_line16_8,
vga_draw_line16_15,
vga_draw_line16_16,
vga_draw_line16_32,
vga_draw_line16_32bgr,
vga_draw_line16_15bgr,
vga_draw_line16_16bgr,
vga_draw_line24_8,
vga_draw_line24_15,
vga_draw_line24_16,
vga_draw_line24_32,
vga_draw_line24_32bgr,
vga_draw_line24_15bgr,
vga_draw_line24_16bgr,
vga_draw_line32_8,
vga_draw_line32_15,
vga_draw_line32_16,
vga_draw_line32_32,
vga_draw_line32_32bgr,
vga_draw_line32_15bgr,
vga_draw_line32_16bgr,
static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = {
vga_draw_line2,
vga_draw_line2d2,
vga_draw_line4,
vga_draw_line4d2,
vga_draw_line8d2,
vga_draw_line8,
vga_draw_line15_le,
vga_draw_line16_le,
vga_draw_line24_le,
vga_draw_line32_le,
vga_draw_line15_be,
vga_draw_line16_be,
vga_draw_line24_be,
vga_draw_line32_be,
};
static int vga_get_bpp(VGACommonState *s)
@@ -1676,11 +1461,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
int disp_width, multi_scan, multi_run;
uint8_t *d;
uint32_t v, addr1, addr;
vga_draw_line_func *vga_draw_line;
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
static const bool byteswap = false;
vga_draw_line_func *vga_draw_line = NULL;
#ifdef HOST_WORDS_BIGENDIAN
bool byteswap = !s->big_endian_fb;
#else
static const bool byteswap = true;
bool byteswap = s->big_endian_fb;
#endif
full_update |= update_basic_params(s);
@@ -1723,7 +1508,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
if (s->line_offset != s->last_line_offset ||
disp_width != s->last_width ||
height != s->last_height ||
s->last_depth != depth) {
s->last_depth != depth ||
s->last_byteswap != byteswap) {
if (depth == 32 || (depth == 16 && !byteswap)) {
pixman_format_code_t format =
qemu_default_pixman_format(depth, !byteswap);
@@ -1741,6 +1527,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
s->last_height = height;
s->last_line_offset = s->line_offset;
s->last_depth = depth;
s->last_byteswap = byteswap;
full_update = 1;
} else if (is_buffer_shared(surface) &&
(full_update || surface_data(surface) != s->vram_ptr
@@ -1753,9 +1540,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
dpy_gfx_replace_surface(s->con, surface);
}
s->rgb_to_pixel =
rgb_to_pixel_dup_table[get_depth_index(surface)];
if (shift_control == 0) {
full_update |= update_palette16(s);
if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
@@ -1786,25 +1570,24 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
bits = 8;
break;
case 15:
v = VGA_DRAW_LINE15;
v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE;
bits = 16;
break;
case 16:
v = VGA_DRAW_LINE16;
v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE;
bits = 16;
break;
case 24:
v = VGA_DRAW_LINE24;
v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE;
bits = 24;
break;
case 32:
v = VGA_DRAW_LINE32;
v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE;
bits = 32;
break;
}
}
vga_draw_line = vga_draw_line_table[v * NB_DEPTHS +
get_depth_index(surface)];
vga_draw_line = vga_draw_line_table[v];
if (!is_buffer_shared(surface) && s->cursor_invalidate) {
s->cursor_invalidate(s);
@@ -1894,7 +1677,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
static void vga_draw_blank(VGACommonState *s, int full_update)
{
DisplaySurface *surface = qemu_console_surface(s->con);
int i, w, val;
int i, w;
uint8_t *d;
if (!full_update)
@@ -1902,17 +1685,10 @@ static void vga_draw_blank(VGACommonState *s, int full_update)
if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
return;
s->rgb_to_pixel =
rgb_to_pixel_dup_table[get_depth_index(surface)];
if (surface_bits_per_pixel(surface) == 8) {
val = s->rgb_to_pixel(0, 0, 0);
} else {
val = 0;
}
w = s->last_scr_width * surface_bytes_per_pixel(surface);
d = surface_data(surface);
for(i = 0; i < s->last_scr_height; i++) {
memset(d, val, w);
memset(d, 0, w);
d += surface_stride(surface);
}
dpy_gfx_update(s->con, 0, 0,
@@ -2015,6 +1791,7 @@ void vga_common_reset(VGACommonState *s)
s->cursor_start = 0;
s->cursor_end = 0;
s->cursor_offset = 0;
s->big_endian_fb = s->default_endian_fb;
memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
memset(s->last_palette, '\0', sizeof(s->last_palette));
memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
@@ -2246,6 +2023,28 @@ static int vga_common_post_load(void *opaque, int version_id)
return 0;
}
static bool vga_endian_state_needed(void *opaque)
{
VGACommonState *s = opaque;
/*
* Only send the endian state if it's different from the
* default one, thus ensuring backward compatibility for
* migration of the common case
*/
return s->default_endian_fb != s->big_endian_fb;
}
const VMStateDescription vmstate_vga_endian = {
.name = "vga.endian",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_BOOL(big_endian_fb, VGACommonState),
VMSTATE_END_OF_LIST()
}
};
const VMStateDescription vmstate_vga_common = {
.name = "vga",
.version_id = 2,
@@ -2282,6 +2081,14 @@ const VMStateDescription vmstate_vga_common = {
VMSTATE_UINT32(vbe_line_offset, VGACommonState),
VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
VMSTATE_END_OF_LIST()
},
.subsections = (VMStateSubsection []) {
{
.vmsd = &vmstate_vga_endian,
.needed = vga_endian_state_needed,
}, {
/* empty */
}
}
};
@@ -2350,6 +2157,17 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
s->update_retrace_info = vga_precise_update_retrace_info;
break;
}
/*
* Set default fb endian based on target, could probably be turned
* into a device attribute set by the machine/platform to remove
* all target endian dependencies from this file.
*/
#ifdef TARGET_WORDS_BIGENDIAN
s->default_endian_fb = true;
#else
s->default_endian_fb = false;
#endif
vga_dirty_log_start(s);
}

View File

@@ -150,15 +150,16 @@ typedef struct VGACommonState {
uint32_t last_width, last_height; /* in chars or pixels */
uint32_t last_scr_width, last_scr_height; /* in pixels */
uint32_t last_depth; /* in bits */
bool last_byteswap;
uint8_t cursor_start, cursor_end;
bool cursor_visible_phase;
int64_t cursor_blink_time;
uint32_t cursor_offset;
unsigned int (*rgb_to_pixel)(unsigned int r,
unsigned int g, unsigned b);
const GraphicHwOps *hw_ops;
bool full_update_text;
bool full_update_gfx;
bool big_endian_fb;
bool default_endian_fb;
/* hardware mouse cursor support */
uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32];
void (*cursor_invalidate)(struct VGACommonState *s);

View File

@@ -1825,8 +1825,6 @@ static int assigned_initfn(struct PCIDevice *pci_dev)
assigned_dev_load_option_rom(dev);
add_boot_device_path(dev->bootindex, &pci_dev->qdev, NULL);
return 0;
assigned_out:
@@ -1850,13 +1848,22 @@ static void assigned_exitfn(struct PCIDevice *pci_dev)
free_assigned_device(dev);
}
static void assigned_dev_instance_init(Object *obj)
{
PCIDevice *pci_dev = PCI_DEVICE(obj);
AssignedDevice *d = DO_UPCAST(AssignedDevice, dev, PCI_DEVICE(obj));
device_add_bootindex_property(obj, &d->bootindex,
"bootindex", NULL,
&pci_dev->qdev, NULL);
}
static Property assigned_dev_properties[] = {
DEFINE_PROP_PCI_HOST_DEVADDR("host", AssignedDevice, host),
DEFINE_PROP_BIT("prefer_msi", AssignedDevice, features,
ASSIGNED_DEVICE_PREFER_MSI_BIT, false),
DEFINE_PROP_BIT("share_intx", AssignedDevice, features,
ASSIGNED_DEVICE_SHARE_INTX_BIT, true),
DEFINE_PROP_INT32("bootindex", AssignedDevice, bootindex, -1),
DEFINE_PROP_STRING("configfd", AssignedDevice, configfd_name),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1882,6 +1889,7 @@ static const TypeInfo assign_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(AssignedDevice),
.class_init = assign_class_init,
.instance_init = assigned_dev_instance_init,
};
static void assign_register_types(void)

View File

@@ -1524,6 +1524,7 @@ static void pc_generic_machine_class_init(ObjectClass *oc, void *data)
mc->hot_add_cpu = qm->hot_add_cpu;
mc->kvm_type = qm->kvm_type;
mc->block_default_type = qm->block_default_type;
mc->units_per_default_bus = qm->units_per_default_bus;
mc->max_cpus = qm->max_cpus;
mc->no_serial = qm->no_serial;
mc->no_parallel = qm->no_parallel;

View File

@@ -239,7 +239,7 @@ static void pc_init1(MachineState *machine,
pc_nic_init(isa_bus, pci_bus);
ide_drive_get(hd, MAX_IDE_BUS);
ide_drive_get(hd, ARRAY_SIZE(hd));
if (pci_enabled) {
PCIDevice *dev;
if (xen_enabled()) {

View File

@@ -86,6 +86,7 @@ static void pc_q35_init(MachineState *machine)
DeviceState *icc_bridge;
PcGuestInfo *guest_info;
ram_addr_t lowmem;
DriveInfo *hd[MAX_SATA_PORTS];
/* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory
* and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping
@@ -253,6 +254,9 @@ static void pc_q35_init(MachineState *machine)
true, "ich9-ahci");
idebus[0] = qdev_get_child_bus(&ahci->qdev, "ide.0");
idebus[1] = qdev_get_child_bus(&ahci->qdev, "ide.1");
g_assert_cmpint(MAX_SATA_PORTS, ==, ICH_AHCI(ahci)->ahci.ports);
ide_drive_get(hd, ICH_AHCI(ahci)->ahci.ports);
ahci_ide_create_devs(ahci, hd);
if (usb_enabled(false)) {
/* Should we create 6 UHCI according to ich9 spec? */
@@ -344,7 +348,8 @@ static void pc_q35_init_1_4(MachineState *machine)
#define PC_Q35_MACHINE_OPTIONS \
PC_DEFAULT_MACHINE_OPTIONS, \
.desc = "Standard PC (Q35 + ICH9, 2009)", \
.hot_add_cpu = pc_hot_add_cpu
.hot_add_cpu = pc_hot_add_cpu, \
.units_per_default_bus = 1
#define PC_Q35_2_2_MACHINE_OPTIONS \
PC_Q35_MACHINE_OPTIONS, \

View File

@@ -1419,3 +1419,18 @@ static void sysbus_ahci_register_types(void)
}
type_init(sysbus_ahci_register_types)
void ahci_ide_create_devs(PCIDevice *dev, DriveInfo **hd)
{
AHCIPCIState *d = ICH_AHCI(dev);
AHCIState *ahci = &d->ahci;
int i;
for (i = 0; i < ahci->ports; i++) {
if (hd[i] == NULL) {
continue;
}
ide_create_drive(&ahci->dev[i].port, 0, hd[i]);
}
}

View File

@@ -332,4 +332,6 @@ void ahci_uninit(AHCIState *s);
void ahci_reset(AHCIState *s);
void ahci_ide_create_devs(PCIDevice *dev, DriveInfo **hd);
#endif /* HW_IDE_AHCI_H */

View File

@@ -2558,16 +2558,28 @@ const VMStateDescription vmstate_ide_bus = {
}
};
void ide_drive_get(DriveInfo **hd, int max_bus)
void ide_drive_get(DriveInfo **hd, int n)
{
int i;
int highest_bus = drive_get_max_bus(IF_IDE) + 1;
int max_devs = drive_get_max_devs(IF_IDE);
int n_buses = max_devs ? (n / max_devs) : n;
if (drive_get_max_bus(IF_IDE) >= max_bus) {
fprintf(stderr, "qemu: too many IDE bus: %d\n", max_bus);
/*
* Note: The number of actual buses available is not known.
* We compute this based on the size of the DriveInfo* array, n.
* If it is less than max_devs * <num_real_buses>,
* We will stop looking for drives prematurely instead of overfilling
* the array.
*/
if (highest_bus > n_buses) {
error_report("Too many IDE buses defined (%d > %d)",
highest_bus, n_buses);
exit(1);
}
for(i = 0; i < max_bus * MAX_IDE_DEVS; i++) {
hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
for (i = 0; i < n; i++) {
hd[i] = drive_get_by_index(IF_IDE, i);
}
}

View File

@@ -23,6 +23,7 @@
#include "sysemu/blockdev.h"
#include "hw/block/block.h"
#include "sysemu/sysemu.h"
#include "qapi/visitor.h"
/* --------------------------------- */
@@ -191,6 +192,51 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
return 0;
}
static void ide_dev_get_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
IDEDevice *d = IDE_DEVICE(obj);
visit_type_int32(v, &d->conf.bootindex, name, errp);
}
static void ide_dev_set_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
IDEDevice *d = IDE_DEVICE(obj);
int32_t boot_index;
Error *local_err = NULL;
visit_type_int32(v, &boot_index, name, &local_err);
if (local_err) {
goto out;
}
/* check whether bootindex is present in fw_boot_order list */
check_boot_index(boot_index, &local_err);
if (local_err) {
goto out;
}
/* change bootindex to a new one */
d->conf.bootindex = boot_index;
if (d->unit != -1) {
add_boot_device_path(d->conf.bootindex, &d->qdev,
d->unit ? "/disk@1" : "/disk@0");
}
out:
if (local_err) {
error_propagate(errp, local_err);
}
}
static void ide_dev_instance_init(Object *obj)
{
object_property_add(obj, "bootindex", "int32",
ide_dev_get_bootindex,
ide_dev_set_bootindex, NULL, NULL, NULL);
object_property_set_int(obj, -1, "bootindex", NULL);
}
static int ide_hd_initfn(IDEDevice *dev)
{
return ide_dev_initfn(dev, IDE_HD);
@@ -300,6 +346,7 @@ static const TypeInfo ide_device_type_info = {
.abstract = true,
.class_size = sizeof(IDEDeviceClass),
.class_init = ide_device_class_init,
.instance_init = ide_dev_instance_init,
};
static void ide_register_types(void)

View File

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

View File

@@ -350,7 +350,7 @@ static void mips_fulong2e_init(MachineState *machine)
pci_bus = bonito_init((qemu_irq *)&(env->irq[2]));
/* South bridge */
ide_drive_get(hd, MAX_IDE_BUS);
ide_drive_get(hd, ARRAY_SIZE(hd));
isa_bus = vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 0));
if (!isa_bus) {

View File

@@ -1147,7 +1147,7 @@ void mips_malta_init(MachineState *machine)
pci_bus = gt64120_register(isa_irq);
/* Southbridge */
ide_drive_get(hd, MAX_IDE_BUS);
ide_drive_get(hd, ARRAY_SIZE(hd));
piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);

View File

@@ -294,7 +294,7 @@ void mips_r4k_init(MachineState *machine)
if (nd_table[0].used)
isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]);
ide_drive_get(hd, MAX_IDE_BUS);
ide_drive_get(hd, ARRAY_SIZE(hd));
for(i = 0; i < MAX_IDE_BUS; i++)
isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i],
hd[MAX_IDE_DEVS * i],

View File

@@ -4296,7 +4296,6 @@ static int vfio_initfn(PCIDevice *pdev)
}
}
add_boot_device_path(vdev->bootindex, &pdev->qdev, NULL);
vfio_register_err_notifier(vdev);
return 0;
@@ -4365,13 +4364,22 @@ post_reset:
vfio_pci_post_reset(vdev);
}
static void vfio_instance_init(Object *obj)
{
PCIDevice *pci_dev = PCI_DEVICE(obj);
VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, PCI_DEVICE(obj));
device_add_bootindex_property(obj, &vdev->bootindex,
"bootindex", NULL,
&pci_dev->qdev, NULL);
}
static Property vfio_pci_dev_properties[] = {
DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIODevice, host),
DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIODevice,
intx.mmap_timeout, 1100),
DEFINE_PROP_BIT("x-vga", VFIODevice, features,
VFIO_FEATURE_ENABLE_VGA_BIT, false),
DEFINE_PROP_INT32("bootindex", VFIODevice, bootindex, -1),
/*
* TODO - support passed fds... is this necessary?
* DEFINE_PROP_STRING("vfiofd", VFIODevice, vfiofd_name),
@@ -4407,6 +4415,7 @@ static const TypeInfo vfio_pci_dev_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VFIODevice),
.class_init = vfio_pci_dev_class_init,
.instance_init = vfio_instance_init,
};
static void register_vfio_pci_dev_type(void)

View File

@@ -1569,8 +1569,6 @@ static int pci_e1000_init(PCIDevice *pci_dev)
qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr);
add_boot_device_path(d->conf.bootindex, dev, "/ethernet-phy@0");
d->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, e1000_autoneg_timer, d);
d->mit_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000_mit_timer, d);
@@ -1621,10 +1619,19 @@ static void e1000_class_init(ObjectClass *klass, void *data)
dc->props = e1000_properties;
}
static void e1000_instance_init(Object *obj)
{
E1000State *n = E1000(obj);
device_add_bootindex_property(obj, &n->conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(n), NULL);
}
static const TypeInfo e1000_base_info = {
.name = TYPE_E1000_BASE,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(E1000State),
.instance_init = e1000_instance_init,
.class_size = sizeof(E1000BaseClass),
.abstract = true,
};
@@ -1668,6 +1675,7 @@ static void e1000_register_types(void)
type_info.parent = TYPE_E1000_BASE;
type_info.class_data = (void *)info;
type_info.class_init = e1000_class_init;
type_info.instance_init = e1000_instance_init;
type_register(&type_info);
}

View File

@@ -1901,11 +1901,17 @@ static int e100_nic_init(PCIDevice *pci_dev)
s->vmstate->name = qemu_get_queue(s->nic)->model;
vmstate_register(&pci_dev->qdev, -1, s->vmstate, s);
add_boot_device_path(s->conf.bootindex, &pci_dev->qdev, "/ethernet-phy@0");
return 0;
}
static void eepro100_instance_init(Object *obj)
{
EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, PCI_DEVICE(obj));
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(s), NULL);
}
static E100PCIDeviceInfo e100_devices[] = {
{
.name = "i82550",
@@ -2104,6 +2110,7 @@ static void eepro100_register_types(void)
type_info.parent = TYPE_PCI_DEVICE;
type_info.class_init = eepro100_class_init;
type_info.instance_size = sizeof(EEPRO100State);
type_info.instance_init = eepro100_instance_init;
type_register(&type_info);
}

View File

@@ -42,6 +42,7 @@
#include "hw/sparc/sun4m.h"
#include "pcnet.h"
#include "trace.h"
#include "sysemu/sysemu.h"
#define TYPE_LANCE "lance"
#define SYSBUS_PCNET(obj) \
@@ -143,6 +144,16 @@ static void lance_reset(DeviceState *dev)
pcnet_h_reset(&d->state);
}
static void lance_instance_init(Object *obj)
{
SysBusPCNetState *d = SYSBUS_PCNET(obj);
PCNetState *s = &d->state;
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(obj), NULL);
}
static Property lance_properties[] = {
DEFINE_PROP_PTR("dma", SysBusPCNetState, state.dma_opaque),
DEFINE_NIC_PROPERTIES(SysBusPCNetState, state.conf),
@@ -169,6 +180,7 @@ static const TypeInfo lance_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysBusPCNetState),
.class_init = lance_class_init,
.instance_init = lance_instance_init,
};
static void lance_register_types(void)

View File

@@ -28,6 +28,7 @@
#include "net/net.h"
#include "ne2000.h"
#include "exec/address-spaces.h"
#include "qapi/visitor.h"
#define TYPE_ISA_NE2000 "ne2k_isa"
#define ISA_NE2000(obj) OBJECT_CHECK(ISANE2000State, (obj), TYPE_ISA_NE2000)
@@ -101,11 +102,54 @@ static void isa_ne2000_class_initfn(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}
static void isa_ne2000_get_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
ISANE2000State *isa = ISA_NE2000(obj);
NE2000State *s = &isa->ne2000;
visit_type_int32(v, &s->c.bootindex, name, errp);
}
static void isa_ne2000_set_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
ISANE2000State *isa = ISA_NE2000(obj);
NE2000State *s = &isa->ne2000;
int32_t boot_index;
Error *local_err = NULL;
visit_type_int32(v, &boot_index, name, &local_err);
if (local_err) {
goto out;
}
/* check whether bootindex is present in fw_boot_order list */
check_boot_index(boot_index, &local_err);
if (local_err) {
goto out;
}
/* change bootindex to a new one */
s->c.bootindex = boot_index;
out:
if (local_err) {
error_propagate(errp, local_err);
}
}
static void isa_ne2000_instance_init(Object *obj)
{
object_property_add(obj, "bootindex", "int32",
isa_ne2000_get_bootindex,
isa_ne2000_set_bootindex, NULL, NULL, NULL);
object_property_set_int(obj, -1, "bootindex", NULL);
}
static const TypeInfo ne2000_isa_info = {
.name = TYPE_ISA_NE2000,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISANE2000State),
.class_init = isa_ne2000_class_initfn,
.instance_init = isa_ne2000_instance_init,
};
static void ne2000_isa_register_types(void)

View File

@@ -738,8 +738,6 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
add_boot_device_path(s->c.bootindex, &pci_dev->qdev, "/ethernet-phy@0");
return 0;
}
@@ -752,6 +750,17 @@ static void pci_ne2000_exit(PCIDevice *pci_dev)
qemu_free_irq(s->irq);
}
static void ne2000_instance_init(Object *obj)
{
PCIDevice *pci_dev = PCI_DEVICE(obj);
PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
NE2000State *s = &d->ne2000;
device_add_bootindex_property(obj, &s->c.bootindex,
"bootindex", "/ethernet-phy@0",
&pci_dev->qdev, NULL);
}
static Property ne2000_properties[] = {
DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
DEFINE_PROP_END_OF_LIST(),
@@ -778,6 +787,7 @@ static const TypeInfo ne2000_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCINE2000State),
.class_init = ne2000_class_init,
.instance_init = ne2000_instance_init,
};
static void ne2000_register_types(void)

View File

@@ -32,6 +32,7 @@
#include "hw/loader.h"
#include "qemu/timer.h"
#include "sysemu/dma.h"
#include "sysemu/sysemu.h"
#include "pcnet.h"
@@ -344,6 +345,16 @@ static void pci_reset(DeviceState *dev)
pcnet_h_reset(&d->state);
}
static void pcnet_instance_init(Object *obj)
{
PCIPCNetState *d = PCI_PCNET(obj);
PCNetState *s = &d->state;
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(obj), NULL);
}
static Property pcnet_properties[] = {
DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
DEFINE_PROP_END_OF_LIST(),
@@ -372,6 +383,7 @@ static const TypeInfo pcnet_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIPCNetState),
.class_init = pcnet_class_init,
.instance_init = pcnet_instance_init,
};
static void pci_pcnet_register_types(void)

View File

@@ -1735,8 +1735,6 @@ int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0");
/* Initialize the PROM */
/*

View File

@@ -66,5 +66,4 @@ void pcnet_set_link_status(NetClientState *nc);
void pcnet_common_cleanup(PCNetState *d);
int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info);
extern const VMStateDescription vmstate_pcnet;
#endif

View File

@@ -3538,11 +3538,18 @@ static int pci_rtl8139_init(PCIDevice *dev)
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rtl8139_timer, s);
rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
add_boot_device_path(s->conf.bootindex, d, "/ethernet-phy@0");
return 0;
}
static void rtl8139_instance_init(Object *obj)
{
RTL8139State *s = RTL8139(obj);
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(obj), NULL);
}
static Property rtl8139_properties[] = {
DEFINE_NIC_PROPERTIES(RTL8139State, conf),
DEFINE_PROP_END_OF_LIST(),
@@ -3571,6 +3578,7 @@ static const TypeInfo rtl8139_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(RTL8139State),
.class_init = rtl8139_class_init,
.instance_init = rtl8139_instance_init,
};
static void rtl8139_register_types(void)

View File

@@ -221,11 +221,18 @@ static int spapr_vlan_init(VIOsPAPRDevice *sdev)
object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
add_boot_device_path(dev->nicconf.bootindex, DEVICE(dev), "");
return 0;
}
static void spapr_vlan_instance_init(Object *obj)
{
VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(obj);
device_add_bootindex_property(obj, &dev->nicconf.bootindex,
"bootindex", "",
DEVICE(dev), NULL);
}
void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd)
{
DeviceState *dev;
@@ -553,6 +560,7 @@ static const TypeInfo spapr_vlan_info = {
.parent = TYPE_VIO_SPAPR_DEVICE,
.instance_size = sizeof(VIOsPAPRVLANDevice),
.class_init = spapr_vlan_class_init,
.instance_init = spapr_vlan_instance_init,
};
static void spapr_vlan_register_types(void)

View File

@@ -1661,8 +1661,6 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
n->qdev = dev;
register_savevm(dev, "virtio-net", -1, VIRTIO_NET_VM_VERSION,
virtio_net_save, virtio_net_load, n);
add_boot_device_path(n->nic_conf.bootindex, dev, "/ethernet-phy@0");
}
static void virtio_net_device_unrealize(DeviceState *dev, Error **errp)
@@ -1714,6 +1712,9 @@ static void virtio_net_instance_init(Object *obj)
* Can be overriden with virtio_net_set_config_size.
*/
n->config_size = sizeof(struct virtio_net_config);
device_add_bootindex_property(obj, &n->nic_conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(n), NULL);
}
static Property virtio_net_properties[] = {

View File

@@ -2172,11 +2172,16 @@ static int vmxnet3_pci_init(PCIDevice *pci_dev)
register_savevm(dev, "vmxnet3-msix", -1, 1,
vmxnet3_msix_save, vmxnet3_msix_load, s);
add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0");
return 0;
}
static void vmxnet3_instance_init(Object *obj)
{
VMXNET3State *s = VMXNET3(obj);
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(obj), NULL);
}
static void vmxnet3_pci_uninit(PCIDevice *pci_dev)
{
@@ -2524,6 +2529,7 @@ static const TypeInfo vmxnet3_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VMXNET3State),
.class_init = vmxnet3_class_init,
.instance_init = vmxnet3_instance_init,
};
static void vmxnet3_register_types(void)

View File

@@ -402,6 +402,26 @@ static void fw_cfg_add_bytes_read_callback(FWCfgState *s, uint16_t key,
s->entries[arch][key].callback_opaque = callback_opaque;
}
static void *fw_cfg_modify_bytes_read(FWCfgState *s, uint16_t key,
void *data, size_t len)
{
void *ptr;
int arch = !!(key & FW_CFG_ARCH_LOCAL);
key &= FW_CFG_ENTRY_MASK;
assert(key < FW_CFG_MAX_ENTRY && len < UINT32_MAX);
/* return the old data to the function caller, avoid memory leak */
ptr = s->entries[arch][key].data;
s->entries[arch][key].data = data;
s->entries[arch][key].len = len;
s->entries[arch][key].callback_opaque = NULL;
s->entries[arch][key].callback = NULL;
return ptr;
}
void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
{
fw_cfg_add_bytes_read_callback(s, key, NULL, NULL, data, len);
@@ -499,13 +519,42 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename,
fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len);
}
static void fw_cfg_machine_ready(struct Notifier *n, void *data)
void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
void *data, size_t len)
{
int i, index;
assert(s->files);
index = be32_to_cpu(s->files->count);
assert(index < FW_CFG_FILE_SLOTS);
for (i = 0; i < index; i++) {
if (strcmp(filename, s->files->f[i].name) == 0) {
return fw_cfg_modify_bytes_read(s, FW_CFG_FILE_FIRST + i,
data, len);
}
}
/* add new one */
fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len);
return NULL;
}
static void fw_cfg_machine_reset(void *opaque)
{
void *ptr;
size_t len;
FWCfgState *s = container_of(n, FWCfgState, machine_ready);
FWCfgState *s = opaque;
char *bootindex = get_boot_devices_list(&len, false);
fw_cfg_add_file(s, "bootorder", (uint8_t*)bootindex, len);
ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)bootindex, len);
g_free(ptr);
}
static void fw_cfg_machine_ready(struct Notifier *n, void *data)
{
FWCfgState *s = container_of(n, FWCfgState, machine_ready);
qemu_register_reset(fw_cfg_machine_reset, s);
}
FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,

View File

@@ -107,6 +107,7 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
{
SCSIBus *scsibus;
SCSIDevice *scsidev;
Error *local_err = NULL;
scsibus = (SCSIBus *)
object_dynamic_cast(OBJECT(QLIST_FIRST(&adapter->child_bus)),
@@ -127,8 +128,10 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1);
dinfo->bus = scsibus->busnr;
scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo->bdrv, dinfo->unit,
false, -1, NULL, NULL);
false, -1, NULL, &local_err);
if (!scsidev) {
error_report("%s", error_get_pretty(local_err));
error_free(local_err);
return -1;
}
dinfo->unit = scsidev->id;

View File

@@ -400,7 +400,7 @@ static void ppc_core99_init(MachineState *machine)
macio_init(macio, pic_mem, escc_bar);
/* We only emulate 2 out of 3 IDE controllers for now */
ide_drive_get(hd, MAX_IDE_BUS);
ide_drive_get(hd, ARRAY_SIZE(hd));
macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
"ide[0]"));

View File

@@ -278,7 +278,7 @@ static void ppc_heathrow_init(MachineState *machine)
pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);
ide_drive_get(hd, MAX_IDE_BUS);
ide_drive_get(hd, ARRAY_SIZE(hd));
macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO);
dev = DEVICE(macio);

View File

@@ -519,7 +519,7 @@ static void ppc_prep_init(MachineState *machine)
}
}
ide_drive_get(hd, MAX_IDE_BUS);
ide_drive_get(hd, ARRAY_SIZE(hd));
for(i = 0; i < MAX_IDE_BUS; i++) {
isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i],
hd[2 * i],

View File

@@ -176,7 +176,7 @@ static void s390_ipl_reset(DeviceState *dev)
}
}
s390_add_running_cpu(cpu);
s390_cpu_set_state(CPU_STATE_OPERATING, cpu);
}
static void s390_ipl_class_init(ObjectClass *klass, void *data)

View File

@@ -159,8 +159,11 @@ static int s390_virtio_net_init(VirtIOS390Device *s390_dev)
static void s390_virtio_net_instance_init(Object *obj)
{
VirtIONetS390 *dev = VIRTIO_NET_S390(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_NET);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
@@ -177,12 +180,13 @@ static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
static void s390_virtio_blk_instance_init(Object *obj)
{
VirtIOBlkS390 *dev = VIRTIO_BLK_S390(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BLK);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_BLK);
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
&error_abort);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
static int s390_virtio_serial_init(VirtIOS390Device *s390_dev)
@@ -222,8 +226,9 @@ static int s390_virtio_serial_init(VirtIOS390Device *s390_dev)
static void s390_virtio_serial_instance_init(Object *obj)
{
VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_SERIAL);
}
static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev)
@@ -254,8 +259,9 @@ static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev)
static void s390_virtio_scsi_instance_init(Object *obj)
{
VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_SCSI);
}
#ifdef CONFIG_VHOST_SCSI
@@ -275,8 +281,9 @@ static int s390_vhost_scsi_init(VirtIOS390Device *s390_dev)
static void s390_vhost_scsi_instance_init(Object *obj)
{
VHostSCSIS390 *dev = VHOST_SCSI_S390(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VHOST_SCSI);
}
#endif
@@ -301,8 +308,9 @@ static int s390_virtio_rng_init(VirtIOS390Device *s390_dev)
static void s390_virtio_rng_instance_init(Object *obj)
{
VirtIORNGS390 *dev = VIRTIO_RNG_S390(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_RNG);
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
(Object **)&dev->vdev.conf.rng,
qdev_prop_allow_set_link_before_realize,
@@ -493,10 +501,8 @@ static unsigned virtio_s390_get_features(DeviceState *d)
/**************** S390 Virtio Bus Device Descriptions *******************/
static Property s390_virtio_net_properties[] = {
DEFINE_NIC_PROPERTIES(VirtIONetS390, vdev.nic_conf),
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
DEFINE_VIRTIO_NET_FEATURES(VirtIOS390Device, host_features),
DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetS390, vdev.net_conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -533,7 +539,6 @@ static const TypeInfo s390_virtio_blk = {
};
static Property s390_virtio_serial_properties[] = {
DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtIOSerialS390, vdev.serial),
DEFINE_PROP_END_OF_LIST(),
};
@@ -556,7 +561,6 @@ static const TypeInfo s390_virtio_serial = {
static Property s390_virtio_rng_properties[] = {
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGS390, vdev.conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -614,7 +618,6 @@ static const TypeInfo virtio_s390_device_info = {
};
static Property s390_virtio_scsi_properties[] = {
DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIS390, vdev.parent_obj.conf),
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
DEFINE_VIRTIO_SCSI_FEATURES(VirtIOS390Device, host_features),
DEFINE_PROP_END_OF_LIST(),
@@ -640,7 +643,6 @@ static const TypeInfo s390_virtio_scsi = {
#ifdef CONFIG_VHOST_SCSI
static Property s390_vhost_scsi_properties[] = {
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
DEFINE_VHOST_SCSI_PROPERTIES(VHostSCSIS390, vdev.parent_obj.conf),
DEFINE_PROP_END_OF_LIST(),
};

View File

@@ -125,38 +125,6 @@ static void s390_virtio_register_hcalls(void)
s390_virtio_hcall_set_status);
}
/*
* The number of running CPUs. On s390 a shutdown is the state of all CPUs
* being either stopped or disabled (for interrupts) waiting. We have to
* track this number to call the shutdown sequence accordingly. This
* number is modified either on startup or while holding the big qemu lock.
*/
static unsigned s390_running_cpus;
void s390_add_running_cpu(S390CPU *cpu)
{
CPUState *cs = CPU(cpu);
if (cs->halted) {
s390_running_cpus++;
cs->halted = 0;
cs->exception_index = -1;
}
}
unsigned s390_del_running_cpu(S390CPU *cpu)
{
CPUState *cs = CPU(cpu);
if (cs->halted == 0) {
assert(s390_running_cpus >= 1);
s390_running_cpus--;
cs->halted = 1;
cs->exception_index = EXCP_HLT;
}
return s390_running_cpus;
}
void s390_init_ipl_dev(const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,

View File

@@ -792,8 +792,11 @@ static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev)
static void virtio_ccw_net_instance_init(Object *obj)
{
VirtIONetCcw *dev = VIRTIO_NET_CCW(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_NET);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
@@ -811,12 +814,13 @@ static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
static void virtio_ccw_blk_instance_init(Object *obj)
{
VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BLK);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_BLK);
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
&error_abort);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev)
@@ -848,8 +852,9 @@ static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev)
static void virtio_ccw_serial_instance_init(Object *obj)
{
VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_SERIAL);
}
static int virtio_ccw_balloon_init(VirtioCcwDevice *ccw_dev)
@@ -896,7 +901,7 @@ static void virtio_ccw_balloon_instance_init(Object *obj)
VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
object_property_add(obj, "guest-stats", "guest statistics",
balloon_ccw_stats_get_all, NULL, NULL, dev, NULL);
@@ -934,8 +939,11 @@ static int virtio_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
static void virtio_ccw_scsi_instance_init(Object *obj)
{
VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_SCSI);
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev), "iothread",
&error_abort);
}
#ifdef CONFIG_VHOST_SCSI
@@ -955,8 +963,9 @@ static int vhost_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
static void vhost_ccw_scsi_instance_init(Object *obj)
{
VHostSCSICcw *dev = VHOST_SCSI_CCW(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VHOST_SCSI);
}
#endif
@@ -1374,8 +1383,6 @@ static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f)
static Property virtio_ccw_net_properties[] = {
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features[0]),
DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetCcw, vdev.net_conf),
DEFINE_NIC_PROPERTIES(VirtIONetCcw, vdev.nic_conf),
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_END_OF_LIST(),
@@ -1428,7 +1435,6 @@ static const TypeInfo virtio_ccw_blk = {
static Property virtio_ccw_serial_properties[] = {
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtioSerialCcw, vdev.serial),
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_END_OF_LIST(),
@@ -1481,7 +1487,6 @@ static const TypeInfo virtio_ccw_balloon = {
static Property virtio_ccw_scsi_properties[] = {
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features[0]),
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
@@ -1510,7 +1515,6 @@ static const TypeInfo virtio_ccw_scsi = {
#ifdef CONFIG_VHOST_SCSI
static Property vhost_ccw_scsi_properties[] = {
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
DEFINE_VHOST_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1528,7 +1532,7 @@ static void vhost_ccw_scsi_class_init(ObjectClass *klass, void *data)
static const TypeInfo vhost_ccw_scsi = {
.name = TYPE_VHOST_SCSI_CCW,
.parent = TYPE_VIRTIO_CCW_DEVICE,
.instance_size = sizeof(VirtIOSCSICcw),
.instance_size = sizeof(VHostSCSICcw),
.instance_init = vhost_ccw_scsi_instance_init,
.class_init = vhost_ccw_scsi_class_init,
};
@@ -1537,8 +1541,9 @@ static const TypeInfo vhost_ccw_scsi = {
static void virtio_ccw_rng_instance_init(Object *obj)
{
VirtIORNGCcw *dev = VIRTIO_RNG_CCW(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_RNG);
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
(Object **)&dev->vdev.conf.rng,
qdev_prop_allow_set_link_before_realize,
@@ -1547,7 +1552,6 @@ static void virtio_ccw_rng_instance_init(Object *obj)
static Property virtio_ccw_rng_properties[] = {
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGCcw, vdev.conf),
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_END_OF_LIST(),

View File

@@ -8,6 +8,6 @@ common-obj-$(CONFIG_ESP_PCI) += esp-pci.o
obj-$(CONFIG_PSERIES) += spapr_vscsi.o
ifeq ($(CONFIG_VIRTIO),y)
obj-y += virtio-scsi.o
obj-y += virtio-scsi.o virtio-scsi-dataplane.o
obj-$(CONFIG_VHOST_SCSI) += vhost-scsi.o
endif

View File

@@ -231,7 +231,8 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
dev = qdev_create(&bus->qbus, driver);
qdev_prop_set_uint32(dev, "scsi-id", unit);
if (bootindex >= 0) {
qdev_prop_set_int32(dev, "bootindex", bootindex);
object_property_set_int(OBJECT(dev), bootindex, "bootindex",
&error_abort);
}
if (object_property_find(OBJECT(dev), "removable", NULL)) {
qdev_prop_set_bit(dev, "removable", removable);
@@ -551,8 +552,11 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
SCSIRequest *req;
SCSIBus *bus = scsi_bus_from_device(d);
BusState *qbus = BUS(bus);
const int memset_off = offsetof(SCSIRequest, sense)
+ sizeof(req->sense);
req = g_malloc0(reqops->size);
req = g_slice_alloc(reqops->size);
memset((uint8_t *)req + memset_off, 0, reqops->size - memset_off);
req->refcount = 1;
req->bus = bus;
req->dev = d;
@@ -560,10 +564,10 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
req->lun = lun;
req->hba_private = hba_private;
req->status = -1;
req->sense_len = 0;
req->ops = reqops;
object_ref(OBJECT(d));
object_ref(OBJECT(qbus->parent));
notifier_list_init(&req->cancel_notifiers);
trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
return req;
}
@@ -1603,7 +1607,7 @@ void scsi_req_unref(SCSIRequest *req)
}
object_unref(OBJECT(req->dev));
object_unref(OBJECT(qbus->parent));
g_free(req);
g_slice_free1(req->ops->size, req);
}
}
@@ -1713,9 +1717,44 @@ void scsi_req_complete(SCSIRequest *req, int status)
scsi_req_ref(req);
scsi_req_dequeue(req);
req->bus->info->complete(req, req->status, req->resid);
/* Cancelled requests might end up being completed instead of cancelled */
notifier_list_notify(&req->cancel_notifiers, req);
scsi_req_unref(req);
}
/* Called by the devices when the request is canceled. */
void scsi_req_cancel_complete(SCSIRequest *req)
{
assert(req->io_canceled);
if (req->bus->info->cancel) {
req->bus->info->cancel(req);
}
notifier_list_notify(&req->cancel_notifiers, req);
scsi_req_unref(req);
}
/* Cancel @req asynchronously. @notifier is added to @req's cancellation
* notifier list, the bus will be notified the requests cancellation is
* completed.
* */
void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier)
{
trace_scsi_req_cancel(req->dev->id, req->lun, req->tag);
if (notifier) {
notifier_list_add(&req->cancel_notifiers, notifier);
}
if (req->io_canceled) {
return;
}
scsi_req_ref(req);
scsi_req_dequeue(req);
req->io_canceled = true;
if (req->aiocb) {
bdrv_aio_cancel_async(req->aiocb);
}
}
void scsi_req_cancel(SCSIRequest *req)
{
trace_scsi_req_cancel(req->dev->id, req->lun, req->tag);
@@ -1725,28 +1764,9 @@ void scsi_req_cancel(SCSIRequest *req)
scsi_req_ref(req);
scsi_req_dequeue(req);
req->io_canceled = true;
if (req->ops->cancel_io) {
req->ops->cancel_io(req);
if (req->aiocb) {
bdrv_aio_cancel(req->aiocb);
}
if (req->bus->info->cancel) {
req->bus->info->cancel(req);
}
scsi_req_unref(req);
}
void scsi_req_abort(SCSIRequest *req, int status)
{
if (!req->enqueued) {
return;
}
scsi_req_ref(req);
scsi_req_dequeue(req);
req->io_canceled = true;
if (req->ops->cancel_io) {
req->ops->cancel_io(req);
}
scsi_req_complete(req, status);
scsi_req_unref(req);
}
static int scsi_ua_precedence(SCSISense sense)
@@ -1997,6 +2017,16 @@ static void scsi_device_class_init(ObjectClass *klass, void *data)
k->props = scsi_props;
}
static void scsi_dev_instance_init(Object *obj)
{
DeviceState *dev = DEVICE(obj);
SCSIDevice *s = DO_UPCAST(SCSIDevice, qdev, dev);
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", NULL,
&s->qdev, NULL);
}
static const TypeInfo scsi_device_type_info = {
.name = TYPE_SCSI_DEVICE,
.parent = TYPE_DEVICE,
@@ -2004,6 +2034,7 @@ static const TypeInfo scsi_device_type_info = {
.abstract = true,
.class_size = sizeof(SCSIDeviceClass),
.class_init = scsi_device_class_init,
.instance_init = scsi_dev_instance_init,
};
static void scsi_register_types(void)

View File

@@ -105,23 +105,6 @@ static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense)
scsi_req_complete(&r->req, CHECK_CONDITION);
}
/* Cancel a pending data transfer. */
static void scsi_cancel_io(SCSIRequest *req)
{
SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
DPRINTF("Cancel tag=0x%x\n", req->tag);
if (r->req.aiocb) {
bdrv_aio_cancel(r->req.aiocb);
/* This reference was left in by scsi_*_data. We take ownership of
* it the moment scsi_req_cancel is called, independent of whether
* bdrv_aio_cancel completes the request or not. */
scsi_req_unref(&r->req);
}
r->req.aiocb = NULL;
}
static uint32_t scsi_init_iovec(SCSIDiskReq *r, size_t size)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
@@ -185,6 +168,7 @@ static void scsi_aio_complete(void *opaque, int ret)
r->req.aiocb = NULL;
block_acct_done(bdrv_get_stats(s->qdev.conf.bs), &r->acct);
if (r->req.io_canceled) {
scsi_req_cancel_complete(&r->req);
goto done;
}
@@ -197,10 +181,8 @@ static void scsi_aio_complete(void *opaque, int ret)
scsi_req_complete(&r->req, GOOD);
done:
if (!r->req.io_canceled) {
scsi_req_unref(&r->req);
}
}
static bool scsi_is_cmd_fua(SCSICommand *cmd)
{
@@ -233,6 +215,7 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
if (r->req.io_canceled) {
scsi_req_cancel_complete(&r->req);
goto done;
}
@@ -246,10 +229,8 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
scsi_req_complete(&r->req, GOOD);
done:
if (!r->req.io_canceled) {
scsi_req_unref(&r->req);
}
}
static void scsi_dma_complete_noio(void *opaque, int ret)
{
@@ -261,6 +242,7 @@ static void scsi_dma_complete_noio(void *opaque, int ret)
block_acct_done(bdrv_get_stats(s->qdev.conf.bs), &r->acct);
}
if (r->req.io_canceled) {
scsi_req_cancel_complete(&r->req);
goto done;
}
@@ -280,10 +262,8 @@ static void scsi_dma_complete_noio(void *opaque, int ret)
}
done:
if (!r->req.io_canceled) {
scsi_req_unref(&r->req);
}
}
static void scsi_dma_complete(void *opaque, int ret)
{
@@ -303,6 +283,7 @@ static void scsi_read_complete(void * opaque, int ret)
r->req.aiocb = NULL;
block_acct_done(bdrv_get_stats(s->qdev.conf.bs), &r->acct);
if (r->req.io_canceled) {
scsi_req_cancel_complete(&r->req);
goto done;
}
@@ -320,10 +301,8 @@ static void scsi_read_complete(void * opaque, int ret)
scsi_req_data(&r->req, r->qiov.size);
done:
if (!r->req.io_canceled) {
scsi_req_unref(&r->req);
}
}
/* Actually issue a read to the block device. */
static void scsi_do_read(void *opaque, int ret)
@@ -337,6 +316,7 @@ static void scsi_do_read(void *opaque, int ret)
block_acct_done(bdrv_get_stats(s->qdev.conf.bs), &r->acct);
}
if (r->req.io_canceled) {
scsi_req_cancel_complete(&r->req);
goto done;
}
@@ -363,10 +343,8 @@ static void scsi_do_read(void *opaque, int ret)
}
done:
if (!r->req.io_canceled) {
scsi_req_unref(&r->req);
}
}
/* Read more data from scsi device into buffer. */
static void scsi_read_data(SCSIRequest *req)
@@ -459,6 +437,7 @@ static void scsi_write_complete(void * opaque, int ret)
block_acct_done(bdrv_get_stats(s->qdev.conf.bs), &r->acct);
}
if (r->req.io_canceled) {
scsi_req_cancel_complete(&r->req);
goto done;
}
@@ -481,10 +460,8 @@ static void scsi_write_complete(void * opaque, int ret)
}
done:
if (!r->req.io_canceled) {
scsi_req_unref(&r->req);
}
}
static void scsi_write_data(SCSIRequest *req)
{
@@ -1553,6 +1530,7 @@ static void scsi_unmap_complete(void *opaque, int ret)
r->req.aiocb = NULL;
if (r->req.io_canceled) {
scsi_req_cancel_complete(&r->req);
goto done;
}
@@ -1582,9 +1560,7 @@ static void scsi_unmap_complete(void *opaque, int ret)
scsi_req_complete(&r->req, GOOD);
done:
if (!r->req.io_canceled) {
scsi_req_unref(&r->req);
}
g_free(data);
}
@@ -1654,6 +1630,7 @@ static void scsi_write_same_complete(void *opaque, int ret)
r->req.aiocb = NULL;
block_acct_done(bdrv_get_stats(s->qdev.conf.bs), &r->acct);
if (r->req.io_canceled) {
scsi_req_cancel_complete(&r->req);
goto done;
}
@@ -1678,9 +1655,7 @@ static void scsi_write_same_complete(void *opaque, int ret)
scsi_req_complete(&r->req, GOOD);
done:
if (!r->req.io_canceled) {
scsi_req_unref(&r->req);
}
qemu_vfree(data->iov.iov_base);
g_free(data);
}
@@ -2294,7 +2269,6 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
bdrv_set_guest_block_size(s->qdev.conf.bs, s->qdev.blocksize);
bdrv_iostatus_enable(s->qdev.conf.bs);
add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, NULL);
}
static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
@@ -2346,7 +2320,6 @@ static const SCSIReqOps scsi_disk_emulate_reqops = {
.send_command = scsi_disk_emulate_command,
.read_data = scsi_disk_emulate_read_data,
.write_data = scsi_disk_emulate_write_data,
.cancel_io = scsi_cancel_io,
.get_buf = scsi_get_buf,
};
@@ -2356,7 +2329,6 @@ static const SCSIReqOps scsi_disk_dma_reqops = {
.send_command = scsi_disk_dma_command,
.read_data = scsi_read_data,
.write_data = scsi_write_data,
.cancel_io = scsi_cancel_io,
.get_buf = scsi_get_buf,
.load_request = scsi_disk_load_request,
.save_request = scsi_disk_save_request,
@@ -2689,7 +2661,6 @@ static const TypeInfo scsi_cd_info = {
#ifdef __linux__
static Property scsi_block_properties[] = {
DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.bs),
DEFINE_PROP_INT32("bootindex", SCSIDiskState, qdev.conf.bootindex, -1),
DEFINE_PROP_END_OF_LIST(),
};

View File

@@ -93,6 +93,10 @@ static void scsi_command_complete(void *opaque, int ret)
SCSIGenericReq *r = (SCSIGenericReq *)opaque;
r->req.aiocb = NULL;
if (r->req.io_canceled) {
scsi_req_cancel_complete(&r->req);
goto done;
}
if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
r->req.sense_len = r->io_header.sb_len_wr;
}
@@ -133,27 +137,9 @@ static void scsi_command_complete(void *opaque, int ret)
r, r->req.tag, status);
scsi_req_complete(&r->req, status);
if (!r->req.io_canceled) {
done:
scsi_req_unref(&r->req);
}
}
/* Cancel a pending data transfer. */
static void scsi_cancel_io(SCSIRequest *req)
{
SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
DPRINTF("Cancel tag=0x%x\n", req->tag);
if (r->req.aiocb) {
bdrv_aio_cancel(r->req.aiocb);
/* This reference was left in by scsi_*_data. We take ownership of
* it independent of whether bdrv_aio_cancel completes the request
* or not. */
scsi_req_unref(&r->req);
}
r->req.aiocb = NULL;
}
static int execute_command(BlockDriverState *bdrv,
SCSIGenericReq *r, int direction,
@@ -186,8 +172,7 @@ static void scsi_read_complete(void * opaque, int ret)
int len;
r->req.aiocb = NULL;
if (ret) {
DPRINTF("IO error ret %d\n", ret);
if (ret || r->req.io_canceled) {
scsi_command_complete(r, ret);
return;
}
@@ -211,11 +196,9 @@ static void scsi_read_complete(void * opaque, int ret)
bdrv_set_guest_block_size(s->conf.bs, s->blocksize);
scsi_req_data(&r->req, len);
if (!r->req.io_canceled) {
scsi_req_unref(&r->req);
}
}
}
/* Read more data from scsi device into buffer. */
static void scsi_read_data(SCSIRequest *req)
@@ -246,8 +229,7 @@ static void scsi_write_complete(void * opaque, int ret)
DPRINTF("scsi_write_complete() ret = %d\n", ret);
r->req.aiocb = NULL;
if (ret) {
DPRINTF("IO error\n");
if (ret || r->req.io_canceled) {
scsi_command_complete(r, ret);
return;
}
@@ -431,9 +413,6 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
/* define device state */
s->type = scsiid.scsi_type;
DPRINTF("device type %d\n", s->type);
if (s->type == TYPE_DISK || s->type == TYPE_ROM) {
add_boot_device_path(s->conf.bootindex, &s->qdev, NULL);
}
switch (s->type) {
case TYPE_TAPE:
@@ -465,7 +444,6 @@ const SCSIReqOps scsi_generic_req_ops = {
.send_command = scsi_send_command,
.read_data = scsi_read_data,
.write_data = scsi_write_data,
.cancel_io = scsi_cancel_io,
.get_buf = scsi_get_buf,
.load_request = scsi_generic_load_request,
.save_request = scsi_generic_save_request,
@@ -482,7 +460,6 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
static Property scsi_generic_properties[] = {
DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs),
DEFINE_PROP_INT32("bootindex", SCSIDevice, conf.bootindex, -1),
DEFINE_PROP_END_OF_LIST(),
};

View File

@@ -77,8 +77,9 @@ typedef struct vscsi_req {
SCSIRequest *sreq;
uint32_t qtag; /* qemu tag != srp tag */
bool active;
uint32_t data_len;
bool writing;
bool dma_error;
uint32_t data_len;
uint32_t senselen;
uint8_t sense[SCSI_SENSE_BUF_SIZE];
@@ -536,8 +537,8 @@ static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
}
if (rc < 0) {
fprintf(stderr, "VSCSI: RDMA error rc=%d!\n", rc);
vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);
scsi_req_abort(req->sreq, CHECK_CONDITION);
req->dma_error = true;
scsi_req_cancel(req->sreq);
return;
}
@@ -591,6 +592,12 @@ static void vscsi_request_cancelled(SCSIRequest *sreq)
{
vscsi_req *req = sreq->hba_private;
if (req->dma_error) {
VSCSIState *s = VIO_SPAPR_VSCSI_DEVICE(sreq->bus->qbus.parent);
vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);
vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
}
vscsi_put_req(req);
}

View File

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

View File

@@ -0,0 +1,229 @@
/*
* Virtio SCSI dataplane
*
* Copyright Red Hat, Inc. 2014
*
* Authors:
* Fam Zheng <famz@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/
#include "hw/virtio/virtio-scsi.h"
#include "qemu/error-report.h"
#include <hw/scsi/scsi.h>
#include <block/scsi.h>
#include <hw/virtio/virtio-bus.h>
#include "hw/virtio/virtio-access.h"
#include "stdio.h"
/* Context: QEMU global mutex held */
void virtio_scsi_set_iothread(VirtIOSCSI *s, IOThread *iothread)
{
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
assert(!s->ctx);
s->ctx = iothread_get_aio_context(vs->conf.iothread);
/* Don't try if transport does not support notifiers. */
if (!k->set_guest_notifiers || !k->set_host_notifier) {
fprintf(stderr, "virtio-scsi: Failed to set iothread "
"(transport does not support notifiers)");
exit(1);
}
}
static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s,
VirtQueue *vq,
EventNotifierHandler *handler,
int n)
{
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
VirtIOSCSIVring *r = g_slice_new(VirtIOSCSIVring);
/* Set up virtqueue notify */
if (k->set_host_notifier(qbus->parent, n, true) != 0) {
fprintf(stderr, "virtio-scsi: Failed to set host notifier\n");
exit(1);
}
r->host_notifier = *virtio_queue_get_host_notifier(vq);
r->guest_notifier = *virtio_queue_get_guest_notifier(vq);
aio_set_event_notifier(s->ctx, &r->host_notifier, handler);
r->parent = s;
if (!vring_setup(&r->vring, VIRTIO_DEVICE(s), n)) {
fprintf(stderr, "virtio-scsi: VRing setup failed\n");
exit(1);
}
return r;
}
VirtIOSCSIReq *virtio_scsi_pop_req_vring(VirtIOSCSI *s,
VirtIOSCSIVring *vring)
{
VirtIOSCSIReq *req = virtio_scsi_init_req(s, NULL);
int r;
req->vring = vring;
r = vring_pop((VirtIODevice *)s, &vring->vring, &req->elem);
if (r < 0) {
virtio_scsi_free_req(req);
req = NULL;
}
return req;
}
void virtio_scsi_vring_push_notify(VirtIOSCSIReq *req)
{
vring_push(&req->vring->vring, &req->elem,
req->qsgl.size + req->resp_iov.size);
event_notifier_set(&req->vring->guest_notifier);
}
static void virtio_scsi_iothread_handle_ctrl(EventNotifier *notifier)
{
VirtIOSCSIVring *vring = container_of(notifier,
VirtIOSCSIVring, host_notifier);
VirtIOSCSI *s = VIRTIO_SCSI(vring->parent);
VirtIOSCSIReq *req;
event_notifier_test_and_clear(notifier);
while ((req = virtio_scsi_pop_req_vring(s, vring))) {
virtio_scsi_handle_ctrl_req(s, req);
}
}
static void virtio_scsi_iothread_handle_event(EventNotifier *notifier)
{
VirtIOSCSIVring *vring = container_of(notifier,
VirtIOSCSIVring, host_notifier);
VirtIOSCSI *s = vring->parent;
VirtIODevice *vdev = VIRTIO_DEVICE(s);
event_notifier_test_and_clear(notifier);
if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
return;
}
if (s->events_dropped) {
virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
}
}
static void virtio_scsi_iothread_handle_cmd(EventNotifier *notifier)
{
VirtIOSCSIVring *vring = container_of(notifier,
VirtIOSCSIVring, host_notifier);
VirtIOSCSI *s = (VirtIOSCSI *)vring->parent;
VirtIOSCSIReq *req, *next;
QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
event_notifier_test_and_clear(notifier);
while ((req = virtio_scsi_pop_req_vring(s, vring))) {
if (virtio_scsi_handle_cmd_req_prepare(s, req)) {
QTAILQ_INSERT_TAIL(&reqs, req, next);
}
}
QTAILQ_FOREACH_SAFE(req, &reqs, next, next) {
virtio_scsi_handle_cmd_req_submit(s, req);
}
}
/* Context: QEMU global mutex held */
void virtio_scsi_dataplane_start(VirtIOSCSI *s)
{
int i;
int rc;
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
if (s->dataplane_started ||
s->dataplane_starting ||
s->ctx != iothread_get_aio_context(vs->conf.iothread)) {
return;
}
s->dataplane_starting = true;
/* Set up guest notifier (irq) */
rc = k->set_guest_notifiers(qbus->parent, vs->conf.num_queues + 2, true);
if (rc != 0) {
fprintf(stderr, "virtio-scsi: Failed to set guest notifiers, "
"ensure -enable-kvm is set\n");
exit(1);
}
aio_context_acquire(s->ctx);
s->ctrl_vring = virtio_scsi_vring_init(s, vs->ctrl_vq,
virtio_scsi_iothread_handle_ctrl,
0);
s->event_vring = virtio_scsi_vring_init(s, vs->event_vq,
virtio_scsi_iothread_handle_event,
1);
s->cmd_vrings = g_malloc0(sizeof(VirtIOSCSIVring) * vs->conf.num_queues);
for (i = 0; i < vs->conf.num_queues; i++) {
s->cmd_vrings[i] =
virtio_scsi_vring_init(s, vs->cmd_vqs[i],
virtio_scsi_iothread_handle_cmd,
i + 2);
}
aio_context_release(s->ctx);
s->dataplane_starting = false;
s->dataplane_started = true;
}
/* Context: QEMU global mutex held */
void virtio_scsi_dataplane_stop(VirtIOSCSI *s)
{
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
VirtIODevice *vdev = VIRTIO_DEVICE(s);
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
int i;
if (!s->dataplane_started || s->dataplane_stopping) {
return;
}
s->dataplane_stopping = true;
assert(s->ctx == iothread_get_aio_context(vs->conf.iothread));
aio_context_acquire(s->ctx);
aio_set_event_notifier(s->ctx, &s->ctrl_vring->host_notifier, NULL);
aio_set_event_notifier(s->ctx, &s->event_vring->host_notifier, NULL);
for (i = 0; i < vs->conf.num_queues; i++) {
aio_set_event_notifier(s->ctx, &s->cmd_vrings[i]->host_notifier, NULL);
}
bdrv_drain_all(); /* ensure there are no in-flight requests */
aio_context_release(s->ctx);
/* Sync vring state back to virtqueue so that non-dataplane request
* processing can continue when we disable the host notifier below.
*/
vring_teardown(&s->ctrl_vring->vring, vdev, 0);
vring_teardown(&s->event_vring->vring, vdev, 1);
for (i = 0; i < vs->conf.num_queues; i++) {
vring_teardown(&s->cmd_vrings[i]->vring, vdev, 2 + i);
}
for (i = 0; i < vs->conf.num_queues + 2; i++) {
k->set_host_notifier(qbus->parent, i, false);
}
/* Clean up guest notifier (irq) */
k->set_guest_notifiers(qbus->parent, vs->conf.num_queues + 2, false);
s->dataplane_stopping = false;
s->dataplane_started = false;
}

View File

@@ -20,34 +20,7 @@
#include <block/scsi.h>
#include <hw/virtio/virtio-bus.h>
#include "hw/virtio/virtio-access.h"
typedef struct VirtIOSCSIReq {
VirtIOSCSI *dev;
VirtQueue *vq;
VirtQueueElement elem;
QEMUSGList qsgl;
SCSIRequest *sreq;
size_t resp_size;
enum SCSIXferMode mode;
QEMUIOVector resp_iov;
union {
VirtIOSCSICmdResp cmd;
VirtIOSCSICtrlTMFResp tmf;
VirtIOSCSICtrlANResp an;
VirtIOSCSIEvent event;
} resp;
union {
struct {
VirtIOSCSICmdReq cmd;
uint8_t cdb[];
} QEMU_PACKED;
VirtIOSCSICtrlTMFReq tmf;
VirtIOSCSICtrlANReq an;
} req;
} VirtIOSCSIReq;
QEMU_BUILD_BUG_ON(offsetof(VirtIOSCSIReq, req.cdb) !=
offsetof(VirtIOSCSIReq, req.cmd) + sizeof(VirtIOSCSICmdReq));
#include "migration/migration.h"
static inline int virtio_scsi_get_lun(uint8_t *lun)
{
@@ -65,26 +38,29 @@ static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun)
return scsi_device_find(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun));
}
static VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq)
VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq)
{
VirtIOSCSIReq *req;
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
req = g_malloc0(sizeof(*req) + vs->cdb_size);
VirtIOSCSICommon *vs = (VirtIOSCSICommon *)s;
const size_t zero_skip = offsetof(VirtIOSCSIReq, elem)
+ sizeof(VirtQueueElement);
req = g_slice_alloc(sizeof(*req) + vs->cdb_size);
req->vq = vq;
req->dev = s;
req->sreq = NULL;
qemu_sglist_init(&req->qsgl, DEVICE(s), 8, &address_space_memory);
qemu_iovec_init(&req->resp_iov, 1);
memset((uint8_t *)req + zero_skip, 0, sizeof(*req) - zero_skip);
return req;
}
static void virtio_scsi_free_req(VirtIOSCSIReq *req)
void virtio_scsi_free_req(VirtIOSCSIReq *req)
{
VirtIOSCSICommon *vs = (VirtIOSCSICommon *)req->dev;
qemu_iovec_destroy(&req->resp_iov);
qemu_sglist_destroy(&req->qsgl);
g_free(req);
g_slice_free1(sizeof(*req) + vs->cdb_size, req);
}
static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
@@ -94,13 +70,19 @@ static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
VirtIODevice *vdev = VIRTIO_DEVICE(s);
qemu_iovec_from_buf(&req->resp_iov, 0, &req->resp, req->resp_size);
if (req->vring) {
assert(req->vq == NULL);
virtio_scsi_vring_push_notify(req);
} else {
virtqueue_push(vq, &req->elem, req->qsgl.size + req->resp_iov.size);
virtio_notify(vdev, vq);
}
if (req->sreq) {
req->sreq->hba_private = NULL;
scsi_req_unref(req->sreq);
}
virtio_scsi_free_req(req);
virtio_notify(vdev, vq);
}
static void virtio_scsi_bad_req(void)
@@ -226,13 +208,39 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
return req;
}
static void virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
typedef struct {
Notifier notifier;
VirtIOSCSIReq *tmf_req;
} VirtIOSCSICancelNotifier;
static void virtio_scsi_cancel_notify(Notifier *notifier, void *data)
{
VirtIOSCSICancelNotifier *n = container_of(notifier,
VirtIOSCSICancelNotifier,
notifier);
if (--n->tmf_req->remaining == 0) {
virtio_scsi_complete_req(n->tmf_req);
}
g_slice_free(VirtIOSCSICancelNotifier, n);
}
/* Return 0 if the request is ready to be completed and return to guest;
* -EINPROGRESS if the request is submitted and will be completed later, in the
* case of async cancellation. */
static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
{
SCSIDevice *d = virtio_scsi_device_find(s, req->req.tmf.lun);
SCSIRequest *r, *next;
BusChild *kid;
int target;
int ret = 0;
if (s->dataplane_started && bdrv_get_aio_context(d->conf.bs) != s->ctx) {
aio_context_acquire(s->ctx);
bdrv_set_aio_context(d->conf.bs, s->ctx);
aio_context_release(s->ctx);
}
/* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */
req->resp.tmf.response = VIRTIO_SCSI_S_OK;
@@ -264,7 +272,14 @@ static void virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
*/
req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;
} else {
scsi_req_cancel(r);
VirtIOSCSICancelNotifier *notifier;
req->remaining = 1;
notifier = g_slice_new(VirtIOSCSICancelNotifier);
notifier->tmf_req = req;
notifier->notifier.notify = virtio_scsi_cancel_notify;
scsi_req_cancel_async(r, &notifier->notifier);
ret = -EINPROGRESS;
}
}
break;
@@ -290,6 +305,13 @@ static void virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {
goto incorrect_lun;
}
/* Add 1 to "remaining" until virtio_scsi_do_tmf returns.
* This way, if the bus starts calling back to the notifiers
* even before we finish the loop, virtio_scsi_cancel_notify
* will not complete the TMF too early.
*/
req->remaining = 1;
QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) {
if (r->hba_private) {
if (req->req.tmf.subtype == VIRTIO_SCSI_T_TMF_QUERY_TASK_SET) {
@@ -299,10 +321,19 @@ static void virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;
break;
} else {
scsi_req_cancel(r);
VirtIOSCSICancelNotifier *notifier;
req->remaining++;
notifier = g_slice_new(VirtIOSCSICancelNotifier);
notifier->notifier.notify = virtio_scsi_cancel_notify;
notifier->tmf_req = req;
scsi_req_cancel_async(r, &notifier->notifier);
}
}
}
if (--req->remaining > 0) {
ret = -EINPROGRESS;
}
break;
case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
@@ -323,28 +354,27 @@ static void virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
break;
}
return;
return ret;
incorrect_lun:
req->resp.tmf.response = VIRTIO_SCSI_S_INCORRECT_LUN;
return;
return ret;
fail:
req->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET;
return ret;
}
static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
{
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
VirtIOSCSIReq *req;
while ((req = virtio_scsi_pop_req(s, vq))) {
VirtIODevice *vdev = (VirtIODevice *)s;
int type;
int r = 0;
if (iov_to_buf(req->elem.out_sg, req->elem.out_num, 0,
&type, sizeof(type)) < sizeof(type)) {
virtio_scsi_bad_req();
continue;
return;
}
virtio_tswap32s(vdev, &req->req.tmf.type);
@@ -353,7 +383,7 @@ static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
sizeof(VirtIOSCSICtrlTMFResp)) < 0) {
virtio_scsi_bad_req();
} else {
virtio_scsi_do_tmf(s, req);
r = virtio_scsi_do_tmf(s, req);
}
} else if (req->req.tmf.type == VIRTIO_SCSI_T_AN_QUERY ||
@@ -366,7 +396,24 @@ static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
req->resp.an.response = VIRTIO_SCSI_S_OK;
}
}
if (r == 0) {
virtio_scsi_complete_req(req);
} else {
assert(r == -EINPROGRESS);
}
}
static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
VirtIOSCSIReq *req;
if (s->ctx && !s->dataplane_disabled) {
virtio_scsi_dataplane_start(s);
return;
}
while ((req = virtio_scsi_pop_req(s, vq))) {
virtio_scsi_handle_ctrl_req(s, req);
}
}
@@ -420,13 +467,7 @@ static int virtio_scsi_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
* host device passthrough.
*/
cmd->xfer = req->qsgl.size;
if (cmd->xfer == 0) {
cmd->mode = SCSI_XFER_NONE;
} else if (iov_size(req->elem.in_sg, req->elem.in_num) > req->resp_size) {
cmd->mode = SCSI_XFER_FROM_DEV;
} else {
cmd->mode = SCSI_XFER_TO_DEV;
}
cmd->mode = req->mode;
return 0;
}
@@ -458,16 +499,9 @@ static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq *req)
virtio_scsi_complete_cmd_req(req);
}
static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
{
/* use non-QOM casts in the data path */
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
VirtIOSCSICommon *vs = &s->parent_obj;
VirtIOSCSIReq *req;
int n;
while ((req = virtio_scsi_pop_req(s, vq))) {
SCSIDevice *d;
int rc;
@@ -479,14 +513,19 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
} else {
virtio_scsi_bad_req();
}
continue;
return false;
}
d = virtio_scsi_device_find(s, req->req.cmd.lun);
if (!d) {
req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET;
virtio_scsi_complete_cmd_req(req);
continue;
return false;
}
if (s->dataplane_started && bdrv_get_aio_context(d->conf.bs) != s->ctx) {
aio_context_acquire(s->ctx);
bdrv_set_aio_context(d->conf.bs, s->ctx);
aio_context_release(s->ctx);
}
req->sreq = scsi_req_new(d, req->req.cmd.tag,
virtio_scsi_get_lun(req->req.cmd.lun),
@@ -497,13 +536,42 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
req->sreq->cmd.xfer > req->qsgl.size)) {
req->resp.cmd.response = VIRTIO_SCSI_S_OVERRUN;
virtio_scsi_complete_cmd_req(req);
continue;
return false;
}
scsi_req_ref(req->sreq);
bdrv_io_plug(d->conf.bs);
return true;
}
n = scsi_req_enqueue(req->sreq);
if (n) {
scsi_req_continue(req->sreq);
void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
{
SCSIRequest *sreq = req->sreq;
if (scsi_req_enqueue(sreq)) {
scsi_req_continue(sreq);
}
bdrv_io_unplug(sreq->dev->conf.bs);
scsi_req_unref(sreq);
}
static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
{
/* use non-QOM casts in the data path */
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
VirtIOSCSIReq *req, *next;
QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
if (s->ctx && !s->dataplane_disabled) {
virtio_scsi_dataplane_start(s);
return;
}
while ((req = virtio_scsi_pop_req(s, vq))) {
if (virtio_scsi_handle_cmd_req_prepare(s, req)) {
QTAILQ_INSERT_TAIL(&reqs, req, next);
}
}
QTAILQ_FOREACH_SAFE(req, &reqs, next, next) {
virtio_scsi_handle_cmd_req_submit(s, req);
}
}
@@ -552,6 +620,9 @@ static void virtio_scsi_reset(VirtIODevice *vdev)
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
if (s->ctx) {
virtio_scsi_dataplane_stop(s);
}
s->resetting++;
qbus_reset_all(&s->bus.qbus);
s->resetting--;
@@ -582,7 +653,7 @@ static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
uint32_t event, uint32_t reason)
{
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
@@ -594,10 +665,19 @@ static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
return;
}
if (s->dataplane_started) {
assert(s->ctx);
aio_context_acquire(s->ctx);
}
if (s->dataplane_started) {
req = virtio_scsi_pop_req_vring(s, s->event_vring);
} else {
req = virtio_scsi_pop_req(s, vs->event_vq);
}
if (!req) {
s->events_dropped = true;
return;
goto out;
}
if (s->events_dropped) {
@@ -626,12 +706,20 @@ static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
evt->lun[3] = dev->lun & 0xFF;
}
virtio_scsi_complete_req(req);
out:
if (s->dataplane_started) {
aio_context_release(s->ctx);
}
}
static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
if (s->ctx && !s->dataplane_disabled) {
virtio_scsi_dataplane_start(s);
return;
}
if (s->events_dropped) {
virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
}
@@ -717,6 +805,35 @@ void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
s->cmd_vqs[i] = virtio_add_queue(vdev, VIRTIO_SCSI_VQ_SIZE,
cmd);
}
if (s->conf.iothread) {
virtio_scsi_set_iothread(VIRTIO_SCSI(s), s->conf.iothread);
}
}
/* Disable dataplane thread during live migration since it does not
* update the dirty memory bitmap yet.
*/
static void virtio_scsi_migration_state_changed(Notifier *notifier, void *data)
{
VirtIOSCSI *s = container_of(notifier, VirtIOSCSI,
migration_state_notifier);
MigrationState *mig = data;
if (migration_in_setup(mig)) {
if (!s->dataplane_started) {
return;
}
virtio_scsi_dataplane_stop(s);
s->dataplane_disabled = true;
} else if (migration_has_finished(mig) ||
migration_has_failed(mig)) {
if (s->dataplane_started) {
return;
}
bdrv_drain_all(); /* complete in-flight non-dataplane requests */
s->dataplane_disabled = false;
}
}
static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
@@ -747,6 +864,18 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
register_savevm(dev, "virtio-scsi", virtio_scsi_id++, 1,
virtio_scsi_save, virtio_scsi_load, s);
s->migration_state_notifier.notify = virtio_scsi_migration_state_changed;
add_migration_state_change_notifier(&s->migration_state_notifier);
}
static void virtio_scsi_instance_init(Object *obj)
{
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(obj);
object_property_add_link(obj, "iothread", TYPE_IOTHREAD,
(Object **)&vs->conf.iothread,
qdev_prop_allow_set_link_before_realize,
OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
}
void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp)
@@ -763,6 +892,7 @@ static void virtio_scsi_device_unrealize(DeviceState *dev, Error **errp)
VirtIOSCSI *s = VIRTIO_SCSI(dev);
unregister_savevm(dev, "virtio-scsi", s);
remove_migration_state_change_notifier(&s->migration_state_notifier);
virtio_scsi_common_unrealize(dev, errp);
}
@@ -807,6 +937,7 @@ static const TypeInfo virtio_scsi_info = {
.name = TYPE_VIRTIO_SCSI,
.parent = TYPE_VIRTIO_SCSI_COMMON,
.instance_size = sizeof(VirtIOSCSI),
.instance_init = virtio_scsi_instance_init,
.class_init = virtio_scsi_class_init,
};

View File

@@ -864,7 +864,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
for(i = 0; i < nb_nics; i++)
pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);
ide_drive_get(hd, MAX_IDE_BUS);
ide_drive_get(hd, ARRAY_SIZE(hd));
pci_cmd646_ide_init(pci_bus, hd, 1);

View File

@@ -1371,8 +1371,16 @@ static void usb_net_realize(USBDevice *dev, Error **errrp)
s->conf.macaddr.a[4],
s->conf.macaddr.a[5]);
usb_desc_set_string(dev, STRING_ETHADDR, s->usbstring_mac);
}
add_boot_device_path(s->conf.bootindex, &dev->qdev, "/ethernet@0");
static void usb_net_instance_init(Object *obj)
{
USBDevice *dev = USB_DEVICE(obj);
USBNetState *s = DO_UPCAST(USBNetState, dev, dev);
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
&dev->qdev, NULL);
}
static USBDevice *usb_net_init(USBBus *bus, const char *cmdline)
@@ -1438,6 +1446,7 @@ static const TypeInfo net_info = {
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBNetState),
.class_init = usb_net_class_initfn,
.instance_init = usb_net_instance_init,
};
static void usb_net_register_types(void)

View File

@@ -17,6 +17,7 @@
#include "monitor/monitor.h"
#include "sysemu/sysemu.h"
#include "sysemu/blockdev.h"
#include "qapi/visitor.h"
//#define DEBUG_MSD
@@ -59,6 +60,7 @@ typedef struct {
/* usb-storage only */
BlockConf conf;
uint32_t removable;
SCSIDevice *scsi_dev;
} MSDState;
struct usb_msd_cbw {
@@ -634,6 +636,7 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
}
s->bus.qbus.allow_hotplug = 0;
usb_msd_handle_reset(dev);
s->scsi_dev = scsi_dev;
if (bdrv_key_required(bs)) {
if (cur_mon) {
@@ -767,6 +770,54 @@ static void usb_msd_class_initfn_storage(ObjectClass *klass, void *data)
usb_msd_class_initfn_common(klass);
}
static void usb_msd_get_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
USBDevice *dev = USB_DEVICE(obj);
MSDState *s = DO_UPCAST(MSDState, dev, dev);
visit_type_int32(v, &s->conf.bootindex, name, errp);
}
static void usb_msd_set_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
USBDevice *dev = USB_DEVICE(obj);
MSDState *s = DO_UPCAST(MSDState, dev, dev);
int32_t boot_index;
Error *local_err = NULL;
visit_type_int32(v, &boot_index, name, &local_err);
if (local_err) {
goto out;
}
/* check whether bootindex is present in fw_boot_order list */
check_boot_index(boot_index, &local_err);
if (local_err) {
goto out;
}
/* change bootindex to a new one */
s->conf.bootindex = boot_index;
if (s->scsi_dev) {
object_property_set_int(OBJECT(s->scsi_dev), boot_index, "bootindex",
&error_abort);
}
out:
if (local_err) {
error_propagate(errp, local_err);
}
}
static void usb_msd_instance_init(Object *obj)
{
object_property_add(obj, "bootindex", "int32",
usb_msd_get_bootindex,
usb_msd_set_bootindex, NULL, NULL, NULL);
object_property_set_int(obj, -1, "bootindex", NULL);
}
static void usb_msd_class_initfn_bot(ObjectClass *klass, void *data)
{
USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
@@ -780,6 +831,7 @@ static const TypeInfo msd_info = {
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(MSDState),
.class_init = usb_msd_class_initfn_storage,
.instance_init = usb_msd_instance_init,
};
static const TypeInfo bot_info = {

View File

@@ -978,10 +978,19 @@ static void usb_host_realize(USBDevice *udev, Error **errp)
qemu_add_exit_notifier(&s->exit);
QTAILQ_INSERT_TAIL(&hostdevs, s, next);
add_boot_device_path(s->bootindex, &udev->qdev, NULL);
usb_host_auto_check(NULL);
}
static void usb_host_instance_init(Object *obj)
{
USBDevice *udev = USB_DEVICE(obj);
USBHostDevice *s = USB_HOST_DEVICE(udev);
device_add_bootindex_property(obj, &s->bootindex,
"bootindex", NULL,
&udev->qdev, NULL);
}
static void usb_host_handle_destroy(USBDevice *udev)
{
USBHostDevice *s = USB_HOST_DEVICE(udev);
@@ -1465,7 +1474,6 @@ static Property usb_host_dev_properties[] = {
DEFINE_PROP_UINT32("productid", USBHostDevice, match.product_id, 0),
DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames, 32),
DEFINE_PROP_INT32("bootindex", USBHostDevice, bootindex, -1),
DEFINE_PROP_UINT32("loglevel", USBHostDevice, loglevel,
LIBUSB_LOG_LEVEL_WARNING),
DEFINE_PROP_BIT("pipeline", USBHostDevice, options,
@@ -1498,6 +1506,7 @@ static TypeInfo usb_host_dev_info = {
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBHostDevice),
.class_init = usb_host_class_initfn,
.instance_init = usb_host_instance_init,
};
static void usb_host_register_types(void)

View File

@@ -1401,7 +1401,6 @@ static void usbredir_realize(USBDevice *udev, Error **errp)
usbredir_chardev_read, usbredir_chardev_event, dev);
qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev);
add_boot_device_path(dev->bootindex, &udev->qdev, NULL);
}
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
@@ -2471,7 +2470,6 @@ static Property usbredir_properties[] = {
DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, usbredirparser_warning),
DEFINE_PROP_STRING("filter", USBRedirDevice, filter_str),
DEFINE_PROP_INT32("bootindex", USBRedirDevice, bootindex, -1),
DEFINE_PROP_END_OF_LIST(),
};
@@ -2496,11 +2494,22 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static void usbredir_instance_init(Object *obj)
{
USBDevice *udev = USB_DEVICE(obj);
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
device_add_bootindex_property(obj, &dev->bootindex,
"bootindex", NULL,
&udev->qdev, NULL);
}
static const TypeInfo usbredir_dev_info = {
.name = "usb-redir",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBRedirDevice),
.class_init = usbredir_class_initfn,
.instance_init = usbredir_instance_init,
};
static void usbredir_register_types(void)

View File

@@ -86,6 +86,9 @@
* 12 is historical, and due to x86 page size. */
#define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12
/* Flags track per-device state like workarounds for quirks in older guests. */
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG (1 << 0)
static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
VirtIOPCIProxy *dev);
@@ -320,6 +323,14 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
proxy->pci_dev.config[PCI_COMMAND] |
PCI_COMMAND_MASTER, 1);
}
/* Linux before 2.6.34 sets the device as OK without enabling
the PCI device bus master bit. In this case we need to disable
some safety checks. */
if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
!(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
}
break;
case VIRTIO_MSI_CONFIG_VECTOR:
msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
@@ -469,18 +480,13 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
uint8_t cmd = proxy->pci_dev.config[PCI_COMMAND];
pci_default_write_config(pci_dev, address, val, len);
if (range_covers_byte(address, len, PCI_COMMAND) &&
!(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
(cmd & PCI_COMMAND_MASTER)) {
/* Bus driver disables bus mastering - make it act
* as a kind of reset to render the device quiescent. */
!(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
virtio_pci_stop_ioeventfd(proxy);
virtio_reset(vdev);
msix_unuse_all_vectors(&proxy->pci_dev);
virtio_set_status(vdev, vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
}
}
@@ -889,19 +895,11 @@ static void virtio_pci_vmstate_change(DeviceState *d, bool running)
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
if (running) {
/* Linux before 2.6.34 drives the device without enabling
the PCI device bus master bit. Enable it automatically
for the guest. This is a PCI spec violation but so is
initiating DMA with bus master bit clear.
Note: this only makes a difference when migrating
across QEMU versions from an old QEMU, as for new QEMU
bus master and driver bits are always in sync.
TODO: consider enabling conditionally for compat machine types. */
if (vdev->status & (VIRTIO_CONFIG_S_ACKNOWLEDGE |
VIRTIO_CONFIG_S_DRIVER)) {
pci_default_write_config(&proxy->pci_dev, PCI_COMMAND,
proxy->pci_dev.config[PCI_COMMAND] |
PCI_COMMAND_MASTER, 1);
/* Try to find out if the guest has bus master disabled, but is
in ready state. Then we have a buggy guest OS. */
if ((vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
!(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
}
virtio_pci_start_ioeventfd(proxy);
} else {
@@ -926,7 +924,6 @@ static Property virtio_9p_pci_properties[] = {
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
DEFINE_VIRTIO_9P_PROPERTIES(V9fsPCIState, vdev.fsconf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -948,8 +945,9 @@ static void virtio_9p_pci_class_init(ObjectClass *klass, void *data)
static void virtio_9p_pci_instance_init(Object *obj)
{
V9fsPCIState *dev = VIRTIO_9P_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_9P);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_9P);
}
static const TypeInfo virtio_9p_pci_info = {
@@ -1042,6 +1040,7 @@ static void virtio_pci_reset(DeviceState *qdev)
virtio_pci_stop_ioeventfd(proxy);
virtio_bus_reset(bus);
msix_unuse_all_vectors(&proxy->pci_dev);
proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
}
static Property virtio_pci_properties[] = {
@@ -1111,12 +1110,13 @@ static void virtio_blk_pci_class_init(ObjectClass *klass, void *data)
static void virtio_blk_pci_instance_init(Object *obj)
{
VirtIOBlkPCI *dev = VIRTIO_BLK_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BLK);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_BLK);
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
&error_abort);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
static const TypeInfo virtio_blk_pci_info = {
@@ -1135,7 +1135,6 @@ static Property virtio_scsi_pci_properties[] = {
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
DEV_NVECTORS_UNSPECIFIED),
DEFINE_VIRTIO_SCSI_FEATURES(VirtIOPCIProxy, host_features),
DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIPCI, vdev.parent_obj.conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1185,8 +1184,11 @@ static void virtio_scsi_pci_class_init(ObjectClass *klass, void *data)
static void virtio_scsi_pci_instance_init(Object *obj)
{
VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_SCSI);
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev), "iothread",
&error_abort);
}
static const TypeInfo virtio_scsi_pci_info = {
@@ -1203,7 +1205,6 @@ static const TypeInfo virtio_scsi_pci_info = {
static Property vhost_scsi_pci_properties[] = {
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
DEV_NVECTORS_UNSPECIFIED),
DEFINE_VHOST_SCSI_PROPERTIES(VHostSCSIPCI, vdev.parent_obj.conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1241,8 +1242,9 @@ static void vhost_scsi_pci_class_init(ObjectClass *klass, void *data)
static void vhost_scsi_pci_instance_init(Object *obj)
{
VHostSCSIPCI *dev = VHOST_SCSI_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VHOST_SCSI);
}
static const TypeInfo vhost_scsi_pci_info = {
@@ -1323,7 +1325,7 @@ static void virtio_balloon_pci_instance_init(Object *obj)
VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_unref(OBJECT(&dev->vdev));
object_property_add(obj, "guest-stats", "guest statistics",
balloon_pci_stats_get_all, NULL, NULL, dev,
NULL);
@@ -1385,7 +1387,6 @@ static Property virtio_serial_pci_properties[] = {
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtIOSerialPCI, vdev.serial),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1406,8 +1407,9 @@ static void virtio_serial_pci_class_init(ObjectClass *klass, void *data)
static void virtio_serial_pci_instance_init(Object *obj)
{
VirtIOSerialPCI *dev = VIRTIO_SERIAL_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_SERIAL);
}
static const TypeInfo virtio_serial_pci_info = {
@@ -1425,8 +1427,6 @@ static Property virtio_net_properties[] = {
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
DEFINE_NIC_PROPERTIES(VirtIONetPCI, vdev.nic_conf),
DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetPCI, vdev.net_conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1465,8 +1465,11 @@ static void virtio_net_pci_class_init(ObjectClass *klass, void *data)
static void virtio_net_pci_instance_init(Object *obj)
{
VirtIONetPCI *dev = VIRTIO_NET_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_NET);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
static const TypeInfo virtio_net_pci_info = {
@@ -1480,7 +1483,6 @@ static const TypeInfo virtio_net_pci_info = {
/* virtio-rng-pci */
static Property virtio_rng_pci_properties[] = {
DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORngPCI, vdev.conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1520,8 +1522,9 @@ static void virtio_rng_pci_class_init(ObjectClass *klass, void *data)
static void virtio_rng_initfn(Object *obj)
{
VirtIORngPCI *dev = VIRTIO_RNG_PCI(obj);
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_RNG);
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
(Object **)&dev->vdev.conf.rng,
qdev_prop_allow_set_link_before_realize,

View File

@@ -1123,6 +1123,17 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
}
}
void virtio_instance_init_common(Object *proxy_obj, void *data,
size_t vdev_size, const char *vdev_name)
{
DeviceState *vdev = data;
object_initialize(vdev, vdev_size, vdev_name);
object_property_add_child(proxy_obj, "virtio-backend", OBJECT(vdev), NULL);
object_unref(OBJECT(vdev));
qdev_alias_all_properties(vdev, proxy_obj);
}
void virtio_init(VirtIODevice *vdev, const char *name,
uint16_t device_id, size_t config_size)
{

View File

@@ -473,14 +473,35 @@ typedef struct {
#define PPC_FEATURE_TRUE_LE 0x00000002
#define PPC_FEATURE_PPC_LE 0x00000001
/* Bits present in AT_HWCAP, primarily for Sparc32. */
/* Bits present in AT_HWCAP for Sparc. */
#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */
#define HWCAP_SPARC_STBAR 2
#define HWCAP_SPARC_SWAP 4
#define HWCAP_SPARC_MULDIV 8
#define HWCAP_SPARC_V9 16
#define HWCAP_SPARC_ULTRA3 32
#define HWCAP_SPARC_FLUSH 0x00000001
#define HWCAP_SPARC_STBAR 0x00000002
#define HWCAP_SPARC_SWAP 0x00000004
#define HWCAP_SPARC_MULDIV 0x00000008
#define HWCAP_SPARC_V9 0x00000010
#define HWCAP_SPARC_ULTRA3 0x00000020
#define HWCAP_SPARC_BLKINIT 0x00000040
#define HWCAP_SPARC_N2 0x00000080
#define HWCAP_SPARC_MUL32 0x00000100
#define HWCAP_SPARC_DIV32 0x00000200
#define HWCAP_SPARC_FSMULD 0x00000400
#define HWCAP_SPARC_V8PLUS 0x00000800
#define HWCAP_SPARC_POPC 0x00001000
#define HWCAP_SPARC_VIS 0x00002000
#define HWCAP_SPARC_VIS2 0x00004000
#define HWCAP_SPARC_ASI_BLK_INIT 0x00008000
#define HWCAP_SPARC_FMAF 0x00010000
#define HWCAP_SPARC_VIS3 0x00020000
#define HWCAP_SPARC_HPC 0x00040000
#define HWCAP_SPARC_RANDOM 0x00080000
#define HWCAP_SPARC_TRANS 0x00100000
#define HWCAP_SPARC_FJFMAU 0x00200000
#define HWCAP_SPARC_IMA 0x00400000
#define HWCAP_SPARC_ASI_CACHE_SPARING 0x00800000
#define HWCAP_SPARC_PAUSE 0x01000000
#define HWCAP_SPARC_CBCOND 0x02000000
#define HWCAP_SPARC_CRYPTO 0x04000000
/* Bits present in AT_HWCAP for s390. */

View File

@@ -232,8 +232,8 @@ extern uintptr_t qemu_host_page_mask;
#if defined(CONFIG_USER_ONLY)
void page_dump(FILE *f);
typedef int (*walk_memory_regions_fn)(void *, abi_ulong,
abi_ulong, unsigned long);
typedef int (*walk_memory_regions_fn)(void *, target_ulong,
target_ulong, unsigned long);
int walk_memory_regions(void *, walk_memory_regions_fn);
int page_get_flags(target_ulong address);

View File

@@ -49,7 +49,6 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
_conf.physical_block_size, 512), \
DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \
DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0), \
DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1), \
DEFINE_PROP_UINT32("discard_granularity", _state, \
_conf.discard_granularity, -1)

View File

@@ -5,12 +5,11 @@
#include "qemu/typedefs.h"
#include "sysemu/blockdev.h"
#include "sysemu/accel.h"
#include "hw/qdev.h"
#include "qom/object.h"
typedef struct MachineState MachineState;
typedef void QEMUMachineInitFunc(MachineState *ms);
typedef void QEMUMachineResetFunc(void);
@@ -28,6 +27,7 @@ struct QEMUMachine {
QEMUMachineHotAddCPUFunc *hot_add_cpu;
QEMUMachineGetKvmtypeFunc *kvm_type;
BlockInterfaceType block_default_type;
int units_per_default_bus;
int max_cpus;
unsigned int no_serial:1,
no_parallel:1,
@@ -86,6 +86,7 @@ struct MachineClass {
int (*kvm_type)(const char *arg);
BlockInterfaceType block_default_type;
int units_per_default_bus;
int max_cpus;
unsigned int no_serial:1,
no_parallel:1,
@@ -133,6 +134,7 @@ struct MachineState {
char *kernel_cmdline;
char *initrd_filename;
const char *cpu_model;
AccelState *accelerator;
};
#endif

View File

@@ -147,7 +147,6 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
}
i++;
}
if (nsyms) {
syms = g_realloc(syms, nsyms * sizeof(*syms));
qsort(syms, nsyms, sizeof(*syms), glue(symcmp, SZ));
@@ -156,10 +155,6 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
syms[i].st_size = syms[i + 1].st_value - syms[i].st_value;
}
}
} else {
g_free(syms);
syms = NULL;
}
/* String table */
if (symtab->sh_link >= ehdr->e_shnum)

View File

@@ -76,6 +76,8 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
FWCfgReadCallback callback, void *callback_opaque,
void *data, size_t len);
void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data,
size_t len);
FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
hwaddr crl_addr, hwaddr data_addr);

View File

@@ -5,6 +5,7 @@
#include "block/block.h"
#include "hw/block/block.h"
#include "sysemu/sysemu.h"
#include "qemu/notify.h"
#define MAX_SCSI_DEVS 255
@@ -50,17 +51,25 @@ struct SCSIRequest {
uint32_t tag;
uint32_t lun;
uint32_t status;
void *hba_private;
size_t resid;
SCSICommand cmd;
BlockDriverAIOCB *aiocb;
QEMUSGList *sg;
bool dma_started;
NotifierList cancel_notifiers;
/* Note:
* - fields before sense are initialized by scsi_req_alloc;
* - sense[] is uninitialized;
* - fields after sense are memset to 0 by scsi_req_alloc.
* */
uint8_t sense[SCSI_SENSE_BUF_SIZE];
uint32_t sense_len;
bool enqueued;
bool io_canceled;
bool retry;
void *hba_private;
bool dma_started;
BlockDriverAIOCB *aiocb;
QEMUSGList *sg;
QTAILQ_ENTRY(SCSIRequest) next;
};
@@ -123,7 +132,6 @@ struct SCSIReqOps {
int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
void (*read_data)(SCSIRequest *req);
void (*write_data)(SCSIRequest *req);
void (*cancel_io)(SCSIRequest *req);
uint8_t *(*get_buf)(SCSIRequest *req);
void (*save_request)(QEMUFile *f, SCSIRequest *req);
@@ -258,8 +266,9 @@ void scsi_req_data(SCSIRequest *req, int len);
void scsi_req_complete(SCSIRequest *req, int status);
uint8_t *scsi_req_get_buf(SCSIRequest *req);
int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len);
void scsi_req_abort(SCSIRequest *req, int status);
void scsi_req_cancel_complete(SCSIRequest *req);
void scsi_req_cancel(SCSIRequest *req);
void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier);
void scsi_req_retry(SCSIRequest *req);
void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense);
void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense);

View File

@@ -17,6 +17,8 @@
#include "hw/virtio/virtio.h"
#include "hw/pci/pci.h"
#include "hw/scsi/scsi.h"
#include "sysemu/iothread.h"
#include "hw/virtio/dataplane/vring.h"
#define TYPE_VIRTIO_SCSI_COMMON "virtio-scsi-common"
#define VIRTIO_SCSI_COMMON(obj) \
@@ -151,8 +153,18 @@ struct VirtIOSCSIConf {
uint32_t cmd_per_lun;
char *vhostfd;
char *wwpn;
IOThread *iothread;
};
struct VirtIOSCSI;
typedef struct {
struct VirtIOSCSI *parent;
Vring vring;
EventNotifier host_notifier;
EventNotifier guest_notifier;
} VirtIOSCSIVring;
typedef struct VirtIOSCSICommon {
VirtIODevice parent_obj;
VirtIOSCSIConf conf;
@@ -164,14 +176,74 @@ typedef struct VirtIOSCSICommon {
VirtQueue **cmd_vqs;
} VirtIOSCSICommon;
typedef struct {
typedef struct VirtIOSCSI {
VirtIOSCSICommon parent_obj;
SCSIBus bus;
int resetting;
bool events_dropped;
/* Fields for dataplane below */
AioContext *ctx; /* one iothread per virtio-scsi-pci for now */
/* Vring is used instead of vq in dataplane code, because of the underlying
* memory layer thread safety */
VirtIOSCSIVring *ctrl_vring;
VirtIOSCSIVring *event_vring;
VirtIOSCSIVring **cmd_vrings;
bool dataplane_started;
bool dataplane_starting;
bool dataplane_stopping;
bool dataplane_disabled;
Notifier migration_state_notifier;
} VirtIOSCSI;
typedef struct VirtIOSCSIReq {
VirtIOSCSI *dev;
VirtQueue *vq;
QEMUSGList qsgl;
QEMUIOVector resp_iov;
/* Note:
* - fields before elem are initialized by virtio_scsi_init_req;
* - elem is uninitialized at the time of allocation.
* - fields after elem are zeroed by virtio_scsi_init_req.
* */
VirtQueueElement elem;
/* Set by dataplane code. */
VirtIOSCSIVring *vring;
union {
/* Used for two-stage request submission */
QTAILQ_ENTRY(VirtIOSCSIReq) next;
/* Used for cancellation of request during TMFs */
int remaining;
};
SCSIRequest *sreq;
size_t resp_size;
enum SCSIXferMode mode;
union {
VirtIOSCSICmdResp cmd;
VirtIOSCSICtrlTMFResp tmf;
VirtIOSCSICtrlANResp an;
VirtIOSCSIEvent event;
} resp;
union {
struct {
VirtIOSCSICmdReq cmd;
uint8_t cdb[];
} QEMU_PACKED;
VirtIOSCSICtrlTMFReq tmf;
VirtIOSCSICtrlANReq an;
} req;
} VirtIOSCSIReq;
QEMU_BUILD_BUG_ON(offsetof(VirtIOSCSIReq, req.cdb) !=
offsetof(VirtIOSCSIReq, req.cmd) + sizeof(VirtIOSCSICmdReq));
#define DEFINE_VIRTIO_SCSI_PROPERTIES(_state, _conf_field) \
DEFINE_PROP_UINT32("num_queues", _state, _conf_field.num_queues, 1), \
DEFINE_PROP_UINT32("max_sectors", _state, _conf_field.max_sectors, 0xFFFF),\
@@ -192,5 +264,19 @@ void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
HandleOutput cmd);
void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp);
void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req);
bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req);
void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req);
VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq);
void virtio_scsi_free_req(VirtIOSCSIReq *req);
void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
uint32_t event, uint32_t reason);
void virtio_scsi_set_iothread(VirtIOSCSI *s, IOThread *iothread);
void virtio_scsi_dataplane_start(VirtIOSCSI *s);
void virtio_scsi_dataplane_stop(VirtIOSCSI *s);
void virtio_scsi_vring_push_notify(VirtIOSCSIReq *req);
VirtIOSCSIReq *virtio_scsi_pop_req_vring(VirtIOSCSI *s,
VirtIOSCSIVring *vring);
#endif /* _QEMU_VIRTIO_SCSI_H */

View File

@@ -161,6 +161,9 @@ typedef struct VirtioDeviceClass {
int (*load)(VirtIODevice *vdev, QEMUFile *f, int version_id);
} VirtioDeviceClass;
void virtio_instance_init_common(Object *proxy_obj, void *data,
size_t vdev_size, const char *vdev_name);
void virtio_init(VirtIODevice *vdev, const char *name,
uint16_t device_id, size_t config_size);
void virtio_cleanup(VirtIODevice *vdev);

View File

@@ -36,7 +36,6 @@ void xen_cmos_set_s3_resume(void *opaque, int irq, int level);
qemu_irq *xen_interrupt_controller_init(void);
int xen_init(MachineClass *mc);
void xenstore_store_pv_console_info(int i, struct CharDriverState *chr);
#if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY)

View File

@@ -36,8 +36,7 @@ typedef struct NICConf {
#define DEFINE_NIC_PROPERTIES(_state, _conf) \
DEFINE_PROP_MACADDR("mac", _state, _conf.macaddr), \
DEFINE_PROP_VLAN("vlan", _state, _conf.peers), \
DEFINE_PROP_NETDEV("netdev", _state, _conf.peers), \
DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1)
DEFINE_PROP_NETDEV("netdev", _state, _conf.peers)
/* Net clients */

View File

@@ -190,6 +190,9 @@ int64_t strtosz_suffix_unit(const char *nptr, char **end,
/* used to print char* safely */
#define STR_OR_NULL(str) ((str) ? (str) : "null")
/* id.c */
bool id_wellformed(const char *id);
/* path.c */
void init_paths(const char *prefix);
const char *path(const char *pathname);

View File

@@ -88,10 +88,19 @@ int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
int slow_bitmap_intersects(const unsigned long *bitmap1,
const unsigned long *bitmap2, long bits);
static inline unsigned long *bitmap_new(long nbits)
static inline unsigned long *bitmap_try_new(long nbits)
{
long len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
return g_malloc0(len);
return g_try_malloc0(len);
}
static inline unsigned long *bitmap_new(long nbits)
{
unsigned long *ptr = bitmap_try_new(nbits);
if (ptr == NULL) {
abort();
}
return ptr;
}
static inline void bitmap_zero(unsigned long *dst, long nbits)

View File

@@ -24,6 +24,12 @@
#define QEMU_WARN_UNUSED_RESULT
#endif
#if QEMU_GNUC_PREREQ(4, 3)
#define QEMU_ARTIFICIAL __attribute__((always_inline, artificial))
#else
#define QEMU_ARTIFICIAL
#endif
#if defined(_WIN32)
# define QEMU_PACKED __attribute__((gcc_struct, packed))
#else

View File

@@ -38,6 +38,7 @@ void error_vprintf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
void error_printf(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
void error_printf_unless_qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
void error_set_progname(const char *argv0);
void error_vreport(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
const char *error_get_progname(void);
extern bool enable_timestamp_msg;

View File

@@ -103,7 +103,6 @@ typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaq
int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
int abort_on_failure);
int qemu_opts_id_wellformed(const char *id);
QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id);
QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
int fail_if_exists, Error **errp);

View File

@@ -47,7 +47,7 @@ int recv_all(int fd, void *buf, int len1, bool single_read);
/* callback function for nonblocking connect
* valid fd on success, negative error code on failure
*/
typedef void NonBlockingConnectHandler(int fd, void *opaque);
typedef void NonBlockingConnectHandler(int fd, Error *errp, void *opaque);
InetSocketAddress *inet_parse(const char *str, Error **errp);
int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp);

View File

@@ -32,6 +32,7 @@ typedef struct MemoryMappingList MemoryMappingList;
typedef struct QEMUMachine QEMUMachine;
typedef struct MachineClass MachineClass;
typedef struct MachineState MachineState;
typedef struct NICInfo NICInfo;
typedef struct HCIInfo HCIInfo;
typedef struct AudioState AudioState;

View File

@@ -99,6 +99,8 @@ struct TranslationBlock;
* @vmsd: State description for migration.
* @gdb_num_core_regs: Number of core registers accessible to GDB.
* @gdb_core_xml_file: File name for core registers GDB XML description.
* @gdb_stop_before_watchpoint: Indicates whether GDB expects the CPU to stop
* before the insn which triggers a watchpoint rather than after it.
* @cpu_exec_enter: Callback for cpu_exec preparation.
* @cpu_exec_exit: Callback for cpu_exec cleanup.
* @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec.
@@ -152,6 +154,7 @@ typedef struct CPUClass {
const struct VMStateDescription *vmsd;
int gdb_num_core_regs;
const char *gdb_core_xml_file;
bool gdb_stop_before_watchpoint;
void (*cpu_exec_enter)(CPUState *cpu);
void (*cpu_exec_exit)(CPUState *cpu);

62
include/sysemu/accel.h Normal file
View File

@@ -0,0 +1,62 @@
/* QEMU accelerator interfaces
*
* Copyright (c) 2014 Red Hat Inc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef HW_ACCEL_H
#define HW_ACCEL_H
#include "qemu/typedefs.h"
#include "qom/object.h"
typedef struct AccelState {
/*< private >*/
Object parent_obj;
} AccelState;
typedef struct AccelClass {
/*< private >*/
ObjectClass parent_class;
/*< public >*/
const char *opt_name;
const char *name;
int (*available)(void);
int (*init_machine)(MachineState *ms);
bool *allowed;
} AccelClass;
#define TYPE_ACCEL "accel"
#define ACCEL_CLASS_SUFFIX "-" TYPE_ACCEL
#define ACCEL_CLASS_NAME(a) (a ACCEL_CLASS_SUFFIX)
#define ACCEL_CLASS(klass) \
OBJECT_CLASS_CHECK(AccelClass, (klass), TYPE_ACCEL)
#define ACCEL(obj) \
OBJECT_CHECK(AccelState, (obj), TYPE_ACCEL)
#define ACCEL_GET_CLASS(obj) \
OBJECT_GET_CLASS(AccelClass, (obj), TYPE_ACCEL)
extern int tcg_tb_size;
int configure_accelerator(MachineState *ms);
#endif

View File

@@ -33,7 +33,6 @@ void do_smbios_option(QemuOpts *opts);
void ram_mig_init(void);
void cpudef_init(void);
void audio_init(void);
int tcg_available(void);
int kvm_available(void);
int xen_available(void);

View File

@@ -38,6 +38,7 @@ struct DriveInfo {
int unit;
int auto_del; /* see blockdev_mark_auto_del() */
bool enable_auto_del; /* Only for legacy drive_new() */
bool is_default; /* Added by default_drive() ? */
int media_cd;
int cyls, heads, secs, trans;
QemuOpts *opts;
@@ -45,9 +46,13 @@ struct DriveInfo {
QTAILQ_ENTRY(DriveInfo) next;
};
void override_max_devs(BlockInterfaceType type, int max_devs);
DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
bool drive_check_orphaned(void);
DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
int drive_get_max_bus(BlockInterfaceType type);
int drive_get_max_devs(BlockInterfaceType type);
DriveInfo *drive_get_next(BlockInterfaceType type);
DriveInfo *drive_get_by_blockdev(BlockDriverState *bs);

View File

@@ -163,8 +163,6 @@ extern KVMState *kvm_state;
/* external API */
int kvm_init(MachineClass *mc);
int kvm_has_sync_mmu(void);
int kvm_has_vcpu_events(void);
int kvm_has_robust_singlestep(void);

View File

@@ -26,7 +26,6 @@ static inline bool qtest_enabled(void)
bool qtest_driver(void);
int qtest_init_accel(MachineClass *mc);
void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);
static inline int qtest_available(void)

View File

@@ -130,6 +130,7 @@ extern int no_shutdown;
extern int semihosting_enabled;
extern int old_param;
extern int boot_menu;
extern bool boot_strict;
extern uint8_t *boot_splash_filedata;
extern size_t boot_splash_filedata_size;
extern uint8_t qemu_extra_params_fw[2];
@@ -212,6 +213,11 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
char *get_boot_devices_list(size_t *size, bool ignore_suffixes);
DeviceState *get_boot_device(uint32_t position);
void check_boot_index(int32_t bootindex, Error **errp);
void del_boot_device_path(DeviceState *dev, const char *suffix);
void device_add_bootindex_property(Object *obj, int32_t *bootindex,
const char *name, const char *suffix,
DeviceState *dev, Error **errp);
QemuOpts *qemu_get_machine_opts(void);

View File

@@ -25,6 +25,7 @@
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "sysemu/sysemu.h"
#include "sysemu/accel.h"
#include "hw/hw.h"
#include "hw/pci/msi.h"
#include "hw/s390x/adapter.h"
@@ -72,6 +73,8 @@ typedef struct kvm_dirty_log KVMDirtyLog;
struct KVMState
{
AccelState parent_obj;
KVMSlot *slots;
int nr_slots;
int fd;
@@ -106,6 +109,11 @@ struct KVMState
#endif
};
#define TYPE_KVM_ACCEL ACCEL_CLASS_NAME("kvm")
#define KVM_STATE(obj) \
OBJECT_CHECK(KVMState, (obj), TYPE_KVM_ACCEL)
KVMState *kvm_state;
bool kvm_kernel_irqchip;
bool kvm_async_interrupts_allowed;
@@ -1377,8 +1385,9 @@ static int kvm_max_vcpus(KVMState *s)
return (ret) ? ret : kvm_recommended_vcpus(s);
}
int kvm_init(MachineClass *mc)
static int kvm_init(MachineState *ms)
{
MachineClass *mc = MACHINE_GET_CLASS(ms);
static const char upgrade_note[] =
"Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
"(see http://sourceforge.net/projects/kvm).\n";
@@ -1397,7 +1406,7 @@ int kvm_init(MachineClass *mc)
int i, type = 0;
const char *kvm_type;
s = g_malloc0(sizeof(KVMState));
s = KVM_STATE(ms->accelerator);
/*
* On systems where the kernel can support different base page
@@ -1586,7 +1595,6 @@ err:
close(s->fd);
}
g_free(s->slots);
g_free(s);
return ret;
}
@@ -2225,3 +2233,25 @@ int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target)
}
return r;
}
static void kvm_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
ac->name = "KVM";
ac->init_machine = kvm_init;
ac->allowed = &kvm_allowed;
}
static const TypeInfo kvm_accel_type = {
.name = TYPE_KVM_ACCEL,
.parent = TYPE_ACCEL,
.class_init = kvm_accel_class_init,
.instance_size = sizeof(KVMState),
};
static void kvm_type_init(void)
{
type_register_static(&kvm_accel_type);
}
type_init(kvm_type_init);

View File

@@ -35,11 +35,6 @@ int kvm_init_vcpu(CPUState *cpu)
return -ENOSYS;
}
int kvm_init(MachineClass *mc)
{
return -ENOSYS;
}
void kvm_flush_coalesced_mmio_buffer(void)
{
}

View File

@@ -1 +1,5 @@
#include <asm-generic/kvm_para.h>
#ifndef _ASM_MIPS_KVM_PARA_H
#define _ASM_MIPS_KVM_PARA_H
#endif /* _ASM_MIPS_KVM_PARA_H */

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