mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-11 03:24:58 -06:00

commit 33cd52b5d7
unset
cannot_instantiate_with_device_add_yet in TYPE_SYSBUS, making all
sysbus devices appear on "-device help" and lack the "no-user"
flag in "info qdm".
To fix this, we can set user_creatable=false by default on
TYPE_SYS_BUS_DEVICE, but this requires setting
user_creatable=true explicitly on the sysbus devices that
actually work with -device.
Fortunately today we have just a few has_dynamic_sysbus=1
machines: virt, pc-q35-*, ppce500, and spapr.
virt, ppce500, and spapr have extra checks to ensure just a few
device types can be instantiated:
* virt supports only TYPE_VFIO_CALXEDA_XGMAC, TYPE_VFIO_AMD_XGBE.
* ppce500 supports only TYPE_ETSEC_COMMON.
* spapr supports only TYPE_SPAPR_PCI_HOST_BRIDGE.
This patch sets user_creatable=true explicitly on those 4 device
classes.
Now, the more complex cases:
pc-q35-*: q35 has no sysbus device whitelist yet (which is a
separate bug). We are in the process of fixing it and building a
sysbus whitelist on q35, but in the meantime we can fix the
"-device help" and "info qdm" bugs mentioned above. Also, despite
not being strictly necessary for fixing the q35 bug, reducing the
list of user_creatable=true devices will help us be more
confident when building the q35 whitelist.
xen: We also have a hack at xen_set_dynamic_sysbus(), that sets
has_dynamic_sysbus=true at runtime when using the Xen
accelerator. This hack is only used to allow xen-backend devices
to be dynamically plugged/unplugged.
This means today we can use -device with the following 22 device
types, that are the ones compiled into the qemu-system-x86_64 and
qemu-system-i386 binaries:
* allwinner-ahci
* amd-iommu
* cfi.pflash01
* esp
* fw_cfg_io
* fw_cfg_mem
* generic-sdhci
* hpet
* intel-iommu
* ioapic
* isabus-bridge
* kvmclock
* kvm-ioapic
* kvmvapic
* SUNW,fdtwo
* sysbus-ahci
* sysbus-fdc
* sysbus-ohci
* unimplemented-device
* virtio-mmio
* xen-backend
* xen-sysdev
This patch adds user_creatable=true explicitly to those devices,
temporarily, just to keep 100% compatibility with existing
behavior of q35. Subsequent patches will remove
user_creatable=true from the devices that are really not meant to
user-creatable on any machine, and remove the FIXME comment from
the ones that are really supposed to be user-creatable. This is
being done in separate patches because we still don't have an
obvious list of devices that will be whitelisted by q35, and I
would like to get each device reviewed individually.
Cc: Alexander Graf <agraf@suse.de>
Cc: Alex Williamson <alex.williamson@redhat.com>
Cc: Alistair Francis <alistair.francis@xilinx.com>
Cc: Beniamino Galvani <b.galvani@gmail.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Cc: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Frank Blaschka <frank.blaschka@de.ibm.com>
Cc: Gabriel L. Somlo <somlo@cmu.edu>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: John Snow <jsnow@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Marcel Apfelbaum <marcel@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Pierre Morel <pmorel@linux.vnet.ibm.com>
Cc: Prasad J Pandit <pjp@fedoraproject.org>
Cc: qemu-arm@nongnu.org
Cc: qemu-block@nongnu.org
Cc: qemu-ppc@nongnu.org
Cc: Richard Henderson <rth@twiddle.net>
Cc: Rob Herring <robh@kernel.org>
Cc: Shannon Zhao <zhaoshenglong@huawei.com>
Cc: sstabellini@kernel.org
Cc: Thomas Huth <thuth@redhat.com>
Cc: Yi Min Zhao <zyimin@linux.vnet.ibm.com>
Acked-by: John Snow <jsnow@redhat.com>
Acked-by: Juergen Gross <jgross@suse.com>
Acked-by: Marcel Apfelbaum <marcel@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20170503203604.31462-3-ehabkost@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[ehabkost: Small changes at sysbus_device_class_init() comments]
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
189 lines
4.8 KiB
C
189 lines
4.8 KiB
C
/*
|
|
* KVM in-kernel IOPIC support
|
|
*
|
|
* Copyright (c) 2011 Siemens AG
|
|
*
|
|
* Authors:
|
|
* Jan Kiszka <jan.kiszka@siemens.com>
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL version 2.
|
|
* See the COPYING file in the top-level directory.
|
|
*/
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "monitor/monitor.h"
|
|
#include "hw/i386/pc.h"
|
|
#include "hw/i386/ioapic_internal.h"
|
|
#include "hw/i386/apic_internal.h"
|
|
#include "sysemu/kvm.h"
|
|
|
|
/* PC Utility function */
|
|
void kvm_pc_setup_irq_routing(bool pci_enabled)
|
|
{
|
|
KVMState *s = kvm_state;
|
|
int i;
|
|
|
|
if (kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) {
|
|
for (i = 0; i < 8; ++i) {
|
|
if (i == 2) {
|
|
continue;
|
|
}
|
|
kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_MASTER, i);
|
|
}
|
|
for (i = 8; i < 16; ++i) {
|
|
kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_SLAVE, i - 8);
|
|
}
|
|
if (pci_enabled) {
|
|
for (i = 0; i < 24; ++i) {
|
|
if (i == 0) {
|
|
kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, 2);
|
|
} else if (i != 2) {
|
|
kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, i);
|
|
}
|
|
}
|
|
}
|
|
kvm_irqchip_commit_routes(s);
|
|
}
|
|
}
|
|
|
|
void kvm_pc_gsi_handler(void *opaque, int n, int level)
|
|
{
|
|
GSIState *s = opaque;
|
|
|
|
if (n < ISA_NUM_IRQS) {
|
|
/* Kernel will forward to both PIC and IOAPIC */
|
|
qemu_set_irq(s->i8259_irq[n], level);
|
|
} else {
|
|
qemu_set_irq(s->ioapic_irq[n], level);
|
|
}
|
|
}
|
|
|
|
typedef struct KVMIOAPICState KVMIOAPICState;
|
|
|
|
struct KVMIOAPICState {
|
|
IOAPICCommonState ioapic;
|
|
uint32_t kvm_gsi_base;
|
|
};
|
|
|
|
static void kvm_ioapic_get(IOAPICCommonState *s)
|
|
{
|
|
struct kvm_irqchip chip;
|
|
struct kvm_ioapic_state *kioapic;
|
|
int ret, i;
|
|
|
|
chip.chip_id = KVM_IRQCHIP_IOAPIC;
|
|
ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, &chip);
|
|
if (ret < 0) {
|
|
fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret));
|
|
abort();
|
|
}
|
|
|
|
kioapic = &chip.chip.ioapic;
|
|
|
|
s->id = kioapic->id;
|
|
s->ioregsel = kioapic->ioregsel;
|
|
s->irr = kioapic->irr;
|
|
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
|
|
s->ioredtbl[i] = kioapic->redirtbl[i].bits;
|
|
}
|
|
}
|
|
|
|
static void kvm_ioapic_put(IOAPICCommonState *s)
|
|
{
|
|
struct kvm_irqchip chip;
|
|
struct kvm_ioapic_state *kioapic;
|
|
int ret, i;
|
|
|
|
chip.chip_id = KVM_IRQCHIP_IOAPIC;
|
|
kioapic = &chip.chip.ioapic;
|
|
|
|
kioapic->id = s->id;
|
|
kioapic->ioregsel = s->ioregsel;
|
|
kioapic->base_address = s->busdev.mmio[0].addr;
|
|
kioapic->irr = s->irr;
|
|
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
|
|
kioapic->redirtbl[i].bits = s->ioredtbl[i];
|
|
}
|
|
|
|
ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, &chip);
|
|
if (ret < 0) {
|
|
fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret));
|
|
abort();
|
|
}
|
|
}
|
|
|
|
void kvm_ioapic_dump_state(Monitor *mon, const QDict *qdict)
|
|
{
|
|
IOAPICCommonState *s = IOAPIC_COMMON(object_resolve_path("ioapic", NULL));
|
|
|
|
assert(s);
|
|
kvm_ioapic_get(s);
|
|
ioapic_print_redtbl(mon, s);
|
|
}
|
|
|
|
static void kvm_ioapic_reset(DeviceState *dev)
|
|
{
|
|
IOAPICCommonState *s = IOAPIC_COMMON(dev);
|
|
|
|
ioapic_reset_common(dev);
|
|
kvm_ioapic_put(s);
|
|
}
|
|
|
|
static void kvm_ioapic_set_irq(void *opaque, int irq, int level)
|
|
{
|
|
KVMIOAPICState *s = opaque;
|
|
int delivered;
|
|
|
|
delivered = kvm_set_irq(kvm_state, s->kvm_gsi_base + irq, level);
|
|
apic_report_irq_delivered(delivered);
|
|
}
|
|
|
|
static void kvm_ioapic_realize(DeviceState *dev, Error **errp)
|
|
{
|
|
IOAPICCommonState *s = IOAPIC_COMMON(dev);
|
|
|
|
memory_region_init_reservation(&s->io_memory, NULL, "kvm-ioapic", 0x1000);
|
|
/*
|
|
* KVM ioapic only supports 0x11 now. This will only be used when
|
|
* we want to dump ioapic version.
|
|
*/
|
|
s->version = 0x11;
|
|
|
|
qdev_init_gpio_in(dev, kvm_ioapic_set_irq, IOAPIC_NUM_PINS);
|
|
}
|
|
|
|
static Property kvm_ioapic_properties[] = {
|
|
DEFINE_PROP_UINT32("gsi_base", KVMIOAPICState, kvm_gsi_base, 0),
|
|
DEFINE_PROP_END_OF_LIST()
|
|
};
|
|
|
|
static void kvm_ioapic_class_init(ObjectClass *klass, void *data)
|
|
{
|
|
IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
|
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
|
|
|
k->realize = kvm_ioapic_realize;
|
|
k->pre_save = kvm_ioapic_get;
|
|
k->post_load = kvm_ioapic_put;
|
|
dc->reset = kvm_ioapic_reset;
|
|
dc->props = kvm_ioapic_properties;
|
|
/*
|
|
* FIXME: Set only because we are not sure yet if this device
|
|
* will be outside the q35 sysbus whitelist.
|
|
*/
|
|
dc->user_creatable = true;
|
|
}
|
|
|
|
static const TypeInfo kvm_ioapic_info = {
|
|
.name = "kvm-ioapic",
|
|
.parent = TYPE_IOAPIC_COMMON,
|
|
.instance_size = sizeof(KVMIOAPICState),
|
|
.class_init = kvm_ioapic_class_init,
|
|
};
|
|
|
|
static void kvm_ioapic_register_types(void)
|
|
{
|
|
type_register_static(&kvm_ioapic_info);
|
|
}
|
|
|
|
type_init(kvm_ioapic_register_types)
|