
commit 33cd52b5d7b9adfd009e95f07e6c64dd88ae2a31 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>
190 lines
4.8 KiB
C
190 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)
|