From 1190044ea5a1c9a871664c4e2013072e51e56d5a Mon Sep 17 00:00:00 2001 From: Shannon Zhao Date: Mon, 11 May 2015 17:34:05 +0800 Subject: hw/virtio/virtio-balloon: move adding property to virtio_balloon_instance_init This is in preparation for using alias property in virtio-balloon-pci and virtio-balloon-ccw. Signed-off-by: Shannon Zhao Signed-off-by: Shannon Zhao Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Cornelia Huck Reviewed-by: Paolo Bonzini --- hw/virtio/virtio-balloon.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 484c3c333c..cfff542f38 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -396,14 +396,6 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) register_savevm(dev, "virtio-balloon", -1, 1, virtio_balloon_save, virtio_balloon_load, s); - - object_property_add(OBJECT(dev), "guest-stats", "guest statistics", - balloon_stats_get_all, NULL, NULL, s, NULL); - - object_property_add(OBJECT(dev), "guest-stats-polling-interval", "int", - balloon_stats_get_poll_interval, - balloon_stats_set_poll_interval, - NULL, s, NULL); } static void virtio_balloon_device_unrealize(DeviceState *dev, Error **errp) @@ -417,6 +409,19 @@ static void virtio_balloon_device_unrealize(DeviceState *dev, Error **errp) virtio_cleanup(vdev); } +static void virtio_balloon_instance_init(Object *obj) +{ + VirtIOBalloon *s = VIRTIO_BALLOON(obj); + + object_property_add(obj, "guest-stats", "guest statistics", + balloon_stats_get_all, NULL, NULL, s, NULL); + + object_property_add(obj, "guest-stats-polling-interval", "int", + balloon_stats_get_poll_interval, + balloon_stats_set_poll_interval, + NULL, s, NULL); +} + static Property virtio_balloon_properties[] = { DEFINE_PROP_END_OF_LIST(), }; @@ -441,6 +446,7 @@ static const TypeInfo virtio_balloon_info = { .name = TYPE_VIRTIO_BALLOON, .parent = TYPE_VIRTIO_DEVICE, .instance_size = sizeof(VirtIOBalloon), + .instance_init = virtio_balloon_instance_init, .class_init = virtio_balloon_class_init, }; -- cgit v1.2.3 From 39b87c7b9f8bf3618e0357699d29615e521264d8 Mon Sep 17 00:00:00 2001 From: Shannon Zhao Date: Mon, 11 May 2015 17:34:06 +0800 Subject: hw/virtio/virtio-pci: use alias property for virtio-balloon-pci Signed-off-by: Shannon Zhao Signed-off-by: Shannon Zhao Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Cornelia Huck Reviewed-by: Paolo Bonzini --- hw/virtio/virtio-pci.c | 40 ++++++---------------------------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 867c9d17ca..c931790dd7 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1207,32 +1207,6 @@ static const TypeInfo vhost_scsi_pci_info = { /* virtio-balloon-pci */ -static void balloon_pci_stats_get_all(Object *obj, struct Visitor *v, - void *opaque, const char *name, - Error **errp) -{ - VirtIOBalloonPCI *dev = opaque; - object_property_get(OBJECT(&dev->vdev), v, "guest-stats", errp); -} - -static void balloon_pci_stats_get_poll_interval(Object *obj, struct Visitor *v, - void *opaque, const char *name, - Error **errp) -{ - VirtIOBalloonPCI *dev = opaque; - object_property_get(OBJECT(&dev->vdev), v, "guest-stats-polling-interval", - errp); -} - -static void balloon_pci_stats_set_poll_interval(Object *obj, struct Visitor *v, - void *opaque, const char *name, - Error **errp) -{ - VirtIOBalloonPCI *dev = opaque; - object_property_set(OBJECT(&dev->vdev), v, "guest-stats-polling-interval", - errp); -} - static Property virtio_balloon_pci_properties[] = { DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0), DEFINE_PROP_END_OF_LIST(), @@ -1269,16 +1243,14 @@ static void virtio_balloon_pci_class_init(ObjectClass *klass, void *data) static void virtio_balloon_pci_instance_init(Object *obj) { VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(obj); + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON); - object_property_add(obj, "guest-stats", "guest statistics", - balloon_pci_stats_get_all, NULL, NULL, dev, - NULL); - - object_property_add(obj, "guest-stats-polling-interval", "int", - balloon_pci_stats_get_poll_interval, - balloon_pci_stats_set_poll_interval, - NULL, dev, NULL); + object_property_add_alias(obj, "guest-stats", OBJECT(&dev->vdev), + "guest-stats", &error_abort); + object_property_add_alias(obj, "guest-stats-polling-interval", + OBJECT(&dev->vdev), + "guest-stats-polling-interval", &error_abort); } static const TypeInfo virtio_balloon_pci_info = { -- cgit v1.2.3 From ecfa60e37439c870d08a90a845b061a53aa26f74 Mon Sep 17 00:00:00 2001 From: Shannon Zhao Date: Mon, 11 May 2015 17:34:07 +0800 Subject: hw/s390x/virtio-ccw: use alias property for virtio-balloon-ccw Signed-off-by: Shannon Zhao Signed-off-by: Shannon Zhao Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Cornelia Huck Reviewed-by: Paolo Bonzini --- hw/s390x/virtio-ccw.c | 39 ++++++--------------------------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index c96101aa7c..f5f327c173 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -896,44 +896,17 @@ static void virtio_ccw_balloon_realize(VirtioCcwDevice *ccw_dev, Error **errp) } } -static void balloon_ccw_stats_get_all(Object *obj, struct Visitor *v, - void *opaque, const char *name, - Error **errp) -{ - VirtIOBalloonCcw *dev = opaque; - object_property_get(OBJECT(&dev->vdev), v, "guest-stats", errp); -} - -static void balloon_ccw_stats_get_poll_interval(Object *obj, struct Visitor *v, - void *opaque, const char *name, - Error **errp) -{ - VirtIOBalloonCcw *dev = opaque; - object_property_get(OBJECT(&dev->vdev), v, "guest-stats-polling-interval", - errp); -} - -static void balloon_ccw_stats_set_poll_interval(Object *obj, struct Visitor *v, - void *opaque, const char *name, - Error **errp) -{ - VirtIOBalloonCcw *dev = opaque; - object_property_set(OBJECT(&dev->vdev), v, "guest-stats-polling-interval", - errp); -} - static void virtio_ccw_balloon_instance_init(Object *obj) { VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj); + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON); - object_property_add(obj, "guest-stats", "guest statistics", - balloon_ccw_stats_get_all, NULL, NULL, dev, NULL); - - object_property_add(obj, "guest-stats-polling-interval", "int", - balloon_ccw_stats_get_poll_interval, - balloon_ccw_stats_set_poll_interval, - NULL, dev, NULL); + object_property_add_alias(obj, "guest-stats", OBJECT(&dev->vdev), + "guest-stats", &error_abort); + object_property_add_alias(obj, "guest-stats-polling-interval", + OBJECT(&dev->vdev), + "guest-stats-polling-interval", &error_abort); } static void virtio_ccw_scsi_realize(VirtioCcwDevice *ccw_dev, Error **errp) -- cgit v1.2.3 From 4974920ab8fc8cf05687f1f764650dbc7c821004 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 14 May 2015 15:52:58 -0300 Subject: pc: Replace tab with spaces Coding style change only. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 2 +- include/hw/i386/pc.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 212e263404..a8ff6f51c7 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -628,7 +628,7 @@ static QEMUMachine pc_i440fx_machine_v1_4 = { }; #define PC_COMPAT_1_3 \ - PC_COMPAT_1_4, \ + PC_COMPAT_1_4, \ {\ .driver = "usb-tablet",\ .property = "usb_version",\ diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 1b35168e96..7ed43f17ec 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -447,23 +447,23 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .driver = "scsi-hd",\ .property = "discard_granularity",\ .value = stringify(0),\ - },{\ + },{\ .driver = "scsi-cd",\ .property = "discard_granularity",\ .value = stringify(0),\ - },{\ + },{\ .driver = "scsi-disk",\ .property = "discard_granularity",\ .value = stringify(0),\ - },{\ + },{\ .driver = "ide-hd",\ .property = "discard_granularity",\ .value = stringify(0),\ - },{\ + },{\ .driver = "ide-cd",\ .property = "discard_granularity",\ .value = stringify(0),\ - },{\ + },{\ .driver = "ide-drive",\ .property = "discard_granularity",\ .value = stringify(0),\ @@ -471,7 +471,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .driver = "virtio-blk-pci",\ .property = "discard_granularity",\ .value = stringify(0),\ - },{\ + },{\ .driver = "virtio-serial-pci",\ .property = "vectors",\ /* DEV_NVECTORS_UNSPECIFIED as a uint32_t string */\ -- cgit v1.2.3 From f27086a731bbd0141646702c95f6dc5fce3e8575 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 14 May 2015 15:52:59 -0300 Subject: hw: Move commas inside HW_COMPAT_2_1 macro Changing the convention to include commas inside the macros will allow macros containing empty lists to be defined and used without compilation errors. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 2 +- hw/i386/pc_q35.c | 2 +- hw/ppc/spapr.c | 2 +- include/hw/compat.h | 2 +- include/hw/i386/pc.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index a8ff6f51c7..608539d42f 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -562,7 +562,7 @@ static QEMUMachine pc_i440fx_machine_v2_1 = { .name = "pc-i440fx-2.1", .init = pc_init_pci_2_1, .compat_props = (GlobalProperty[]) { - HW_COMPAT_2_1, + HW_COMPAT_2_1 { /* end of list */ } }, }; diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index e67f2dead7..36b8834925 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -458,7 +458,7 @@ static QEMUMachine pc_q35_machine_v2_1 = { .name = "pc-q35-2.1", .init = pc_q35_init_2_1, .compat_props = (GlobalProperty[]) { - HW_COMPAT_2_1, + HW_COMPAT_2_1 { /* end of list */ } }, }; diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index ac261ef050..f768de11fc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1861,7 +1861,7 @@ static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); static GlobalProperty compat_props[] = { - HW_COMPAT_2_1, + HW_COMPAT_2_1 SPAPR_COMPAT_2_1, { /* end of list */ } }; diff --git a/include/hw/compat.h b/include/hw/compat.h index 313682a708..c56a6989be 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -30,6 +30,6 @@ .driver = "virtio-pci",\ .property = "virtio-pci-bus-master-bug-migration",\ .value = "on",\ - } + }, #endif /* HW_COMPAT_H */ diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 7ed43f17ec..7673a4dfce 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -296,7 +296,7 @@ int e820_get_num_entries(void); bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); #define PC_COMPAT_2_0 \ - HW_COMPAT_2_1, \ + HW_COMPAT_2_1 \ {\ .driver = "virtio-scsi-pci",\ .property = "any_layout",\ -- cgit v1.2.3 From a7cde24dc2f104c8e5861df0e2938e79264e9d58 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 14 May 2015 15:53:00 -0300 Subject: pc: Move commas inside PC_COMPAT_* macros Changing the convention to include commas inside the macros will allow macros containing empty lists to be defined and used without compilation errors. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 62 ++++++++++++++++++++++++++-------------------------- hw/i386/pc_q35.c | 10 ++++----- include/hw/i386/pc.h | 18 +++++++-------- 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 608539d42f..25da8a5025 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -574,7 +574,7 @@ static QEMUMachine pc_i440fx_machine_v2_0 = { .name = "pc-i440fx-2.0", .init = pc_init_pci_2_0, .compat_props = (GlobalProperty[]) { - PC_COMPAT_2_0, + PC_COMPAT_2_0 { /* end of list */ } }, }; @@ -586,7 +586,7 @@ static QEMUMachine pc_i440fx_machine_v1_7 = { .name = "pc-i440fx-1.7", .init = pc_init_pci_1_7, .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_7, + PC_COMPAT_1_7 { /* end of list */ } }, }; @@ -598,7 +598,7 @@ static QEMUMachine pc_i440fx_machine_v1_6 = { .name = "pc-i440fx-1.6", .init = pc_init_pci_1_6, .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_6, + PC_COMPAT_1_6 { /* end of list */ } }, }; @@ -608,7 +608,7 @@ static QEMUMachine pc_i440fx_machine_v1_5 = { .name = "pc-i440fx-1.5", .init = pc_init_pci_1_5, .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_5, + PC_COMPAT_1_5 { /* end of list */ } }, }; @@ -622,13 +622,13 @@ static QEMUMachine pc_i440fx_machine_v1_4 = { .name = "pc-i440fx-1.4", .init = pc_init_pci_1_4, .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_4, + PC_COMPAT_1_4 { /* end of list */ } }, }; #define PC_COMPAT_1_3 \ - PC_COMPAT_1_4, \ + PC_COMPAT_1_4 \ {\ .driver = "usb-tablet",\ .property = "usb_version",\ @@ -645,20 +645,20 @@ static QEMUMachine pc_i440fx_machine_v1_4 = { .driver = "e1000",\ .property = "autonegotiation",\ .value = "off",\ - } + }, static QEMUMachine pc_machine_v1_3 = { PC_I440FX_1_4_MACHINE_OPTIONS, .name = "pc-1.3", .init = pc_init_pci_1_3, .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_3, + PC_COMPAT_1_3 { /* end of list */ } }, }; #define PC_COMPAT_1_2 \ - PC_COMPAT_1_3,\ + PC_COMPAT_1_3 \ {\ .driver = "nec-usb-xhci",\ .property = "msi",\ @@ -683,7 +683,7 @@ static QEMUMachine pc_machine_v1_3 = { .driver = "VGA",\ .property = "mmio",\ .value = "off",\ - } + }, #define PC_I440FX_1_2_MACHINE_OPTIONS \ PC_I440FX_1_4_MACHINE_OPTIONS, \ @@ -693,13 +693,13 @@ static QEMUMachine pc_machine_v1_2 = { PC_I440FX_1_2_MACHINE_OPTIONS, .name = "pc-1.2", .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_2, + PC_COMPAT_1_2 { /* end of list */ } }, }; #define PC_COMPAT_1_1 \ - PC_COMPAT_1_2,\ + PC_COMPAT_1_2 \ {\ .driver = "virtio-scsi-pci",\ .property = "hotplug",\ @@ -728,19 +728,19 @@ static QEMUMachine pc_machine_v1_2 = { .driver = "virtio-blk-pci",\ .property = "config-wce",\ .value = "off",\ - } + }, static QEMUMachine pc_machine_v1_1 = { PC_I440FX_1_2_MACHINE_OPTIONS, .name = "pc-1.1", .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_1, + PC_COMPAT_1_1 { /* end of list */ } }, }; #define PC_COMPAT_1_0 \ - PC_COMPAT_1_1,\ + PC_COMPAT_1_1 \ {\ .driver = TYPE_ISA_FDC,\ .property = "check_media_rate",\ @@ -757,13 +757,13 @@ static QEMUMachine pc_machine_v1_1 = { .driver = TYPE_USB_DEVICE,\ .property = "full-path",\ .value = "no",\ - } + }, static QEMUMachine pc_machine_v1_0 = { PC_I440FX_1_2_MACHINE_OPTIONS, .name = "pc-1.0", .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_0, + PC_COMPAT_1_0 { /* end of list */ } }, .hw_version = "1.0", @@ -776,14 +776,14 @@ static QEMUMachine pc_machine_v0_15 = { PC_I440FX_1_2_MACHINE_OPTIONS, .name = "pc-0.15", .compat_props = (GlobalProperty[]) { - PC_COMPAT_0_15, + PC_COMPAT_0_15 { /* end of list */ } }, .hw_version = "0.15", }; #define PC_COMPAT_0_14 \ - PC_COMPAT_0_15,\ + PC_COMPAT_0_15 \ {\ .driver = "virtio-blk-pci",\ .property = "event_idx",\ @@ -800,13 +800,13 @@ static QEMUMachine pc_machine_v0_15 = { .driver = "virtio-balloon-pci",\ .property = "event_idx",\ .value = "off",\ - } + }, static QEMUMachine pc_machine_v0_14 = { PC_I440FX_1_2_MACHINE_OPTIONS, .name = "pc-0.14", .compat_props = (GlobalProperty[]) { - PC_COMPAT_0_14, + PC_COMPAT_0_14 { .driver = "qxl", .property = "revision", @@ -822,7 +822,7 @@ static QEMUMachine pc_machine_v0_14 = { }; #define PC_COMPAT_0_13 \ - PC_COMPAT_0_14,\ + PC_COMPAT_0_14 \ {\ .driver = TYPE_PCI_DEVICE,\ .property = "command_serr_enable",\ @@ -831,7 +831,7 @@ static QEMUMachine pc_machine_v0_14 = { .driver = "AC97",\ .property = "use_broken_id",\ .value = stringify(1),\ - } + }, #define PC_I440FX_0_13_MACHINE_OPTIONS \ PC_I440FX_1_2_MACHINE_OPTIONS, \ @@ -841,7 +841,7 @@ static QEMUMachine pc_machine_v0_13 = { PC_I440FX_0_13_MACHINE_OPTIONS, .name = "pc-0.13", .compat_props = (GlobalProperty[]) { - PC_COMPAT_0_13, + PC_COMPAT_0_13 { .driver = "virtio-9p-pci", .property = "vectors", @@ -861,7 +861,7 @@ static QEMUMachine pc_machine_v0_13 = { }; #define PC_COMPAT_0_12 \ - PC_COMPAT_0_13,\ + PC_COMPAT_0_13 \ {\ .driver = "virtio-serial-pci",\ .property = "max_ports",\ @@ -882,13 +882,13 @@ static QEMUMachine pc_machine_v0_13 = { .driver = "usb-kbd",\ .property = "serial",\ .value = "1",\ - } + }, static QEMUMachine pc_machine_v0_12 = { PC_I440FX_0_13_MACHINE_OPTIONS, .name = "pc-0.12", .compat_props = (GlobalProperty[]) { - PC_COMPAT_0_12, + PC_COMPAT_0_12 { .driver = "VGA", .property = "rombar", @@ -904,7 +904,7 @@ static QEMUMachine pc_machine_v0_12 = { }; #define PC_COMPAT_0_11 \ - PC_COMPAT_0_12,\ + PC_COMPAT_0_12 \ {\ .driver = "virtio-blk-pci",\ .property = "vectors",\ @@ -913,13 +913,13 @@ static QEMUMachine pc_machine_v0_12 = { .driver = TYPE_PCI_DEVICE,\ .property = "rombar",\ .value = stringify(0),\ - } + }, static QEMUMachine pc_machine_v0_11 = { PC_I440FX_0_13_MACHINE_OPTIONS, .name = "pc-0.11", .compat_props = (GlobalProperty[]) { - PC_COMPAT_0_11, + PC_COMPAT_0_11 { .driver = "ide-drive", .property = "ver", @@ -938,7 +938,7 @@ static QEMUMachine pc_machine_v0_10 = { PC_I440FX_0_13_MACHINE_OPTIONS, .name = "pc-0.10", .compat_props = (GlobalProperty[]) { - PC_COMPAT_0_11, + PC_COMPAT_0_11 { .driver = "virtio-blk-pci", .property = "class", diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 36b8834925..d0d70e8b90 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -470,7 +470,7 @@ static QEMUMachine pc_q35_machine_v2_0 = { .name = "pc-q35-2.0", .init = pc_q35_init_2_0, .compat_props = (GlobalProperty[]) { - PC_COMPAT_2_0, + PC_COMPAT_2_0 { /* end of list */ } }, }; @@ -482,7 +482,7 @@ static QEMUMachine pc_q35_machine_v1_7 = { .name = "pc-q35-1.7", .init = pc_q35_init_1_7, .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_7, + PC_COMPAT_1_7 { /* end of list */ } }, }; @@ -494,7 +494,7 @@ static QEMUMachine pc_q35_machine_v1_6 = { .name = "pc-q35-1.6", .init = pc_q35_init_1_6, .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_6, + PC_COMPAT_1_6 { /* end of list */ } }, }; @@ -504,7 +504,7 @@ static QEMUMachine pc_q35_machine_v1_5 = { .name = "pc-q35-1.5", .init = pc_q35_init_1_5, .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_5, + PC_COMPAT_1_5 { /* end of list */ } }, }; @@ -518,7 +518,7 @@ static QEMUMachine pc_q35_machine_v1_4 = { .name = "pc-q35-1.4", .init = pc_q35_init_1_4, .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_4, + PC_COMPAT_1_4 { /* end of list */ } }, }; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 7673a4dfce..ab862e3c6f 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -353,10 +353,10 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .driver = "ioh3420",\ .property = COMPAT_PROP_PCP,\ .value = "off",\ - } + }, #define PC_COMPAT_1_7 \ - PC_COMPAT_2_0, \ + PC_COMPAT_2_0 \ {\ .driver = TYPE_USB_DEVICE,\ .property = "msos-desc",\ @@ -371,10 +371,10 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .driver = "hpet",\ .property = HPET_INTCAP,\ .value = stringify(4),\ - } + }, #define PC_COMPAT_1_6 \ - PC_COMPAT_1_7, \ + PC_COMPAT_1_7 \ {\ .driver = "e1000",\ .property = "mitigation",\ @@ -395,10 +395,10 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .driver = "q35-pcihost",\ .property = "short_root_bus",\ .value = stringify(1),\ - } + }, #define PC_COMPAT_1_5 \ - PC_COMPAT_1_6, \ + PC_COMPAT_1_6 \ {\ .driver = "Conroe-" TYPE_X86_CPU,\ .property = "model",\ @@ -439,10 +439,10 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .driver = "q35-pcihost",\ .property = "short_root_bus",\ .value = stringify(0),\ - } + }, #define PC_COMPAT_1_4 \ - PC_COMPAT_1_5, \ + PC_COMPAT_1_5 \ {\ .driver = "scsi-hd",\ .property = "discard_granularity",\ @@ -504,7 +504,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .driver = "486-" TYPE_X86_CPU,\ .property = "model",\ .value = stringify(0),\ - } + }, #define PC_COMMON_MACHINE_OPTIONS \ .default_boot_order = "cad" -- cgit v1.2.3 From dd754baf46b6479a02521f671a0b58ffc799810e Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 14 May 2015 15:53:01 -0300 Subject: spapr: Move commas inside SPAPR_COMPAT_* macros Changing the convention to include commas inside the macros will allow macros containing empty lists to be defined and used without compilation errors. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/ppc/spapr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index f768de11fc..ee0ec61e33 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1820,7 +1820,7 @@ static const TypeInfo spapr_machine_info = { .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,\ .property = "mem_win_size",\ .value = "0x20000000",\ - } + }, #define SPAPR_COMPAT_2_1 \ SPAPR_COMPAT_2_2 @@ -1862,7 +1862,7 @@ static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data) MachineClass *mc = MACHINE_CLASS(oc); static GlobalProperty compat_props[] = { HW_COMPAT_2_1 - SPAPR_COMPAT_2_1, + SPAPR_COMPAT_2_1 { /* end of list */ } }; @@ -1881,7 +1881,7 @@ static const TypeInfo spapr_machine_2_1_info = { static void spapr_machine_2_2_class_init(ObjectClass *oc, void *data) { static GlobalProperty compat_props[] = { - SPAPR_COMPAT_2_2, + SPAPR_COMPAT_2_2 { /* end of list */ } }; MachineClass *mc = MACHINE_CLASS(oc); -- cgit v1.2.3 From 1edbde82b809f80b973978886d8232fbf280cb03 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 14 May 2015 15:53:02 -0300 Subject: hw: Define empty HW_COMPAT_2_[23] macros Now we can make everything consistent and define the macros even if they are still empty. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/compat.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/hw/compat.h b/include/hw/compat.h index c56a6989be..4a43466f03 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -1,6 +1,12 @@ #ifndef HW_COMPAT_H #define HW_COMPAT_H +#define HW_COMPAT_2_3 \ + /* empty */ + +#define HW_COMPAT_2_2 \ + /* empty */ + #define HW_COMPAT_2_1 \ {\ .driver = "intel-hda",\ -- cgit v1.2.3 From 42134ac9d74799cf2f70257798b72a2988b75d31 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 14 May 2015 15:53:03 -0300 Subject: pc: Define PC_COMPAT_2_[123] macros Once we start adding compat code for pc-2.3, the usage of HW_COMPAT_2_1 in pc-*-2.2 won't be enough, as it also has to include PC_COMPAT_2_3 inside it. To ensure that, define PC_COMPAT_2_3, PC_COMPAT_2_2, and PC_COMPAT_2_1 macros. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 10 +++++++++- hw/i386/pc_q35.c | 10 +++++++++- include/hw/i386/pc.h | 13 ++++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 25da8a5025..8796e60b8e 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -543,6 +543,10 @@ static QEMUMachine pc_i440fx_machine_v2_3 = { PC_I440FX_2_3_MACHINE_OPTIONS, .name = "pc-i440fx-2.3", .init = pc_init_pci_2_3, + .compat_props = (GlobalProperty[]) { + PC_COMPAT_2_3 + { /* end of list */ } + }, }; #define PC_I440FX_2_2_MACHINE_OPTIONS PC_I440FX_2_3_MACHINE_OPTIONS @@ -551,6 +555,10 @@ static QEMUMachine pc_i440fx_machine_v2_2 = { PC_I440FX_2_2_MACHINE_OPTIONS, .name = "pc-i440fx-2.2", .init = pc_init_pci_2_2, + .compat_props = (GlobalProperty[]) { + PC_COMPAT_2_2 + { /* end of list */ } + }, }; #define PC_I440FX_2_1_MACHINE_OPTIONS \ @@ -562,7 +570,7 @@ static QEMUMachine pc_i440fx_machine_v2_1 = { .name = "pc-i440fx-2.1", .init = pc_init_pci_2_1, .compat_props = (GlobalProperty[]) { - HW_COMPAT_2_1 + PC_COMPAT_2_1 { /* end of list */ } }, }; diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index d0d70e8b90..0051666ce2 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -439,6 +439,10 @@ static QEMUMachine pc_q35_machine_v2_3 = { PC_Q35_2_3_MACHINE_OPTIONS, .name = "pc-q35-2.3", .init = pc_q35_init_2_3, + .compat_props = (GlobalProperty[]) { + PC_COMPAT_2_3 + { /* end of list */ } + }, }; #define PC_Q35_2_2_MACHINE_OPTIONS PC_Q35_2_3_MACHINE_OPTIONS @@ -447,6 +451,10 @@ static QEMUMachine pc_q35_machine_v2_2 = { PC_Q35_2_2_MACHINE_OPTIONS, .name = "pc-q35-2.2", .init = pc_q35_init_2_2, + .compat_props = (GlobalProperty[]) { + PC_COMPAT_2_2 + { /* end of list */ } + }, }; #define PC_Q35_2_1_MACHINE_OPTIONS \ @@ -458,7 +466,7 @@ static QEMUMachine pc_q35_machine_v2_1 = { .name = "pc-q35-2.1", .init = pc_q35_init_2_1, .compat_props = (GlobalProperty[]) { - HW_COMPAT_2_1 + PC_COMPAT_2_1 { /* end of list */ } }, }; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index ab862e3c6f..672f1f7b41 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -295,8 +295,19 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); int e820_get_num_entries(void); bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); +#define PC_COMPAT_2_3 \ + HW_COMPAT_2_3 + +#define PC_COMPAT_2_2 \ + PC_COMPAT_2_3 \ + HW_COMPAT_2_2 + +#define PC_COMPAT_2_1 \ + PC_COMPAT_2_2 \ + HW_COMPAT_2_1 + #define PC_COMPAT_2_0 \ - HW_COMPAT_2_1 \ + PC_COMPAT_2_1 \ {\ .driver = "virtio-scsi-pci",\ .property = "any_layout",\ -- cgit v1.2.3 From 4dfd8eaa19c90087f19b56da5d04d9c468109a65 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 14 May 2015 15:53:04 -0300 Subject: spapr: Use HW_COMPAT_* inside SPAPR_COMPAT_* macros SPAPR_COMPAT_2_1 will need to include both HW_COMPAT_2_2 and HW_COMPAT_2_1, so include HW_COMPAT_2_1 inside SPAPR_COMPAT_2_1 and HW_COMPAT_2_2 inside SPAPR_COMPAT_2_2. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/ppc/spapr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index ee0ec61e33..de1b74052d 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1816,6 +1816,7 @@ static const TypeInfo spapr_machine_info = { }; #define SPAPR_COMPAT_2_2 \ + HW_COMPAT_2_2 \ {\ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,\ .property = "mem_win_size",\ @@ -1823,7 +1824,8 @@ static const TypeInfo spapr_machine_info = { }, #define SPAPR_COMPAT_2_1 \ - SPAPR_COMPAT_2_2 + SPAPR_COMPAT_2_2 \ + HW_COMPAT_2_1 static void spapr_compat_2_3(Object *obj) { @@ -1861,7 +1863,6 @@ static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); static GlobalProperty compat_props[] = { - HW_COMPAT_2_1 SPAPR_COMPAT_2_1 { /* end of list */ } }; -- cgit v1.2.3 From 38ff32c6e6fd966c5adb9cde4d393a8cca9ef093 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 14 May 2015 15:53:05 -0300 Subject: spapr: define SPAPR_COMPAT_2_3 Don't add the pseries-2.3 machine yet, but define the corresponding SPAPR_COMPAT macro to make sure both pseries-2.2 and pseries-2.1 will inherit HW_COMPAT_2_3. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/ppc/spapr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index de1b74052d..a15fa3c965 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1815,7 +1815,11 @@ static const TypeInfo spapr_machine_info = { }, }; +#define SPAPR_COMPAT_2_3 \ + HW_COMPAT_2_3 + #define SPAPR_COMPAT_2_2 \ + SPAPR_COMPAT_2_3 \ HW_COMPAT_2_2 \ {\ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,\ -- cgit v1.2.3 From bb08d8829b5bec6af619e4532a397ef12727516c Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 14 May 2015 15:53:06 -0300 Subject: piix: Move pc-0.14 qxl compat properties to PC_COMPAT_0_14 Those properties were introduced by commit 3827cdb1c3aa17a792d1658161195b9d7173c26b. They were not duplicated into pc-0.13 and older because 0.14 was the first QEMU version supporting qxl. The only problem is that this breaks the PC_COMPAT_* nesting pattern we currently use. So, move the properties to PC_COMPAT_0_14. This makes pc-0.13 and older inherit them, but that shouldn't be an issue as QEMU 0.13 didn't support qxl. Cc: Gerd Hoffmann Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 8796e60b8e..1e12eff59e 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -808,6 +808,14 @@ static QEMUMachine pc_machine_v0_15 = { .driver = "virtio-balloon-pci",\ .property = "event_idx",\ .value = "off",\ + },{\ + .driver = "qxl",\ + .property = "revision",\ + .value = stringify(2),\ + },{\ + .driver = "qxl-vga",\ + .property = "revision",\ + .value = stringify(2),\ }, static QEMUMachine pc_machine_v0_14 = { @@ -815,15 +823,6 @@ static QEMUMachine pc_machine_v0_14 = { .name = "pc-0.14", .compat_props = (GlobalProperty[]) { PC_COMPAT_0_14 - { - .driver = "qxl", - .property = "revision", - .value = stringify(2), - },{ - .driver = "qxl-vga", - .property = "revision", - .value = stringify(2), - }, { /* end of list */ } }, .hw_version = "0.14", -- cgit v1.2.3 From d5303df71073da70e0ad29a6dfb304ec7b747f5c Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 14 May 2015 15:53:07 -0300 Subject: piix: Move pc-0.11 drive version compat props to PC_COMPAT_0_11 The current code setting ide-drive.ver and scsi-disk.ver on pc-0.11 breaks the PC_COMPAT_* nesting pattern we currently use. As those variables are overwritten in pc-0.10 too, they can be inherited by pc-0.10 with no side-effects at all. Cc: Gerd Hoffmann Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 1e12eff59e..eb0c11f201 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -920,6 +920,14 @@ static QEMUMachine pc_machine_v0_12 = { .driver = TYPE_PCI_DEVICE,\ .property = "rombar",\ .value = stringify(0),\ + },{\ + .driver = "ide-drive",\ + .property = "ver",\ + .value = "0.11",\ + },{\ + .driver = "scsi-disk",\ + .property = "ver",\ + .value = "0.11",\ }, static QEMUMachine pc_machine_v0_11 = { @@ -927,15 +935,6 @@ static QEMUMachine pc_machine_v0_11 = { .name = "pc-0.11", .compat_props = (GlobalProperty[]) { PC_COMPAT_0_11 - { - .driver = "ide-drive", - .property = "ver", - .value = "0.11", - },{ - .driver = "scsi-disk", - .property = "ver", - .value = "0.11", - }, { /* end of list */ } }, .hw_version = "0.11", -- cgit v1.2.3 From d765519bef48bd95f2139314a5354144387523eb Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 14 May 2015 15:53:08 -0300 Subject: piix: Move pc-0.13 virtio-9p-pci compat to PC_COMPAT_0_13 The compat property was added by commit 9dbcca5aa13cb9ab40788ac4c56bc227d94ca920, and the pc-0.12 and older machine-types were not changed because virtio-9p-pci was introduced on QEMU 0.13 (commit 9f10751365b26b13b8a9b67e0e90536ae3d282df). The only problem is that this breaks the PC_COMPAT_* nesting pattern we currently use. So, move the property to PC_COMPAT_0_13. This make pc-0.12 and older inherit it, but that shouldn't be an issue as QEMU 0.12 didn't have virtio-9p-pci. Cc: Gerd Hoffmann Cc: Aneesh Kumar K.V Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index eb0c11f201..9d12c9364a 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -838,6 +838,10 @@ static QEMUMachine pc_machine_v0_14 = { .driver = "AC97",\ .property = "use_broken_id",\ .value = stringify(1),\ + },{\ + .driver = "virtio-9p-pci",\ + .property = "vectors",\ + .value = stringify(0),\ }, #define PC_I440FX_0_13_MACHINE_OPTIONS \ @@ -850,10 +854,6 @@ static QEMUMachine pc_machine_v0_13 = { .compat_props = (GlobalProperty[]) { PC_COMPAT_0_13 { - .driver = "virtio-9p-pci", - .property = "vectors", - .value = stringify(0), - },{ .driver = "VGA", .property = "rombar", .value = stringify(0), -- cgit v1.2.3 From faf7e4254fa33a13805a34a1ffeeb9dcc0a36a5e Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 14 May 2015 15:53:09 -0300 Subject: piix: Move pc-0.1[23] rombar compat props to PC_COMPAT_0_13 The VGA and vmware-svga rombar compat properties were added by commit 281a26b15b4adcecb8604216738975abd754bea8, but only to pc-0.13 and pc-0.12. This breaks the PC_COMPAT_* nesting pattern we currently follow. The new variables will now be inherited by pc-0.11 and older, but pc-0.11 and pc-0.10 already have PCI.rombar=0 on compat_props, so they shouldn't be affected at all. Cc: Stefan Weil Cc: Gerd Hoffmann Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 9d12c9364a..ac98af12d7 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -842,6 +842,14 @@ static QEMUMachine pc_machine_v0_14 = { .driver = "virtio-9p-pci",\ .property = "vectors",\ .value = stringify(0),\ + },{\ + .driver = "VGA",\ + .property = "rombar",\ + .value = stringify(0),\ + },{\ + .driver = "vmware-svga",\ + .property = "rombar",\ + .value = stringify(0),\ }, #define PC_I440FX_0_13_MACHINE_OPTIONS \ @@ -853,15 +861,6 @@ static QEMUMachine pc_machine_v0_13 = { .name = "pc-0.13", .compat_props = (GlobalProperty[]) { PC_COMPAT_0_13 - { - .driver = "VGA", - .property = "rombar", - .value = stringify(0), - },{ - .driver = "vmware-svga", - .property = "rombar", - .value = stringify(0), - }, { /* end of list */ } }, .hw_version = "0.13", @@ -896,15 +895,6 @@ static QEMUMachine pc_machine_v0_12 = { .name = "pc-0.12", .compat_props = (GlobalProperty[]) { PC_COMPAT_0_12 - { - .driver = "VGA", - .property = "rombar", - .value = stringify(0), - },{ - .driver = "vmware-svga", - .property = "rombar", - .value = stringify(0), - }, { /* end of list */ } }, .hw_version = "0.12", -- cgit v1.2.3 From f6d5a0bad276ea97fac4e0efb0f41f54a3f1ac84 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 14 May 2015 15:53:10 -0300 Subject: piix: Define PC_COMPAT_0_10 Move compat_props from pc-0.10 to the macro, to make it consistent with the other machines. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index ac98af12d7..6734c62df7 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -930,32 +930,35 @@ static QEMUMachine pc_machine_v0_11 = { .hw_version = "0.11", }; +#define PC_COMPAT_0_10 \ + PC_COMPAT_0_11 \ + {\ + .driver = "virtio-blk-pci",\ + .property = "class",\ + .value = stringify(PCI_CLASS_STORAGE_OTHER),\ + },{\ + .driver = "virtio-serial-pci",\ + .property = "class",\ + .value = stringify(PCI_CLASS_DISPLAY_OTHER),\ + },{\ + .driver = "virtio-net-pci",\ + .property = "vectors",\ + .value = stringify(0),\ + },{\ + .driver = "ide-drive",\ + .property = "ver",\ + .value = "0.10",\ + },{\ + .driver = "scsi-disk",\ + .property = "ver",\ + .value = "0.10",\ + }, + static QEMUMachine pc_machine_v0_10 = { PC_I440FX_0_13_MACHINE_OPTIONS, .name = "pc-0.10", .compat_props = (GlobalProperty[]) { - PC_COMPAT_0_11 - { - .driver = "virtio-blk-pci", - .property = "class", - .value = stringify(PCI_CLASS_STORAGE_OTHER), - },{ - .driver = "virtio-serial-pci", - .property = "class", - .value = stringify(PCI_CLASS_DISPLAY_OTHER), - },{ - .driver = "virtio-net-pci", - .property = "vectors", - .value = stringify(0), - },{ - .driver = "ide-drive", - .property = "ver", - .value = "0.10", - },{ - .driver = "scsi-disk", - .property = "ver", - .value = "0.10", - }, + PC_COMPAT_0_10 { /* end of list */ } }, .hw_version = "0.10", -- cgit v1.2.3 From b6b5c8e492ae7b71a16fe702b7409bff0feebfa7 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 15 May 2015 14:18:52 -0300 Subject: pc: Define MACHINE_OPTIONS macros consistently for all machines Define a MACHINE_OPTIONS macro for each PC machine, and move every field inside the QEMUMachine structs to the macros, except for name, init, and compat_props. This also ensures that all MACHINE_OPTIONS inherit the fields from the next version, so their definitions carry only the changes that exist between one version and the next one. Comments about specific cases: pc-*-2.1: Existing PC_*_2_1_MACHINE_OPTIONS macros were defined as: PC_*_MACHINE_OPTIONS, .default_machine_opts = "firmware=bios-256k.bin" PC_*_2_2_MACHINE_OPTIONS is: PC_*_2_3_MACHINE_OPTIONS which is expanded to: PC_*_MACHINE_OPTIONS, .default_machine_opts = "firmware=bios-256k.bin", .default_display = "std" The only difference between 2_1 and 2_2 is .default_display, that's why we didn't reuse PC_*_2_2_MACHINE_OPTIONS. The good news is that having multiple initializers for a field is allowed by C99, and the last initializer overrides the previous ones. So we can reuse the 2_2 macro in 2_1 and define PC_*_2_1_MACHINE_OPTIONS as: PC_*_2_2_MACHINE_OPTIONS, .default_display = NULL pc-*-1.7: PC_*_1_7_MACHINE_OPTIONS was defined as: PC_*_MACHINE_OPTIONS PC_*_2_0_MACHINE_OPTIONS is defined as: PC_*_2_1_MACHINE_OPTIONS which is expanded to: PC_*_2_2_MACHINE_OPTIONS, .default_display = NULL which is expanded to: PC_*_2_3_MACHINE_OPTIONS, .default_display = NULL which is expanded to: PC_*_MACHINE_OPTIONS, .default_machine_opts = "firmware=bios-256k.bin", .default_display = "std", .default_display = NULL /* overrides the previous line */ So, the only difference between PC_*_1_7_MACHINE_OPTIONS and PC_*_2_0_MACHINE_OPTIONS is .default_machine_opts (as .default_display is not explicitly set by PC_*_MACHINE_OPTIONS so it is NULL). So we can keep the macro reuse pattern and define PC_*_2_0_MACHINE_OPTIONS as: PC_*_2_0_MACHINE_OPTIONS, .default_machine_opts = NULL pc-*-2.4 (alias and is_default fields): Set alias and is_default fields inside the 2.4 MACHINE_OPTIONS macro, and clear it in the 2.3 macro (that reuses the 2.4 macro). hw_machine: As all the machines older than v1.0 set hw_version explicitly, we can safely move the field to the MACHINE_OPTIONS macros without affecting the other versions that reuse them. init function: Some machines had the init function set inside the MACHINE_OPTIONS macro. Move it to the QEMUMachine declaration, to keep it consistent with the other machines. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 128 +++++++++++++++++++++++++++++++++++++----------------- hw/i386/pc_q35.c | 34 ++++++++++----- 2 files changed, 110 insertions(+), 52 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 6734c62df7..0bbe97907c 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -526,18 +526,21 @@ static void pc_xen_hvm_init(MachineState *machine) #define PC_I440FX_2_4_MACHINE_OPTIONS \ PC_I440FX_MACHINE_OPTIONS, \ .default_machine_opts = "firmware=bios-256k.bin", \ - .default_display = "std" + .default_display = "std", \ + .alias = "pc", \ + .is_default = 1 static QEMUMachine pc_i440fx_machine_v2_4 = { PC_I440FX_2_4_MACHINE_OPTIONS, .name = "pc-i440fx-2.4", - .alias = "pc", .init = pc_init_pci, - .is_default = 1, }; -#define PC_I440FX_2_3_MACHINE_OPTIONS PC_I440FX_2_4_MACHINE_OPTIONS +#define PC_I440FX_2_3_MACHINE_OPTIONS \ + PC_I440FX_2_4_MACHINE_OPTIONS, \ + .alias = NULL, \ + .is_default = 0 static QEMUMachine pc_i440fx_machine_v2_3 = { PC_I440FX_2_3_MACHINE_OPTIONS, @@ -549,7 +552,8 @@ static QEMUMachine pc_i440fx_machine_v2_3 = { }, }; -#define PC_I440FX_2_2_MACHINE_OPTIONS PC_I440FX_2_3_MACHINE_OPTIONS +#define PC_I440FX_2_2_MACHINE_OPTIONS \ + PC_I440FX_2_3_MACHINE_OPTIONS static QEMUMachine pc_i440fx_machine_v2_2 = { PC_I440FX_2_2_MACHINE_OPTIONS, @@ -561,9 +565,9 @@ static QEMUMachine pc_i440fx_machine_v2_2 = { }, }; -#define PC_I440FX_2_1_MACHINE_OPTIONS \ - PC_I440FX_MACHINE_OPTIONS, \ - .default_machine_opts = "firmware=bios-256k.bin" +#define PC_I440FX_2_1_MACHINE_OPTIONS \ + PC_I440FX_2_2_MACHINE_OPTIONS, \ + .default_display = NULL static QEMUMachine pc_i440fx_machine_v2_1 = { PC_I440FX_2_1_MACHINE_OPTIONS, @@ -575,7 +579,8 @@ static QEMUMachine pc_i440fx_machine_v2_1 = { }, }; -#define PC_I440FX_2_0_MACHINE_OPTIONS PC_I440FX_2_1_MACHINE_OPTIONS +#define PC_I440FX_2_0_MACHINE_OPTIONS \ + PC_I440FX_2_1_MACHINE_OPTIONS static QEMUMachine pc_i440fx_machine_v2_0 = { PC_I440FX_2_0_MACHINE_OPTIONS, @@ -587,7 +592,9 @@ static QEMUMachine pc_i440fx_machine_v2_0 = { }, }; -#define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS +#define PC_I440FX_1_7_MACHINE_OPTIONS \ + PC_I440FX_2_0_MACHINE_OPTIONS, \ + .default_machine_opts = NULL static QEMUMachine pc_i440fx_machine_v1_7 = { PC_I440FX_1_7_MACHINE_OPTIONS, @@ -599,7 +606,8 @@ static QEMUMachine pc_i440fx_machine_v1_7 = { }, }; -#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS +#define PC_I440FX_1_6_MACHINE_OPTIONS \ + PC_I440FX_1_7_MACHINE_OPTIONS static QEMUMachine pc_i440fx_machine_v1_6 = { PC_I440FX_1_6_MACHINE_OPTIONS, @@ -611,8 +619,11 @@ static QEMUMachine pc_i440fx_machine_v1_6 = { }, }; +#define PC_I440FX_1_5_MACHINE_OPTIONS \ + PC_I440FX_1_6_MACHINE_OPTIONS + static QEMUMachine pc_i440fx_machine_v1_5 = { - PC_I440FX_1_6_MACHINE_OPTIONS, + PC_I440FX_1_5_MACHINE_OPTIONS, .name = "pc-i440fx-1.5", .init = pc_init_pci_1_5, .compat_props = (GlobalProperty[]) { @@ -622,7 +633,7 @@ static QEMUMachine pc_i440fx_machine_v1_5 = { }; #define PC_I440FX_1_4_MACHINE_OPTIONS \ - PC_I440FX_1_6_MACHINE_OPTIONS, \ + PC_I440FX_1_5_MACHINE_OPTIONS, \ .hot_add_cpu = NULL static QEMUMachine pc_i440fx_machine_v1_4 = { @@ -655,8 +666,11 @@ static QEMUMachine pc_i440fx_machine_v1_4 = { .value = "off",\ }, +#define PC_I440FX_1_3_MACHINE_OPTIONS \ + PC_I440FX_1_4_MACHINE_OPTIONS + static QEMUMachine pc_machine_v1_3 = { - PC_I440FX_1_4_MACHINE_OPTIONS, + PC_I440FX_1_3_MACHINE_OPTIONS, .name = "pc-1.3", .init = pc_init_pci_1_3, .compat_props = (GlobalProperty[]) { @@ -694,12 +708,12 @@ static QEMUMachine pc_machine_v1_3 = { }, #define PC_I440FX_1_2_MACHINE_OPTIONS \ - PC_I440FX_1_4_MACHINE_OPTIONS, \ - .init = pc_init_pci_1_2 + PC_I440FX_1_3_MACHINE_OPTIONS static QEMUMachine pc_machine_v1_2 = { PC_I440FX_1_2_MACHINE_OPTIONS, .name = "pc-1.2", + .init = pc_init_pci_1_2, .compat_props = (GlobalProperty[]) { PC_COMPAT_1_2 { /* end of list */ } @@ -738,9 +752,13 @@ static QEMUMachine pc_machine_v1_2 = { .value = "off",\ }, +#define PC_I440FX_1_1_MACHINE_OPTIONS \ + PC_I440FX_1_2_MACHINE_OPTIONS + static QEMUMachine pc_machine_v1_1 = { - PC_I440FX_1_2_MACHINE_OPTIONS, + PC_I440FX_1_1_MACHINE_OPTIONS, .name = "pc-1.1", + .init = pc_init_pci_1_2, .compat_props = (GlobalProperty[]) { PC_COMPAT_1_1 { /* end of list */ } @@ -767,27 +785,35 @@ static QEMUMachine pc_machine_v1_1 = { .value = "no",\ }, +#define PC_I440FX_1_0_MACHINE_OPTIONS \ + PC_I440FX_1_1_MACHINE_OPTIONS, \ + .hw_version = "1.0" + static QEMUMachine pc_machine_v1_0 = { - PC_I440FX_1_2_MACHINE_OPTIONS, + PC_I440FX_1_0_MACHINE_OPTIONS, .name = "pc-1.0", + .init = pc_init_pci_1_2, .compat_props = (GlobalProperty[]) { PC_COMPAT_1_0 { /* end of list */ } }, - .hw_version = "1.0", }; #define PC_COMPAT_0_15 \ PC_COMPAT_1_0 +#define PC_I440FX_0_15_MACHINE_OPTIONS \ + PC_I440FX_1_0_MACHINE_OPTIONS, \ + .hw_version = "0.15" + static QEMUMachine pc_machine_v0_15 = { - PC_I440FX_1_2_MACHINE_OPTIONS, + PC_I440FX_0_15_MACHINE_OPTIONS, .name = "pc-0.15", + .init = pc_init_pci_1_2, .compat_props = (GlobalProperty[]) { PC_COMPAT_0_15 { /* end of list */ } }, - .hw_version = "0.15", }; #define PC_COMPAT_0_14 \ @@ -818,14 +844,18 @@ static QEMUMachine pc_machine_v0_15 = { .value = stringify(2),\ }, +#define PC_I440FX_0_14_MACHINE_OPTIONS \ + PC_I440FX_0_15_MACHINE_OPTIONS, \ + .hw_version = "0.14" + static QEMUMachine pc_machine_v0_14 = { - PC_I440FX_1_2_MACHINE_OPTIONS, + PC_I440FX_0_14_MACHINE_OPTIONS, .name = "pc-0.14", + .init = pc_init_pci_1_2, .compat_props = (GlobalProperty[]) { PC_COMPAT_0_14 { /* end of list */ } }, - .hw_version = "0.14", }; #define PC_COMPAT_0_13 \ @@ -853,17 +883,17 @@ static QEMUMachine pc_machine_v0_14 = { }, #define PC_I440FX_0_13_MACHINE_OPTIONS \ - PC_I440FX_1_2_MACHINE_OPTIONS, \ - .init = pc_init_pci_no_kvmclock + PC_I440FX_0_14_MACHINE_OPTIONS, \ + .hw_version = "0.13" static QEMUMachine pc_machine_v0_13 = { PC_I440FX_0_13_MACHINE_OPTIONS, .name = "pc-0.13", + .init = pc_init_pci_no_kvmclock, .compat_props = (GlobalProperty[]) { PC_COMPAT_0_13 { /* end of list */ } }, - .hw_version = "0.13", }; #define PC_COMPAT_0_12 \ @@ -890,14 +920,18 @@ static QEMUMachine pc_machine_v0_13 = { .value = "1",\ }, +#define PC_I440FX_0_12_MACHINE_OPTIONS \ + PC_I440FX_0_13_MACHINE_OPTIONS, \ + .hw_version = "0.12" + static QEMUMachine pc_machine_v0_12 = { - PC_I440FX_0_13_MACHINE_OPTIONS, + PC_I440FX_0_12_MACHINE_OPTIONS, .name = "pc-0.12", + .init = pc_init_pci_no_kvmclock, .compat_props = (GlobalProperty[]) { PC_COMPAT_0_12 { /* end of list */ } }, - .hw_version = "0.12", }; #define PC_COMPAT_0_11 \ @@ -920,14 +954,18 @@ static QEMUMachine pc_machine_v0_12 = { .value = "0.11",\ }, +#define PC_I440FX_0_11_MACHINE_OPTIONS \ + PC_I440FX_0_12_MACHINE_OPTIONS, \ + .hw_version = "0.11" + static QEMUMachine pc_machine_v0_11 = { - PC_I440FX_0_13_MACHINE_OPTIONS, + PC_I440FX_0_11_MACHINE_OPTIONS, .name = "pc-0.11", + .init = pc_init_pci_no_kvmclock, .compat_props = (GlobalProperty[]) { PC_COMPAT_0_11 { /* end of list */ } }, - .hw_version = "0.11", }; #define PC_COMPAT_0_10 \ @@ -954,36 +992,46 @@ static QEMUMachine pc_machine_v0_11 = { .value = "0.10",\ }, +#define PC_I440FX_0_10_MACHINE_OPTIONS \ + PC_I440FX_0_11_MACHINE_OPTIONS, \ + .hw_version = "0.10" + static QEMUMachine pc_machine_v0_10 = { - PC_I440FX_0_13_MACHINE_OPTIONS, + PC_I440FX_0_10_MACHINE_OPTIONS, .name = "pc-0.10", + .init = pc_init_pci_no_kvmclock, .compat_props = (GlobalProperty[]) { PC_COMPAT_0_10 { /* end of list */ } }, - .hw_version = "0.10", }; +#define ISAPC_MACHINE_OPTIONS \ + PC_COMMON_MACHINE_OPTIONS, \ + .desc = "ISA-only PC", \ + .max_cpus = 1 + static QEMUMachine isapc_machine = { - PC_COMMON_MACHINE_OPTIONS, + ISAPC_MACHINE_OPTIONS, .name = "isapc", - .desc = "ISA-only PC", .init = pc_init_isa, - .max_cpus = 1, .compat_props = (GlobalProperty[]) { { /* end of list */ } }, }; #ifdef CONFIG_XEN +#define XENFV_MACHINE_OPTIONS \ + PC_COMMON_MACHINE_OPTIONS, \ + .desc = "Xen Fully-virtualized PC", \ + .max_cpus = HVM_MAX_VCPUS, \ + .default_machine_opts = "accel=xen", \ + .hot_add_cpu = pc_hot_add_cpu + static QEMUMachine xenfv_machine = { - PC_COMMON_MACHINE_OPTIONS, + XENFV_MACHINE_OPTIONS, .name = "xenfv", - .desc = "Xen Fully-virtualized PC", .init = pc_xen_hvm_init, - .max_cpus = HVM_MAX_VCPUS, - .default_machine_opts = "accel=xen", - .hot_add_cpu = pc_hot_add_cpu, }; #endif diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 0051666ce2..196178ec5f 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -424,16 +424,18 @@ static void pc_q35_init_1_4(MachineState *machine) #define PC_Q35_2_4_MACHINE_OPTIONS \ PC_Q35_MACHINE_OPTIONS, \ .default_machine_opts = "firmware=bios-256k.bin", \ - .default_display = "std" + .default_display = "std", \ + .alias = "q35" static QEMUMachine pc_q35_machine_v2_4 = { PC_Q35_2_4_MACHINE_OPTIONS, .name = "pc-q35-2.4", - .alias = "q35", .init = pc_q35_init, }; -#define PC_Q35_2_3_MACHINE_OPTIONS PC_Q35_2_4_MACHINE_OPTIONS +#define PC_Q35_2_3_MACHINE_OPTIONS \ + PC_Q35_2_4_MACHINE_OPTIONS, \ + .alias = NULL static QEMUMachine pc_q35_machine_v2_3 = { PC_Q35_2_3_MACHINE_OPTIONS, @@ -445,7 +447,8 @@ static QEMUMachine pc_q35_machine_v2_3 = { }, }; -#define PC_Q35_2_2_MACHINE_OPTIONS PC_Q35_2_3_MACHINE_OPTIONS +#define PC_Q35_2_2_MACHINE_OPTIONS \ + PC_Q35_2_3_MACHINE_OPTIONS static QEMUMachine pc_q35_machine_v2_2 = { PC_Q35_2_2_MACHINE_OPTIONS, @@ -457,9 +460,9 @@ static QEMUMachine pc_q35_machine_v2_2 = { }, }; -#define PC_Q35_2_1_MACHINE_OPTIONS \ - PC_Q35_MACHINE_OPTIONS, \ - .default_machine_opts = "firmware=bios-256k.bin" +#define PC_Q35_2_1_MACHINE_OPTIONS \ + PC_Q35_2_2_MACHINE_OPTIONS, \ + .default_display = NULL static QEMUMachine pc_q35_machine_v2_1 = { PC_Q35_2_1_MACHINE_OPTIONS, @@ -471,7 +474,8 @@ static QEMUMachine pc_q35_machine_v2_1 = { }, }; -#define PC_Q35_2_0_MACHINE_OPTIONS PC_Q35_2_1_MACHINE_OPTIONS +#define PC_Q35_2_0_MACHINE_OPTIONS \ + PC_Q35_2_1_MACHINE_OPTIONS static QEMUMachine pc_q35_machine_v2_0 = { PC_Q35_2_0_MACHINE_OPTIONS, @@ -483,7 +487,9 @@ static QEMUMachine pc_q35_machine_v2_0 = { }, }; -#define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS +#define PC_Q35_1_7_MACHINE_OPTIONS \ + PC_Q35_2_0_MACHINE_OPTIONS, \ + .default_machine_opts = NULL static QEMUMachine pc_q35_machine_v1_7 = { PC_Q35_1_7_MACHINE_OPTIONS, @@ -495,7 +501,8 @@ static QEMUMachine pc_q35_machine_v1_7 = { }, }; -#define PC_Q35_1_6_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS +#define PC_Q35_1_6_MACHINE_OPTIONS \ + PC_Q35_MACHINE_OPTIONS static QEMUMachine pc_q35_machine_v1_6 = { PC_Q35_1_6_MACHINE_OPTIONS, @@ -507,8 +514,11 @@ static QEMUMachine pc_q35_machine_v1_6 = { }, }; +#define PC_Q35_1_5_MACHINE_OPTIONS \ + PC_Q35_1_6_MACHINE_OPTIONS + static QEMUMachine pc_q35_machine_v1_5 = { - PC_Q35_1_6_MACHINE_OPTIONS, + PC_Q35_1_5_MACHINE_OPTIONS, .name = "pc-q35-1.5", .init = pc_q35_init_1_5, .compat_props = (GlobalProperty[]) { @@ -518,7 +528,7 @@ static QEMUMachine pc_q35_machine_v1_5 = { }; #define PC_Q35_1_4_MACHINE_OPTIONS \ - PC_Q35_1_6_MACHINE_OPTIONS, \ + PC_Q35_1_5_MACHINE_OPTIONS, \ .hot_add_cpu = NULL static QEMUMachine pc_q35_machine_v1_4 = { -- cgit v1.2.3 From 61f219dfb093c0df91926928c780299cdf429619 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 15 May 2015 14:18:53 -0300 Subject: pc: Define machines using a DEFINE_PC_MACHINE macro This will automatically generate the existing QEMUMachine structs based on the *_MACHINE_OPTIONS macros, and automatically add registration code for them. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 270 ++++++++++++--------------------------------------- hw/i386/pc_q35.c | 118 +++++----------------- include/hw/i386/pc.h | 16 +++ 3 files changed, 103 insertions(+), 301 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 0bbe97907c..3c5061fd60 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -530,121 +530,70 @@ static void pc_xen_hvm_init(MachineState *machine) .alias = "pc", \ .is_default = 1 +DEFINE_PC_MACHINE(v2_4, "pc-i440fx-2.4", pc_init_pci, + PC_I440FX_2_4_MACHINE_OPTIONS, /* no compat */) -static QEMUMachine pc_i440fx_machine_v2_4 = { - PC_I440FX_2_4_MACHINE_OPTIONS, - .name = "pc-i440fx-2.4", - .init = pc_init_pci, -}; #define PC_I440FX_2_3_MACHINE_OPTIONS \ PC_I440FX_2_4_MACHINE_OPTIONS, \ .alias = NULL, \ .is_default = 0 -static QEMUMachine pc_i440fx_machine_v2_3 = { - PC_I440FX_2_3_MACHINE_OPTIONS, - .name = "pc-i440fx-2.3", - .init = pc_init_pci_2_3, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_2_3 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v2_3, "pc-i440fx-2.3", pc_init_pci_2_3, + PC_I440FX_2_3_MACHINE_OPTIONS, PC_COMPAT_2_3); + #define PC_I440FX_2_2_MACHINE_OPTIONS \ PC_I440FX_2_3_MACHINE_OPTIONS -static QEMUMachine pc_i440fx_machine_v2_2 = { - PC_I440FX_2_2_MACHINE_OPTIONS, - .name = "pc-i440fx-2.2", - .init = pc_init_pci_2_2, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_2_2 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v2_2, "pc-i440fx-2.2", pc_init_pci_2_2, + PC_I440FX_2_2_MACHINE_OPTIONS, PC_COMPAT_2_2); + #define PC_I440FX_2_1_MACHINE_OPTIONS \ PC_I440FX_2_2_MACHINE_OPTIONS, \ .default_display = NULL -static QEMUMachine pc_i440fx_machine_v2_1 = { - PC_I440FX_2_1_MACHINE_OPTIONS, - .name = "pc-i440fx-2.1", - .init = pc_init_pci_2_1, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_2_1 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v2_1, "pc-i440fx-2.1", pc_init_pci_2_1, + PC_I440FX_2_1_MACHINE_OPTIONS, PC_COMPAT_2_1); + #define PC_I440FX_2_0_MACHINE_OPTIONS \ PC_I440FX_2_1_MACHINE_OPTIONS -static QEMUMachine pc_i440fx_machine_v2_0 = { - PC_I440FX_2_0_MACHINE_OPTIONS, - .name = "pc-i440fx-2.0", - .init = pc_init_pci_2_0, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_2_0 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v2_0, "pc-i440fx-2.0", pc_init_pci_2_0, + PC_I440FX_2_0_MACHINE_OPTIONS, PC_COMPAT_2_0); + #define PC_I440FX_1_7_MACHINE_OPTIONS \ PC_I440FX_2_0_MACHINE_OPTIONS, \ .default_machine_opts = NULL -static QEMUMachine pc_i440fx_machine_v1_7 = { - PC_I440FX_1_7_MACHINE_OPTIONS, - .name = "pc-i440fx-1.7", - .init = pc_init_pci_1_7, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_7 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v1_7, "pc-i440fx-1.7", pc_init_pci_1_7, + PC_I440FX_1_7_MACHINE_OPTIONS, PC_COMPAT_1_7); + #define PC_I440FX_1_6_MACHINE_OPTIONS \ PC_I440FX_1_7_MACHINE_OPTIONS -static QEMUMachine pc_i440fx_machine_v1_6 = { - PC_I440FX_1_6_MACHINE_OPTIONS, - .name = "pc-i440fx-1.6", - .init = pc_init_pci_1_6, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_6 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v1_6, "pc-i440fx-1.6", pc_init_pci_1_6, + PC_I440FX_1_6_MACHINE_OPTIONS, PC_COMPAT_1_6); + #define PC_I440FX_1_5_MACHINE_OPTIONS \ PC_I440FX_1_6_MACHINE_OPTIONS -static QEMUMachine pc_i440fx_machine_v1_5 = { - PC_I440FX_1_5_MACHINE_OPTIONS, - .name = "pc-i440fx-1.5", - .init = pc_init_pci_1_5, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_5 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v1_5, "pc-i440fx-1.5", pc_init_pci_1_5, + PC_I440FX_1_5_MACHINE_OPTIONS, PC_COMPAT_1_5); + #define PC_I440FX_1_4_MACHINE_OPTIONS \ PC_I440FX_1_5_MACHINE_OPTIONS, \ .hot_add_cpu = NULL -static QEMUMachine pc_i440fx_machine_v1_4 = { - PC_I440FX_1_4_MACHINE_OPTIONS, - .name = "pc-i440fx-1.4", - .init = pc_init_pci_1_4, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_4 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v1_4, "pc-i440fx-1.4", pc_init_pci_1_4, + PC_I440FX_1_4_MACHINE_OPTIONS, PC_COMPAT_1_4); + #define PC_COMPAT_1_3 \ PC_COMPAT_1_4 \ @@ -669,15 +618,9 @@ static QEMUMachine pc_i440fx_machine_v1_4 = { #define PC_I440FX_1_3_MACHINE_OPTIONS \ PC_I440FX_1_4_MACHINE_OPTIONS -static QEMUMachine pc_machine_v1_3 = { - PC_I440FX_1_3_MACHINE_OPTIONS, - .name = "pc-1.3", - .init = pc_init_pci_1_3, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_3 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v1_3, "pc-1.3", pc_init_pci_1_3, + PC_I440FX_1_3_MACHINE_OPTIONS, PC_COMPAT_1_3); + #define PC_COMPAT_1_2 \ PC_COMPAT_1_3 \ @@ -710,15 +653,9 @@ static QEMUMachine pc_machine_v1_3 = { #define PC_I440FX_1_2_MACHINE_OPTIONS \ PC_I440FX_1_3_MACHINE_OPTIONS -static QEMUMachine pc_machine_v1_2 = { - PC_I440FX_1_2_MACHINE_OPTIONS, - .name = "pc-1.2", - .init = pc_init_pci_1_2, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_2 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v1_2, "pc-1.2", pc_init_pci_1_2, + PC_I440FX_1_2_MACHINE_OPTIONS, PC_COMPAT_1_2); + #define PC_COMPAT_1_1 \ PC_COMPAT_1_2 \ @@ -755,15 +692,9 @@ static QEMUMachine pc_machine_v1_2 = { #define PC_I440FX_1_1_MACHINE_OPTIONS \ PC_I440FX_1_2_MACHINE_OPTIONS -static QEMUMachine pc_machine_v1_1 = { - PC_I440FX_1_1_MACHINE_OPTIONS, - .name = "pc-1.1", - .init = pc_init_pci_1_2, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_1 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v1_1, "pc-1.1", pc_init_pci_1_2, + PC_I440FX_1_1_MACHINE_OPTIONS, PC_COMPAT_1_1); + #define PC_COMPAT_1_0 \ PC_COMPAT_1_1 \ @@ -789,15 +720,9 @@ static QEMUMachine pc_machine_v1_1 = { PC_I440FX_1_1_MACHINE_OPTIONS, \ .hw_version = "1.0" -static QEMUMachine pc_machine_v1_0 = { - PC_I440FX_1_0_MACHINE_OPTIONS, - .name = "pc-1.0", - .init = pc_init_pci_1_2, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_0 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v1_0, "pc-1.0", pc_init_pci_1_2, + PC_I440FX_1_0_MACHINE_OPTIONS, PC_COMPAT_1_0); + #define PC_COMPAT_0_15 \ PC_COMPAT_1_0 @@ -806,15 +731,9 @@ static QEMUMachine pc_machine_v1_0 = { PC_I440FX_1_0_MACHINE_OPTIONS, \ .hw_version = "0.15" -static QEMUMachine pc_machine_v0_15 = { - PC_I440FX_0_15_MACHINE_OPTIONS, - .name = "pc-0.15", - .init = pc_init_pci_1_2, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_0_15 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v0_15, "pc-0.15", pc_init_pci_1_2, + PC_I440FX_0_15_MACHINE_OPTIONS, PC_COMPAT_0_15); + #define PC_COMPAT_0_14 \ PC_COMPAT_0_15 \ @@ -848,15 +767,9 @@ static QEMUMachine pc_machine_v0_15 = { PC_I440FX_0_15_MACHINE_OPTIONS, \ .hw_version = "0.14" -static QEMUMachine pc_machine_v0_14 = { - PC_I440FX_0_14_MACHINE_OPTIONS, - .name = "pc-0.14", - .init = pc_init_pci_1_2, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_0_14 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v0_14, "pc-0.14", pc_init_pci_1_2, + PC_I440FX_0_14_MACHINE_OPTIONS, PC_COMPAT_0_14); + #define PC_COMPAT_0_13 \ PC_COMPAT_0_14 \ @@ -886,15 +799,9 @@ static QEMUMachine pc_machine_v0_14 = { PC_I440FX_0_14_MACHINE_OPTIONS, \ .hw_version = "0.13" -static QEMUMachine pc_machine_v0_13 = { - PC_I440FX_0_13_MACHINE_OPTIONS, - .name = "pc-0.13", - .init = pc_init_pci_no_kvmclock, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_0_13 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v0_13, "pc-0.13", pc_init_pci_no_kvmclock, + PC_I440FX_0_13_MACHINE_OPTIONS, PC_COMPAT_0_13); + #define PC_COMPAT_0_12 \ PC_COMPAT_0_13 \ @@ -924,15 +831,9 @@ static QEMUMachine pc_machine_v0_13 = { PC_I440FX_0_13_MACHINE_OPTIONS, \ .hw_version = "0.12" -static QEMUMachine pc_machine_v0_12 = { - PC_I440FX_0_12_MACHINE_OPTIONS, - .name = "pc-0.12", - .init = pc_init_pci_no_kvmclock, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_0_12 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v0_12, "pc-0.12", pc_init_pci_no_kvmclock, + PC_I440FX_0_12_MACHINE_OPTIONS, PC_COMPAT_0_12); + #define PC_COMPAT_0_11 \ PC_COMPAT_0_12 \ @@ -958,15 +859,9 @@ static QEMUMachine pc_machine_v0_12 = { PC_I440FX_0_12_MACHINE_OPTIONS, \ .hw_version = "0.11" -static QEMUMachine pc_machine_v0_11 = { - PC_I440FX_0_11_MACHINE_OPTIONS, - .name = "pc-0.11", - .init = pc_init_pci_no_kvmclock, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_0_11 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v0_11, "pc-0.11", pc_init_pci_no_kvmclock, + PC_I440FX_0_11_MACHINE_OPTIONS, PC_COMPAT_0_11); + #define PC_COMPAT_0_10 \ PC_COMPAT_0_11 \ @@ -996,29 +891,18 @@ static QEMUMachine pc_machine_v0_11 = { PC_I440FX_0_11_MACHINE_OPTIONS, \ .hw_version = "0.10" -static QEMUMachine pc_machine_v0_10 = { - PC_I440FX_0_10_MACHINE_OPTIONS, - .name = "pc-0.10", - .init = pc_init_pci_no_kvmclock, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_0_10 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v0_10, "pc-0.10", pc_init_pci_no_kvmclock, + PC_I440FX_0_10_MACHINE_OPTIONS, PC_COMPAT_0_10); + #define ISAPC_MACHINE_OPTIONS \ PC_COMMON_MACHINE_OPTIONS, \ .desc = "ISA-only PC", \ .max_cpus = 1 -static QEMUMachine isapc_machine = { - ISAPC_MACHINE_OPTIONS, - .name = "isapc", - .init = pc_init_isa, - .compat_props = (GlobalProperty[]) { - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa, + ISAPC_MACHINE_OPTIONS, /* no compat */); + #ifdef CONFIG_XEN #define XENFV_MACHINE_OPTIONS \ @@ -1028,38 +912,6 @@ static QEMUMachine isapc_machine = { .default_machine_opts = "accel=xen", \ .hot_add_cpu = pc_hot_add_cpu -static QEMUMachine xenfv_machine = { - XENFV_MACHINE_OPTIONS, - .name = "xenfv", - .init = pc_xen_hvm_init, -}; +DEFINE_PC_MACHINE(xenfv, "xenfv", pc_xen_hvm_init, + XENFV_MACHINE_OPTIONS, /* no compat */); #endif - -static void pc_machine_init(void) -{ - qemu_register_pc_machine(&pc_i440fx_machine_v2_4); - qemu_register_pc_machine(&pc_i440fx_machine_v2_3); - qemu_register_pc_machine(&pc_i440fx_machine_v2_2); - qemu_register_pc_machine(&pc_i440fx_machine_v2_1); - qemu_register_pc_machine(&pc_i440fx_machine_v2_0); - qemu_register_pc_machine(&pc_i440fx_machine_v1_7); - qemu_register_pc_machine(&pc_i440fx_machine_v1_6); - qemu_register_pc_machine(&pc_i440fx_machine_v1_5); - qemu_register_pc_machine(&pc_i440fx_machine_v1_4); - qemu_register_pc_machine(&pc_machine_v1_3); - qemu_register_pc_machine(&pc_machine_v1_2); - qemu_register_pc_machine(&pc_machine_v1_1); - qemu_register_pc_machine(&pc_machine_v1_0); - qemu_register_pc_machine(&pc_machine_v0_15); - qemu_register_pc_machine(&pc_machine_v0_14); - qemu_register_pc_machine(&pc_machine_v0_13); - qemu_register_pc_machine(&pc_machine_v0_12); - qemu_register_pc_machine(&pc_machine_v0_11); - qemu_register_pc_machine(&pc_machine_v0_10); - qemu_register_pc_machine(&isapc_machine); -#ifdef CONFIG_XEN - qemu_register_pc_machine(&xenfv_machine); -#endif -} - -machine_init(pc_machine_init); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 196178ec5f..54447d053a 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -427,131 +427,65 @@ static void pc_q35_init_1_4(MachineState *machine) .default_display = "std", \ .alias = "q35" -static QEMUMachine pc_q35_machine_v2_4 = { - PC_Q35_2_4_MACHINE_OPTIONS, - .name = "pc-q35-2.4", - .init = pc_q35_init, -}; +DEFINE_PC_MACHINE(v2_4, "pc-q35-2.4", pc_q35_init, + PC_Q35_2_4_MACHINE_OPTIONS, /* no compat */); + #define PC_Q35_2_3_MACHINE_OPTIONS \ PC_Q35_2_4_MACHINE_OPTIONS, \ .alias = NULL -static QEMUMachine pc_q35_machine_v2_3 = { - PC_Q35_2_3_MACHINE_OPTIONS, - .name = "pc-q35-2.3", - .init = pc_q35_init_2_3, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_2_3 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v2_3, "pc-q35-2.3", pc_q35_init_2_3, + PC_Q35_2_3_MACHINE_OPTIONS, PC_COMPAT_2_3); + #define PC_Q35_2_2_MACHINE_OPTIONS \ PC_Q35_2_3_MACHINE_OPTIONS -static QEMUMachine pc_q35_machine_v2_2 = { - PC_Q35_2_2_MACHINE_OPTIONS, - .name = "pc-q35-2.2", - .init = pc_q35_init_2_2, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_2_2 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v2_2, "pc-q35-2.2", pc_q35_init_2_2, + PC_Q35_2_2_MACHINE_OPTIONS, PC_COMPAT_2_2); + #define PC_Q35_2_1_MACHINE_OPTIONS \ PC_Q35_2_2_MACHINE_OPTIONS, \ .default_display = NULL -static QEMUMachine pc_q35_machine_v2_1 = { - PC_Q35_2_1_MACHINE_OPTIONS, - .name = "pc-q35-2.1", - .init = pc_q35_init_2_1, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_2_1 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v2_1, "pc-q35-2.1", pc_q35_init_2_1, + PC_Q35_2_1_MACHINE_OPTIONS, PC_COMPAT_2_1); + #define PC_Q35_2_0_MACHINE_OPTIONS \ PC_Q35_2_1_MACHINE_OPTIONS -static QEMUMachine pc_q35_machine_v2_0 = { - PC_Q35_2_0_MACHINE_OPTIONS, - .name = "pc-q35-2.0", - .init = pc_q35_init_2_0, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_2_0 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v2_0, "pc-q35-2.0", pc_q35_init_2_0, + PC_Q35_2_0_MACHINE_OPTIONS, PC_COMPAT_2_0); + #define PC_Q35_1_7_MACHINE_OPTIONS \ PC_Q35_2_0_MACHINE_OPTIONS, \ .default_machine_opts = NULL -static QEMUMachine pc_q35_machine_v1_7 = { - PC_Q35_1_7_MACHINE_OPTIONS, - .name = "pc-q35-1.7", - .init = pc_q35_init_1_7, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_7 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v1_7, "pc-q35-1.7", pc_q35_init_1_7, + PC_Q35_1_7_MACHINE_OPTIONS, PC_COMPAT_1_7); + #define PC_Q35_1_6_MACHINE_OPTIONS \ PC_Q35_MACHINE_OPTIONS -static QEMUMachine pc_q35_machine_v1_6 = { - PC_Q35_1_6_MACHINE_OPTIONS, - .name = "pc-q35-1.6", - .init = pc_q35_init_1_6, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_6 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v1_6, "pc-q35-1.6", pc_q35_init_1_6, + PC_Q35_1_6_MACHINE_OPTIONS, PC_COMPAT_1_6); + #define PC_Q35_1_5_MACHINE_OPTIONS \ PC_Q35_1_6_MACHINE_OPTIONS -static QEMUMachine pc_q35_machine_v1_5 = { - PC_Q35_1_5_MACHINE_OPTIONS, - .name = "pc-q35-1.5", - .init = pc_q35_init_1_5, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_5 - { /* end of list */ } - }, -}; +DEFINE_PC_MACHINE(v1_5, "pc-q35-1.5", pc_q35_init_1_5, + PC_Q35_1_5_MACHINE_OPTIONS, PC_COMPAT_1_5); + #define PC_Q35_1_4_MACHINE_OPTIONS \ PC_Q35_1_5_MACHINE_OPTIONS, \ .hot_add_cpu = NULL -static QEMUMachine pc_q35_machine_v1_4 = { - PC_Q35_1_4_MACHINE_OPTIONS, - .name = "pc-q35-1.4", - .init = pc_q35_init_1_4, - .compat_props = (GlobalProperty[]) { - PC_COMPAT_1_4 - { /* end of list */ } - }, -}; - -static void pc_q35_machine_init(void) -{ - qemu_register_pc_machine(&pc_q35_machine_v2_4); - qemu_register_pc_machine(&pc_q35_machine_v2_3); - qemu_register_pc_machine(&pc_q35_machine_v2_2); - qemu_register_pc_machine(&pc_q35_machine_v2_1); - qemu_register_pc_machine(&pc_q35_machine_v2_0); - qemu_register_pc_machine(&pc_q35_machine_v1_7); - qemu_register_pc_machine(&pc_q35_machine_v1_6); - qemu_register_pc_machine(&pc_q35_machine_v1_5); - qemu_register_pc_machine(&pc_q35_machine_v1_4); -} - -machine_init(pc_q35_machine_init); +DEFINE_PC_MACHINE(v1_4, "pc-q35-1.4", pc_q35_init_1_4, + PC_Q35_1_4_MACHINE_OPTIONS, PC_COMPAT_1_4); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 672f1f7b41..a5b1fb02bb 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -525,4 +525,20 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .hot_add_cpu = pc_hot_add_cpu, \ .max_cpus = 255 +#define DEFINE_PC_MACHINE(suffix, namestr, initfn, OPTS, COMPAT) \ + static QEMUMachine pc_machine_##suffix = { \ + OPTS, \ + .name = namestr, \ + .init = initfn, \ + .compat_props = (GlobalProperty[]) { \ + COMPAT \ + { /* end of list */ } \ + }, \ + }; \ + static void pc_machine_init_##suffix(void) \ + { \ + qemu_register_pc_machine(&pc_machine_##suffix); \ + } \ + machine_init(pc_machine_init_##suffix) + #endif -- cgit v1.2.3 From fddd179ab962f6f78a8493742e1068d6a620e059 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 15 May 2015 14:18:54 -0300 Subject: pc: Convert *_MACHINE_OPTIONS macros into functions By now the new functions will get QEMUMachine as argument, but they will be later converted to initialize a MachineClass struct directly. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 229 +++++++++++++++++++++++++++++++-------------------- hw/i386/pc_q35.c | 102 ++++++++++++++--------- include/hw/i386/pc.h | 42 +++++----- 3 files changed, 222 insertions(+), 151 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 3c5061fd60..5acd0e089e 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -517,82 +517,104 @@ static void pc_xen_hvm_init(MachineState *machine) } #endif -#define PC_I440FX_MACHINE_OPTIONS \ - PC_DEFAULT_MACHINE_OPTIONS, \ - .family = "pc_piix", \ - .desc = "Standard PC (i440FX + PIIX, 1996)", \ - .hot_add_cpu = pc_hot_add_cpu - -#define PC_I440FX_2_4_MACHINE_OPTIONS \ - PC_I440FX_MACHINE_OPTIONS, \ - .default_machine_opts = "firmware=bios-256k.bin", \ - .default_display = "std", \ - .alias = "pc", \ - .is_default = 1 + +static void pc_i440fx_machine_options(QEMUMachine *m) +{ + pc_default_machine_options(m); + m->family = "pc_piix"; + m->desc = "Standard PC (i440FX + PIIX, 1996)"; + m->hot_add_cpu = pc_hot_add_cpu; +} + +static void pc_i440fx_2_4_machine_options(QEMUMachine *m) +{ + pc_i440fx_machine_options(m); + m->default_machine_opts = "firmware=bios-256k.bin"; + m->default_display = "std"; + m->alias = "pc"; + m->is_default = 1; +} DEFINE_PC_MACHINE(v2_4, "pc-i440fx-2.4", pc_init_pci, - PC_I440FX_2_4_MACHINE_OPTIONS, /* no compat */) + pc_i440fx_2_4_machine_options, /* no compat */) -#define PC_I440FX_2_3_MACHINE_OPTIONS \ - PC_I440FX_2_4_MACHINE_OPTIONS, \ - .alias = NULL, \ - .is_default = 0 +static void pc_i440fx_2_3_machine_options(QEMUMachine *m) +{ + pc_i440fx_machine_options(m); + m->alias = NULL; + m->is_default = 0; +} DEFINE_PC_MACHINE(v2_3, "pc-i440fx-2.3", pc_init_pci_2_3, - PC_I440FX_2_3_MACHINE_OPTIONS, PC_COMPAT_2_3); + pc_i440fx_2_3_machine_options, PC_COMPAT_2_3); -#define PC_I440FX_2_2_MACHINE_OPTIONS \ - PC_I440FX_2_3_MACHINE_OPTIONS +static void pc_i440fx_2_2_machine_options(QEMUMachine *m) +{ + pc_i440fx_2_3_machine_options(m); +} DEFINE_PC_MACHINE(v2_2, "pc-i440fx-2.2", pc_init_pci_2_2, - PC_I440FX_2_2_MACHINE_OPTIONS, PC_COMPAT_2_2); + pc_i440fx_2_2_machine_options, PC_COMPAT_2_2); -#define PC_I440FX_2_1_MACHINE_OPTIONS \ - PC_I440FX_2_2_MACHINE_OPTIONS, \ - .default_display = NULL +static void pc_i440fx_2_1_machine_options(QEMUMachine *m) +{ + pc_i440fx_2_2_machine_options(m); + m->default_display = NULL; +} DEFINE_PC_MACHINE(v2_1, "pc-i440fx-2.1", pc_init_pci_2_1, - PC_I440FX_2_1_MACHINE_OPTIONS, PC_COMPAT_2_1); + pc_i440fx_2_1_machine_options, PC_COMPAT_2_1); -#define PC_I440FX_2_0_MACHINE_OPTIONS \ - PC_I440FX_2_1_MACHINE_OPTIONS + +static void pc_i440fx_2_0_machine_options(QEMUMachine *m) +{ + pc_i440fx_2_1_machine_options(m); +} DEFINE_PC_MACHINE(v2_0, "pc-i440fx-2.0", pc_init_pci_2_0, - PC_I440FX_2_0_MACHINE_OPTIONS, PC_COMPAT_2_0); + pc_i440fx_2_0_machine_options, PC_COMPAT_2_0); -#define PC_I440FX_1_7_MACHINE_OPTIONS \ - PC_I440FX_2_0_MACHINE_OPTIONS, \ - .default_machine_opts = NULL +static void pc_i440fx_1_7_machine_options(QEMUMachine *m) +{ + pc_i440fx_2_0_machine_options(m); + m->default_machine_opts = NULL; +} DEFINE_PC_MACHINE(v1_7, "pc-i440fx-1.7", pc_init_pci_1_7, - PC_I440FX_1_7_MACHINE_OPTIONS, PC_COMPAT_1_7); + pc_i440fx_1_7_machine_options, PC_COMPAT_1_7); -#define PC_I440FX_1_6_MACHINE_OPTIONS \ - PC_I440FX_1_7_MACHINE_OPTIONS +static void pc_i440fx_1_6_machine_options(QEMUMachine *m) +{ + pc_i440fx_1_7_machine_options(m); +} DEFINE_PC_MACHINE(v1_6, "pc-i440fx-1.6", pc_init_pci_1_6, - PC_I440FX_1_6_MACHINE_OPTIONS, PC_COMPAT_1_6); + pc_i440fx_1_6_machine_options, PC_COMPAT_1_6); -#define PC_I440FX_1_5_MACHINE_OPTIONS \ - PC_I440FX_1_6_MACHINE_OPTIONS +static void pc_i440fx_1_5_machine_options(QEMUMachine *m) +{ + pc_i440fx_1_6_machine_options(m); +} DEFINE_PC_MACHINE(v1_5, "pc-i440fx-1.5", pc_init_pci_1_5, - PC_I440FX_1_5_MACHINE_OPTIONS, PC_COMPAT_1_5); + pc_i440fx_1_5_machine_options, PC_COMPAT_1_5); -#define PC_I440FX_1_4_MACHINE_OPTIONS \ - PC_I440FX_1_5_MACHINE_OPTIONS, \ - .hot_add_cpu = NULL +static void pc_i440fx_1_4_machine_options(QEMUMachine *m) +{ + pc_i440fx_1_5_machine_options(m); + m->hot_add_cpu = NULL; +} DEFINE_PC_MACHINE(v1_4, "pc-i440fx-1.4", pc_init_pci_1_4, - PC_I440FX_1_4_MACHINE_OPTIONS, PC_COMPAT_1_4); + pc_i440fx_1_4_machine_options, PC_COMPAT_1_4); #define PC_COMPAT_1_3 \ @@ -615,11 +637,14 @@ DEFINE_PC_MACHINE(v1_4, "pc-i440fx-1.4", pc_init_pci_1_4, .value = "off",\ }, -#define PC_I440FX_1_3_MACHINE_OPTIONS \ - PC_I440FX_1_4_MACHINE_OPTIONS + +static void pc_i440fx_1_3_machine_options(QEMUMachine *m) +{ + pc_i440fx_1_4_machine_options(m); +} DEFINE_PC_MACHINE(v1_3, "pc-1.3", pc_init_pci_1_3, - PC_I440FX_1_3_MACHINE_OPTIONS, PC_COMPAT_1_3); + pc_i440fx_1_3_machine_options, PC_COMPAT_1_3); #define PC_COMPAT_1_2 \ @@ -650,11 +675,13 @@ DEFINE_PC_MACHINE(v1_3, "pc-1.3", pc_init_pci_1_3, .value = "off",\ }, -#define PC_I440FX_1_2_MACHINE_OPTIONS \ - PC_I440FX_1_3_MACHINE_OPTIONS +static void pc_i440fx_1_2_machine_options(QEMUMachine *m) +{ + pc_i440fx_1_3_machine_options(m); +} DEFINE_PC_MACHINE(v1_2, "pc-1.2", pc_init_pci_1_2, - PC_I440FX_1_2_MACHINE_OPTIONS, PC_COMPAT_1_2); + pc_i440fx_1_2_machine_options, PC_COMPAT_1_2); #define PC_COMPAT_1_1 \ @@ -689,11 +716,13 @@ DEFINE_PC_MACHINE(v1_2, "pc-1.2", pc_init_pci_1_2, .value = "off",\ }, -#define PC_I440FX_1_1_MACHINE_OPTIONS \ - PC_I440FX_1_2_MACHINE_OPTIONS +static void pc_i440fx_1_1_machine_options(QEMUMachine *m) +{ + pc_i440fx_1_2_machine_options(m); +} DEFINE_PC_MACHINE(v1_1, "pc-1.1", pc_init_pci_1_2, - PC_I440FX_1_1_MACHINE_OPTIONS, PC_COMPAT_1_1); + pc_i440fx_1_1_machine_options, PC_COMPAT_1_1); #define PC_COMPAT_1_0 \ @@ -716,23 +745,27 @@ DEFINE_PC_MACHINE(v1_1, "pc-1.1", pc_init_pci_1_2, .value = "no",\ }, -#define PC_I440FX_1_0_MACHINE_OPTIONS \ - PC_I440FX_1_1_MACHINE_OPTIONS, \ - .hw_version = "1.0" +static void pc_i440fx_1_0_machine_options(QEMUMachine *m) +{ + pc_i440fx_1_1_machine_options(m); + m->hw_version = "1.0"; +} DEFINE_PC_MACHINE(v1_0, "pc-1.0", pc_init_pci_1_2, - PC_I440FX_1_0_MACHINE_OPTIONS, PC_COMPAT_1_0); + pc_i440fx_1_0_machine_options, PC_COMPAT_1_0); #define PC_COMPAT_0_15 \ PC_COMPAT_1_0 -#define PC_I440FX_0_15_MACHINE_OPTIONS \ - PC_I440FX_1_0_MACHINE_OPTIONS, \ - .hw_version = "0.15" +static void pc_i440fx_0_15_machine_options(QEMUMachine *m) +{ + pc_i440fx_1_0_machine_options(m); + m->hw_version = "0.15"; +} DEFINE_PC_MACHINE(v0_15, "pc-0.15", pc_init_pci_1_2, - PC_I440FX_0_15_MACHINE_OPTIONS, PC_COMPAT_0_15); + pc_i440fx_0_15_machine_options, PC_COMPAT_0_15); #define PC_COMPAT_0_14 \ @@ -763,12 +796,14 @@ DEFINE_PC_MACHINE(v0_15, "pc-0.15", pc_init_pci_1_2, .value = stringify(2),\ }, -#define PC_I440FX_0_14_MACHINE_OPTIONS \ - PC_I440FX_0_15_MACHINE_OPTIONS, \ - .hw_version = "0.14" +static void pc_i440fx_0_14_machine_options(QEMUMachine *m) +{ + pc_i440fx_0_15_machine_options(m); + m->hw_version = "0.14"; +} DEFINE_PC_MACHINE(v0_14, "pc-0.14", pc_init_pci_1_2, - PC_I440FX_0_14_MACHINE_OPTIONS, PC_COMPAT_0_14); + pc_i440fx_0_14_machine_options, PC_COMPAT_0_14); #define PC_COMPAT_0_13 \ @@ -795,12 +830,14 @@ DEFINE_PC_MACHINE(v0_14, "pc-0.14", pc_init_pci_1_2, .value = stringify(0),\ }, -#define PC_I440FX_0_13_MACHINE_OPTIONS \ - PC_I440FX_0_14_MACHINE_OPTIONS, \ - .hw_version = "0.13" +static void pc_i440fx_0_13_machine_options(QEMUMachine *m) +{ + pc_i440fx_0_14_machine_options(m); + m->hw_version = "0.13"; +} DEFINE_PC_MACHINE(v0_13, "pc-0.13", pc_init_pci_no_kvmclock, - PC_I440FX_0_13_MACHINE_OPTIONS, PC_COMPAT_0_13); + pc_i440fx_0_13_machine_options, PC_COMPAT_0_13); #define PC_COMPAT_0_12 \ @@ -827,12 +864,14 @@ DEFINE_PC_MACHINE(v0_13, "pc-0.13", pc_init_pci_no_kvmclock, .value = "1",\ }, -#define PC_I440FX_0_12_MACHINE_OPTIONS \ - PC_I440FX_0_13_MACHINE_OPTIONS, \ - .hw_version = "0.12" +static void pc_i440fx_0_12_machine_options(QEMUMachine *m) +{ + pc_i440fx_0_13_machine_options(m); + m->hw_version = "0.12"; +} DEFINE_PC_MACHINE(v0_12, "pc-0.12", pc_init_pci_no_kvmclock, - PC_I440FX_0_12_MACHINE_OPTIONS, PC_COMPAT_0_12); + pc_i440fx_0_12_machine_options, PC_COMPAT_0_12); #define PC_COMPAT_0_11 \ @@ -855,12 +894,14 @@ DEFINE_PC_MACHINE(v0_12, "pc-0.12", pc_init_pci_no_kvmclock, .value = "0.11",\ }, -#define PC_I440FX_0_11_MACHINE_OPTIONS \ - PC_I440FX_0_12_MACHINE_OPTIONS, \ - .hw_version = "0.11" +static void pc_i440fx_0_11_machine_options(QEMUMachine *m) +{ + pc_i440fx_0_12_machine_options(m); + m->hw_version = "0.11"; +} DEFINE_PC_MACHINE(v0_11, "pc-0.11", pc_init_pci_no_kvmclock, - PC_I440FX_0_11_MACHINE_OPTIONS, PC_COMPAT_0_11); + pc_i440fx_0_11_machine_options, PC_COMPAT_0_11); #define PC_COMPAT_0_10 \ @@ -887,31 +928,37 @@ DEFINE_PC_MACHINE(v0_11, "pc-0.11", pc_init_pci_no_kvmclock, .value = "0.10",\ }, -#define PC_I440FX_0_10_MACHINE_OPTIONS \ - PC_I440FX_0_11_MACHINE_OPTIONS, \ - .hw_version = "0.10" +static void pc_i440fx_0_10_machine_options(QEMUMachine *m) +{ + pc_i440fx_0_11_machine_options(m); + m->hw_version = "0.10"; +} DEFINE_PC_MACHINE(v0_10, "pc-0.10", pc_init_pci_no_kvmclock, - PC_I440FX_0_10_MACHINE_OPTIONS, PC_COMPAT_0_10); + pc_i440fx_0_10_machine_options, PC_COMPAT_0_10); -#define ISAPC_MACHINE_OPTIONS \ - PC_COMMON_MACHINE_OPTIONS, \ - .desc = "ISA-only PC", \ - .max_cpus = 1 +static void isapc_machine_options(QEMUMachine *m) +{ + pc_common_machine_options(m); + m->desc = "ISA-only PC"; + m->max_cpus = 1; +} DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa, - ISAPC_MACHINE_OPTIONS, /* no compat */); + isapc_machine_options, /* no compat */); #ifdef CONFIG_XEN -#define XENFV_MACHINE_OPTIONS \ - PC_COMMON_MACHINE_OPTIONS, \ - .desc = "Xen Fully-virtualized PC", \ - .max_cpus = HVM_MAX_VCPUS, \ - .default_machine_opts = "accel=xen", \ - .hot_add_cpu = pc_hot_add_cpu +static void xenfv_machine_options(QEMUMachine *m) +{ + pc_common_machine_options(m); + m->desc = "Xen Fully-virtualized PC"; + m->max_cpus = HVM_MAX_VCPUS; + m->default_machine_opts = "accel=xen"; + m->hot_add_cpu = pc_hot_add_cpu; +} DEFINE_PC_MACHINE(xenfv, "xenfv", pc_xen_hvm_init, - XENFV_MACHINE_OPTIONS, /* no compat */); + xenfv_machine_options, /* no compat */); #endif diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 54447d053a..0226021b5d 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -414,78 +414,98 @@ static void pc_q35_init_1_4(MachineState *machine) pc_q35_init(machine); } -#define PC_Q35_MACHINE_OPTIONS \ - PC_DEFAULT_MACHINE_OPTIONS, \ - .family = "pc_q35", \ - .desc = "Standard PC (Q35 + ICH9, 2009)", \ - .hot_add_cpu = pc_hot_add_cpu, \ - .units_per_default_bus = 1 - -#define PC_Q35_2_4_MACHINE_OPTIONS \ - PC_Q35_MACHINE_OPTIONS, \ - .default_machine_opts = "firmware=bios-256k.bin", \ - .default_display = "std", \ - .alias = "q35" +static void pc_q35_machine_options(QEMUMachine *m) +{ + pc_default_machine_options(m); + m->family = "pc_q35"; + m->desc = "Standard PC (Q35 + ICH9, 2009)"; + m->hot_add_cpu = pc_hot_add_cpu; + m->units_per_default_bus = 1; +} + +static void pc_q35_2_4_machine_options(QEMUMachine *m) +{ + pc_q35_machine_options(m); + m->default_machine_opts = "firmware=bios-256k.bin"; + m->default_display = "std"; + m->alias = "q35"; +} DEFINE_PC_MACHINE(v2_4, "pc-q35-2.4", pc_q35_init, - PC_Q35_2_4_MACHINE_OPTIONS, /* no compat */); + pc_q35_2_4_machine_options, /* no compat */); -#define PC_Q35_2_3_MACHINE_OPTIONS \ - PC_Q35_2_4_MACHINE_OPTIONS, \ - .alias = NULL +static void pc_q35_2_3_machine_options(QEMUMachine *m) +{ + pc_q35_2_4_machine_options(m); + m->alias = NULL; +} DEFINE_PC_MACHINE(v2_3, "pc-q35-2.3", pc_q35_init_2_3, - PC_Q35_2_3_MACHINE_OPTIONS, PC_COMPAT_2_3); + pc_q35_2_3_machine_options, PC_COMPAT_2_3); -#define PC_Q35_2_2_MACHINE_OPTIONS \ - PC_Q35_2_3_MACHINE_OPTIONS +static void pc_q35_2_2_machine_options(QEMUMachine *m) +{ + pc_q35_2_3_machine_options(m); +} DEFINE_PC_MACHINE(v2_2, "pc-q35-2.2", pc_q35_init_2_2, - PC_Q35_2_2_MACHINE_OPTIONS, PC_COMPAT_2_2); + pc_q35_2_2_machine_options, PC_COMPAT_2_2); -#define PC_Q35_2_1_MACHINE_OPTIONS \ - PC_Q35_2_2_MACHINE_OPTIONS, \ - .default_display = NULL +static void pc_q35_2_1_machine_options(QEMUMachine *m) +{ + pc_q35_2_2_machine_options(m); + m->default_display = NULL; +} DEFINE_PC_MACHINE(v2_1, "pc-q35-2.1", pc_q35_init_2_1, - PC_Q35_2_1_MACHINE_OPTIONS, PC_COMPAT_2_1); + pc_q35_2_1_machine_options, PC_COMPAT_2_1); -#define PC_Q35_2_0_MACHINE_OPTIONS \ - PC_Q35_2_1_MACHINE_OPTIONS +static void pc_q35_2_0_machine_options(QEMUMachine *m) +{ + pc_q35_2_1_machine_options(m); +} DEFINE_PC_MACHINE(v2_0, "pc-q35-2.0", pc_q35_init_2_0, - PC_Q35_2_0_MACHINE_OPTIONS, PC_COMPAT_2_0); + pc_q35_2_0_machine_options, PC_COMPAT_2_0); -#define PC_Q35_1_7_MACHINE_OPTIONS \ - PC_Q35_2_0_MACHINE_OPTIONS, \ - .default_machine_opts = NULL +static void pc_q35_1_7_machine_options(QEMUMachine *m) +{ + pc_q35_2_0_machine_options(m); + m->default_machine_opts = NULL; +} DEFINE_PC_MACHINE(v1_7, "pc-q35-1.7", pc_q35_init_1_7, - PC_Q35_1_7_MACHINE_OPTIONS, PC_COMPAT_1_7); + pc_q35_1_7_machine_options, PC_COMPAT_1_7); -#define PC_Q35_1_6_MACHINE_OPTIONS \ - PC_Q35_MACHINE_OPTIONS +static void pc_q35_1_6_machine_options(QEMUMachine *m) +{ + pc_q35_machine_options(m); +} DEFINE_PC_MACHINE(v1_6, "pc-q35-1.6", pc_q35_init_1_6, - PC_Q35_1_6_MACHINE_OPTIONS, PC_COMPAT_1_6); + pc_q35_1_6_machine_options, PC_COMPAT_1_6); -#define PC_Q35_1_5_MACHINE_OPTIONS \ - PC_Q35_1_6_MACHINE_OPTIONS +static void pc_q35_1_5_machine_options(QEMUMachine *m) +{ + pc_q35_1_6_machine_options(m); +} DEFINE_PC_MACHINE(v1_5, "pc-q35-1.5", pc_q35_init_1_5, - PC_Q35_1_5_MACHINE_OPTIONS, PC_COMPAT_1_5); + pc_q35_1_5_machine_options, PC_COMPAT_1_5); -#define PC_Q35_1_4_MACHINE_OPTIONS \ - PC_Q35_1_5_MACHINE_OPTIONS, \ - .hot_add_cpu = NULL +static void pc_q35_1_4_machine_options(QEMUMachine *m) +{ + pc_q35_1_5_machine_options(m); + m->hot_add_cpu = NULL; +} DEFINE_PC_MACHINE(v1_4, "pc-q35-1.4", pc_q35_init_1_4, - PC_Q35_1_4_MACHINE_OPTIONS, PC_COMPAT_1_4); + pc_q35_1_4_machine_options, PC_COMPAT_1_4); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index a5b1fb02bb..7a70d1f8b6 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -517,27 +517,31 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .value = stringify(0),\ }, -#define PC_COMMON_MACHINE_OPTIONS \ - .default_boot_order = "cad" - -#define PC_DEFAULT_MACHINE_OPTIONS \ - PC_COMMON_MACHINE_OPTIONS, \ - .hot_add_cpu = pc_hot_add_cpu, \ - .max_cpus = 255 - -#define DEFINE_PC_MACHINE(suffix, namestr, initfn, OPTS, COMPAT) \ - static QEMUMachine pc_machine_##suffix = { \ - OPTS, \ - .name = namestr, \ - .init = initfn, \ - .compat_props = (GlobalProperty[]) { \ - COMPAT \ - { /* end of list */ } \ - }, \ - }; \ +static inline void pc_common_machine_options(QEMUMachine *m) +{ + m->default_boot_order = "cad"; +} + +static inline void pc_default_machine_options(QEMUMachine *m) +{ + pc_common_machine_options(m); + m->hot_add_cpu = pc_hot_add_cpu; + m->max_cpus = 255; +} + +#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn, COMPAT) \ static void pc_machine_init_##suffix(void) \ { \ - qemu_register_pc_machine(&pc_machine_##suffix); \ + static QEMUMachine m = { }; \ + static GlobalProperty props[] = { \ + COMPAT \ + { /* end of list */ } \ + }; \ + optsfn(&m); \ + m.name = namestr; \ + m.init = initfn; \ + m.compat_props = props; \ + qemu_register_pc_machine(&m); \ } \ machine_init(pc_machine_init_##suffix) -- cgit v1.2.3 From 25519b062c70f2afe2d2f0c262f3838a41e8bc7c Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 15 May 2015 14:18:55 -0300 Subject: pc: Move compat_props setting inside *_machine_options() functions This will simplify the DEFINE_PC_MACHINE macro, and will help us to implement reuse of PC_COMPAT_* macros through class_init function reuse, in the future. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 60 ++++++++++++++++++++++++++++++++++------------------ hw/i386/pc_q35.c | 26 +++++++++++++++-------- include/hw/i386/pc.h | 15 +++++++------ 3 files changed, 65 insertions(+), 36 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 5acd0e089e..89f55d723e 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -536,7 +536,7 @@ static void pc_i440fx_2_4_machine_options(QEMUMachine *m) } DEFINE_PC_MACHINE(v2_4, "pc-i440fx-2.4", pc_init_pci, - pc_i440fx_2_4_machine_options, /* no compat */) + pc_i440fx_2_4_machine_options) static void pc_i440fx_2_3_machine_options(QEMUMachine *m) @@ -544,77 +544,85 @@ static void pc_i440fx_2_3_machine_options(QEMUMachine *m) pc_i440fx_machine_options(m); m->alias = NULL; m->is_default = 0; + SET_MACHINE_COMPAT(m, PC_COMPAT_2_3); } DEFINE_PC_MACHINE(v2_3, "pc-i440fx-2.3", pc_init_pci_2_3, - pc_i440fx_2_3_machine_options, PC_COMPAT_2_3); + pc_i440fx_2_3_machine_options); static void pc_i440fx_2_2_machine_options(QEMUMachine *m) { pc_i440fx_2_3_machine_options(m); + SET_MACHINE_COMPAT(m, PC_COMPAT_2_2); } DEFINE_PC_MACHINE(v2_2, "pc-i440fx-2.2", pc_init_pci_2_2, - pc_i440fx_2_2_machine_options, PC_COMPAT_2_2); + pc_i440fx_2_2_machine_options); static void pc_i440fx_2_1_machine_options(QEMUMachine *m) { pc_i440fx_2_2_machine_options(m); m->default_display = NULL; + SET_MACHINE_COMPAT(m, PC_COMPAT_2_1); } DEFINE_PC_MACHINE(v2_1, "pc-i440fx-2.1", pc_init_pci_2_1, - pc_i440fx_2_1_machine_options, PC_COMPAT_2_1); + pc_i440fx_2_1_machine_options); static void pc_i440fx_2_0_machine_options(QEMUMachine *m) { pc_i440fx_2_1_machine_options(m); + SET_MACHINE_COMPAT(m, PC_COMPAT_2_0); } DEFINE_PC_MACHINE(v2_0, "pc-i440fx-2.0", pc_init_pci_2_0, - pc_i440fx_2_0_machine_options, PC_COMPAT_2_0); + pc_i440fx_2_0_machine_options); static void pc_i440fx_1_7_machine_options(QEMUMachine *m) { pc_i440fx_2_0_machine_options(m); m->default_machine_opts = NULL; + SET_MACHINE_COMPAT(m, PC_COMPAT_1_7); } DEFINE_PC_MACHINE(v1_7, "pc-i440fx-1.7", pc_init_pci_1_7, - pc_i440fx_1_7_machine_options, PC_COMPAT_1_7); + pc_i440fx_1_7_machine_options); static void pc_i440fx_1_6_machine_options(QEMUMachine *m) { pc_i440fx_1_7_machine_options(m); + SET_MACHINE_COMPAT(m, PC_COMPAT_1_6); } DEFINE_PC_MACHINE(v1_6, "pc-i440fx-1.6", pc_init_pci_1_6, - pc_i440fx_1_6_machine_options, PC_COMPAT_1_6); + pc_i440fx_1_6_machine_options); static void pc_i440fx_1_5_machine_options(QEMUMachine *m) { pc_i440fx_1_6_machine_options(m); + SET_MACHINE_COMPAT(m, PC_COMPAT_1_5); } DEFINE_PC_MACHINE(v1_5, "pc-i440fx-1.5", pc_init_pci_1_5, - pc_i440fx_1_5_machine_options, PC_COMPAT_1_5); + pc_i440fx_1_5_machine_options); static void pc_i440fx_1_4_machine_options(QEMUMachine *m) { pc_i440fx_1_5_machine_options(m); m->hot_add_cpu = NULL; + SET_MACHINE_COMPAT(m, PC_COMPAT_1_4); } DEFINE_PC_MACHINE(v1_4, "pc-i440fx-1.4", pc_init_pci_1_4, - pc_i440fx_1_4_machine_options, PC_COMPAT_1_4); + pc_i440fx_1_4_machine_options); #define PC_COMPAT_1_3 \ @@ -641,10 +649,11 @@ DEFINE_PC_MACHINE(v1_4, "pc-i440fx-1.4", pc_init_pci_1_4, static void pc_i440fx_1_3_machine_options(QEMUMachine *m) { pc_i440fx_1_4_machine_options(m); + SET_MACHINE_COMPAT(m, PC_COMPAT_1_3); } DEFINE_PC_MACHINE(v1_3, "pc-1.3", pc_init_pci_1_3, - pc_i440fx_1_3_machine_options, PC_COMPAT_1_3); + pc_i440fx_1_3_machine_options); #define PC_COMPAT_1_2 \ @@ -678,10 +687,11 @@ DEFINE_PC_MACHINE(v1_3, "pc-1.3", pc_init_pci_1_3, static void pc_i440fx_1_2_machine_options(QEMUMachine *m) { pc_i440fx_1_3_machine_options(m); + SET_MACHINE_COMPAT(m, PC_COMPAT_1_2); } DEFINE_PC_MACHINE(v1_2, "pc-1.2", pc_init_pci_1_2, - pc_i440fx_1_2_machine_options, PC_COMPAT_1_2); + pc_i440fx_1_2_machine_options); #define PC_COMPAT_1_1 \ @@ -719,10 +729,11 @@ DEFINE_PC_MACHINE(v1_2, "pc-1.2", pc_init_pci_1_2, static void pc_i440fx_1_1_machine_options(QEMUMachine *m) { pc_i440fx_1_2_machine_options(m); + SET_MACHINE_COMPAT(m, PC_COMPAT_1_1); } DEFINE_PC_MACHINE(v1_1, "pc-1.1", pc_init_pci_1_2, - pc_i440fx_1_1_machine_options, PC_COMPAT_1_1); + pc_i440fx_1_1_machine_options); #define PC_COMPAT_1_0 \ @@ -749,10 +760,11 @@ static void pc_i440fx_1_0_machine_options(QEMUMachine *m) { pc_i440fx_1_1_machine_options(m); m->hw_version = "1.0"; + SET_MACHINE_COMPAT(m, PC_COMPAT_1_0); } DEFINE_PC_MACHINE(v1_0, "pc-1.0", pc_init_pci_1_2, - pc_i440fx_1_0_machine_options, PC_COMPAT_1_0); + pc_i440fx_1_0_machine_options); #define PC_COMPAT_0_15 \ @@ -762,10 +774,11 @@ static void pc_i440fx_0_15_machine_options(QEMUMachine *m) { pc_i440fx_1_0_machine_options(m); m->hw_version = "0.15"; + SET_MACHINE_COMPAT(m, PC_COMPAT_0_15); } DEFINE_PC_MACHINE(v0_15, "pc-0.15", pc_init_pci_1_2, - pc_i440fx_0_15_machine_options, PC_COMPAT_0_15); + pc_i440fx_0_15_machine_options); #define PC_COMPAT_0_14 \ @@ -800,10 +813,11 @@ static void pc_i440fx_0_14_machine_options(QEMUMachine *m) { pc_i440fx_0_15_machine_options(m); m->hw_version = "0.14"; + SET_MACHINE_COMPAT(m, PC_COMPAT_0_14); } DEFINE_PC_MACHINE(v0_14, "pc-0.14", pc_init_pci_1_2, - pc_i440fx_0_14_machine_options, PC_COMPAT_0_14); + pc_i440fx_0_14_machine_options); #define PC_COMPAT_0_13 \ @@ -834,10 +848,11 @@ static void pc_i440fx_0_13_machine_options(QEMUMachine *m) { pc_i440fx_0_14_machine_options(m); m->hw_version = "0.13"; + SET_MACHINE_COMPAT(m, PC_COMPAT_0_13); } DEFINE_PC_MACHINE(v0_13, "pc-0.13", pc_init_pci_no_kvmclock, - pc_i440fx_0_13_machine_options, PC_COMPAT_0_13); + pc_i440fx_0_13_machine_options); #define PC_COMPAT_0_12 \ @@ -868,10 +883,11 @@ static void pc_i440fx_0_12_machine_options(QEMUMachine *m) { pc_i440fx_0_13_machine_options(m); m->hw_version = "0.12"; + SET_MACHINE_COMPAT(m, PC_COMPAT_0_12); } DEFINE_PC_MACHINE(v0_12, "pc-0.12", pc_init_pci_no_kvmclock, - pc_i440fx_0_12_machine_options, PC_COMPAT_0_12); + pc_i440fx_0_12_machine_options); #define PC_COMPAT_0_11 \ @@ -898,10 +914,11 @@ static void pc_i440fx_0_11_machine_options(QEMUMachine *m) { pc_i440fx_0_12_machine_options(m); m->hw_version = "0.11"; + SET_MACHINE_COMPAT(m, PC_COMPAT_0_11); } DEFINE_PC_MACHINE(v0_11, "pc-0.11", pc_init_pci_no_kvmclock, - pc_i440fx_0_11_machine_options, PC_COMPAT_0_11); + pc_i440fx_0_11_machine_options); #define PC_COMPAT_0_10 \ @@ -932,10 +949,11 @@ static void pc_i440fx_0_10_machine_options(QEMUMachine *m) { pc_i440fx_0_11_machine_options(m); m->hw_version = "0.10"; + SET_MACHINE_COMPAT(m, PC_COMPAT_0_10); } DEFINE_PC_MACHINE(v0_10, "pc-0.10", pc_init_pci_no_kvmclock, - pc_i440fx_0_10_machine_options, PC_COMPAT_0_10); + pc_i440fx_0_10_machine_options); static void isapc_machine_options(QEMUMachine *m) @@ -946,7 +964,7 @@ static void isapc_machine_options(QEMUMachine *m) } DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa, - isapc_machine_options, /* no compat */); + isapc_machine_options); #ifdef CONFIG_XEN @@ -960,5 +978,5 @@ static void xenfv_machine_options(QEMUMachine *m) } DEFINE_PC_MACHINE(xenfv, "xenfv", pc_xen_hvm_init, - xenfv_machine_options, /* no compat */); + xenfv_machine_options); #endif diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 0226021b5d..dcd728cc07 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -432,80 +432,88 @@ static void pc_q35_2_4_machine_options(QEMUMachine *m) } DEFINE_PC_MACHINE(v2_4, "pc-q35-2.4", pc_q35_init, - pc_q35_2_4_machine_options, /* no compat */); + pc_q35_2_4_machine_options); static void pc_q35_2_3_machine_options(QEMUMachine *m) { pc_q35_2_4_machine_options(m); m->alias = NULL; + SET_MACHINE_COMPAT(m, PC_COMPAT_2_3); } DEFINE_PC_MACHINE(v2_3, "pc-q35-2.3", pc_q35_init_2_3, - pc_q35_2_3_machine_options, PC_COMPAT_2_3); + pc_q35_2_3_machine_options); static void pc_q35_2_2_machine_options(QEMUMachine *m) { pc_q35_2_3_machine_options(m); + SET_MACHINE_COMPAT(m, PC_COMPAT_2_2); } DEFINE_PC_MACHINE(v2_2, "pc-q35-2.2", pc_q35_init_2_2, - pc_q35_2_2_machine_options, PC_COMPAT_2_2); + pc_q35_2_2_machine_options); static void pc_q35_2_1_machine_options(QEMUMachine *m) { pc_q35_2_2_machine_options(m); m->default_display = NULL; + SET_MACHINE_COMPAT(m, PC_COMPAT_2_1); } DEFINE_PC_MACHINE(v2_1, "pc-q35-2.1", pc_q35_init_2_1, - pc_q35_2_1_machine_options, PC_COMPAT_2_1); + pc_q35_2_1_machine_options); static void pc_q35_2_0_machine_options(QEMUMachine *m) { pc_q35_2_1_machine_options(m); + SET_MACHINE_COMPAT(m, PC_COMPAT_2_0); } DEFINE_PC_MACHINE(v2_0, "pc-q35-2.0", pc_q35_init_2_0, - pc_q35_2_0_machine_options, PC_COMPAT_2_0); + pc_q35_2_0_machine_options); static void pc_q35_1_7_machine_options(QEMUMachine *m) { pc_q35_2_0_machine_options(m); m->default_machine_opts = NULL; + SET_MACHINE_COMPAT(m, PC_COMPAT_1_7); } DEFINE_PC_MACHINE(v1_7, "pc-q35-1.7", pc_q35_init_1_7, - pc_q35_1_7_machine_options, PC_COMPAT_1_7); + pc_q35_1_7_machine_options); static void pc_q35_1_6_machine_options(QEMUMachine *m) { pc_q35_machine_options(m); + SET_MACHINE_COMPAT(m, PC_COMPAT_1_6); } DEFINE_PC_MACHINE(v1_6, "pc-q35-1.6", pc_q35_init_1_6, - pc_q35_1_6_machine_options, PC_COMPAT_1_6); + pc_q35_1_6_machine_options); static void pc_q35_1_5_machine_options(QEMUMachine *m) { pc_q35_1_6_machine_options(m); + SET_MACHINE_COMPAT(m, PC_COMPAT_1_5); } DEFINE_PC_MACHINE(v1_5, "pc-q35-1.5", pc_q35_init_1_5, - pc_q35_1_5_machine_options, PC_COMPAT_1_5); + pc_q35_1_5_machine_options); static void pc_q35_1_4_machine_options(QEMUMachine *m) { pc_q35_1_5_machine_options(m); m->hot_add_cpu = NULL; + SET_MACHINE_COMPAT(m, PC_COMPAT_1_4); } DEFINE_PC_MACHINE(v1_4, "pc-q35-1.4", pc_q35_init_1_4, - pc_q35_1_4_machine_options, PC_COMPAT_1_4); + pc_q35_1_4_machine_options); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 7a70d1f8b6..c4f080878d 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -529,20 +529,23 @@ static inline void pc_default_machine_options(QEMUMachine *m) m->max_cpus = 255; } -#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn, COMPAT) \ +#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \ static void pc_machine_init_##suffix(void) \ { \ static QEMUMachine m = { }; \ - static GlobalProperty props[] = { \ - COMPAT \ - { /* end of list */ } \ - }; \ optsfn(&m); \ m.name = namestr; \ m.init = initfn; \ - m.compat_props = props; \ qemu_register_pc_machine(&m); \ } \ machine_init(pc_machine_init_##suffix) +#define SET_MACHINE_COMPAT(m, COMPAT) do { \ + static GlobalProperty props[] = { \ + COMPAT \ + { /* end of list */ } \ + }; \ + (m)->compat_props = props; \ +} while (0) + #endif -- cgit v1.2.3 From 865906f7fdadd2732441ab158787f81f6a212bfe Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 15 May 2015 14:18:56 -0300 Subject: pc: Don't use QEMUMachine anymore Now that we have a DEFINE_PC_MACHINE helper macro that just requires an initialization function, it is trivial to convert them to register a QOM machine class directly, instead of using QEMUMachine. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 44 ++++++++++++++++++++++---------------------- hw/i386/pc_q35.c | 20 ++++++++++---------- include/hw/i386/pc.h | 22 +++++++++++++++------- 3 files changed, 47 insertions(+), 39 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 89f55d723e..052fca26ef 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -518,7 +518,7 @@ static void pc_xen_hvm_init(MachineState *machine) #endif -static void pc_i440fx_machine_options(QEMUMachine *m) +static void pc_i440fx_machine_options(MachineClass *m) { pc_default_machine_options(m); m->family = "pc_piix"; @@ -526,7 +526,7 @@ static void pc_i440fx_machine_options(QEMUMachine *m) m->hot_add_cpu = pc_hot_add_cpu; } -static void pc_i440fx_2_4_machine_options(QEMUMachine *m) +static void pc_i440fx_2_4_machine_options(MachineClass *m) { pc_i440fx_machine_options(m); m->default_machine_opts = "firmware=bios-256k.bin"; @@ -539,7 +539,7 @@ DEFINE_PC_MACHINE(v2_4, "pc-i440fx-2.4", pc_init_pci, pc_i440fx_2_4_machine_options) -static void pc_i440fx_2_3_machine_options(QEMUMachine *m) +static void pc_i440fx_2_3_machine_options(MachineClass *m) { pc_i440fx_machine_options(m); m->alias = NULL; @@ -551,7 +551,7 @@ DEFINE_PC_MACHINE(v2_3, "pc-i440fx-2.3", pc_init_pci_2_3, pc_i440fx_2_3_machine_options); -static void pc_i440fx_2_2_machine_options(QEMUMachine *m) +static void pc_i440fx_2_2_machine_options(MachineClass *m) { pc_i440fx_2_3_machine_options(m); SET_MACHINE_COMPAT(m, PC_COMPAT_2_2); @@ -561,7 +561,7 @@ DEFINE_PC_MACHINE(v2_2, "pc-i440fx-2.2", pc_init_pci_2_2, pc_i440fx_2_2_machine_options); -static void pc_i440fx_2_1_machine_options(QEMUMachine *m) +static void pc_i440fx_2_1_machine_options(MachineClass *m) { pc_i440fx_2_2_machine_options(m); m->default_display = NULL; @@ -573,7 +573,7 @@ DEFINE_PC_MACHINE(v2_1, "pc-i440fx-2.1", pc_init_pci_2_1, -static void pc_i440fx_2_0_machine_options(QEMUMachine *m) +static void pc_i440fx_2_0_machine_options(MachineClass *m) { pc_i440fx_2_1_machine_options(m); SET_MACHINE_COMPAT(m, PC_COMPAT_2_0); @@ -583,7 +583,7 @@ DEFINE_PC_MACHINE(v2_0, "pc-i440fx-2.0", pc_init_pci_2_0, pc_i440fx_2_0_machine_options); -static void pc_i440fx_1_7_machine_options(QEMUMachine *m) +static void pc_i440fx_1_7_machine_options(MachineClass *m) { pc_i440fx_2_0_machine_options(m); m->default_machine_opts = NULL; @@ -594,7 +594,7 @@ DEFINE_PC_MACHINE(v1_7, "pc-i440fx-1.7", pc_init_pci_1_7, pc_i440fx_1_7_machine_options); -static void pc_i440fx_1_6_machine_options(QEMUMachine *m) +static void pc_i440fx_1_6_machine_options(MachineClass *m) { pc_i440fx_1_7_machine_options(m); SET_MACHINE_COMPAT(m, PC_COMPAT_1_6); @@ -604,7 +604,7 @@ DEFINE_PC_MACHINE(v1_6, "pc-i440fx-1.6", pc_init_pci_1_6, pc_i440fx_1_6_machine_options); -static void pc_i440fx_1_5_machine_options(QEMUMachine *m) +static void pc_i440fx_1_5_machine_options(MachineClass *m) { pc_i440fx_1_6_machine_options(m); SET_MACHINE_COMPAT(m, PC_COMPAT_1_5); @@ -614,7 +614,7 @@ DEFINE_PC_MACHINE(v1_5, "pc-i440fx-1.5", pc_init_pci_1_5, pc_i440fx_1_5_machine_options); -static void pc_i440fx_1_4_machine_options(QEMUMachine *m) +static void pc_i440fx_1_4_machine_options(MachineClass *m) { pc_i440fx_1_5_machine_options(m); m->hot_add_cpu = NULL; @@ -646,7 +646,7 @@ DEFINE_PC_MACHINE(v1_4, "pc-i440fx-1.4", pc_init_pci_1_4, }, -static void pc_i440fx_1_3_machine_options(QEMUMachine *m) +static void pc_i440fx_1_3_machine_options(MachineClass *m) { pc_i440fx_1_4_machine_options(m); SET_MACHINE_COMPAT(m, PC_COMPAT_1_3); @@ -684,7 +684,7 @@ DEFINE_PC_MACHINE(v1_3, "pc-1.3", pc_init_pci_1_3, .value = "off",\ }, -static void pc_i440fx_1_2_machine_options(QEMUMachine *m) +static void pc_i440fx_1_2_machine_options(MachineClass *m) { pc_i440fx_1_3_machine_options(m); SET_MACHINE_COMPAT(m, PC_COMPAT_1_2); @@ -726,7 +726,7 @@ DEFINE_PC_MACHINE(v1_2, "pc-1.2", pc_init_pci_1_2, .value = "off",\ }, -static void pc_i440fx_1_1_machine_options(QEMUMachine *m) +static void pc_i440fx_1_1_machine_options(MachineClass *m) { pc_i440fx_1_2_machine_options(m); SET_MACHINE_COMPAT(m, PC_COMPAT_1_1); @@ -756,7 +756,7 @@ DEFINE_PC_MACHINE(v1_1, "pc-1.1", pc_init_pci_1_2, .value = "no",\ }, -static void pc_i440fx_1_0_machine_options(QEMUMachine *m) +static void pc_i440fx_1_0_machine_options(MachineClass *m) { pc_i440fx_1_1_machine_options(m); m->hw_version = "1.0"; @@ -770,7 +770,7 @@ DEFINE_PC_MACHINE(v1_0, "pc-1.0", pc_init_pci_1_2, #define PC_COMPAT_0_15 \ PC_COMPAT_1_0 -static void pc_i440fx_0_15_machine_options(QEMUMachine *m) +static void pc_i440fx_0_15_machine_options(MachineClass *m) { pc_i440fx_1_0_machine_options(m); m->hw_version = "0.15"; @@ -809,7 +809,7 @@ DEFINE_PC_MACHINE(v0_15, "pc-0.15", pc_init_pci_1_2, .value = stringify(2),\ }, -static void pc_i440fx_0_14_machine_options(QEMUMachine *m) +static void pc_i440fx_0_14_machine_options(MachineClass *m) { pc_i440fx_0_15_machine_options(m); m->hw_version = "0.14"; @@ -844,7 +844,7 @@ DEFINE_PC_MACHINE(v0_14, "pc-0.14", pc_init_pci_1_2, .value = stringify(0),\ }, -static void pc_i440fx_0_13_machine_options(QEMUMachine *m) +static void pc_i440fx_0_13_machine_options(MachineClass *m) { pc_i440fx_0_14_machine_options(m); m->hw_version = "0.13"; @@ -879,7 +879,7 @@ DEFINE_PC_MACHINE(v0_13, "pc-0.13", pc_init_pci_no_kvmclock, .value = "1",\ }, -static void pc_i440fx_0_12_machine_options(QEMUMachine *m) +static void pc_i440fx_0_12_machine_options(MachineClass *m) { pc_i440fx_0_13_machine_options(m); m->hw_version = "0.12"; @@ -910,7 +910,7 @@ DEFINE_PC_MACHINE(v0_12, "pc-0.12", pc_init_pci_no_kvmclock, .value = "0.11",\ }, -static void pc_i440fx_0_11_machine_options(QEMUMachine *m) +static void pc_i440fx_0_11_machine_options(MachineClass *m) { pc_i440fx_0_12_machine_options(m); m->hw_version = "0.11"; @@ -945,7 +945,7 @@ DEFINE_PC_MACHINE(v0_11, "pc-0.11", pc_init_pci_no_kvmclock, .value = "0.10",\ }, -static void pc_i440fx_0_10_machine_options(QEMUMachine *m) +static void pc_i440fx_0_10_machine_options(MachineClass *m) { pc_i440fx_0_11_machine_options(m); m->hw_version = "0.10"; @@ -956,7 +956,7 @@ DEFINE_PC_MACHINE(v0_10, "pc-0.10", pc_init_pci_no_kvmclock, pc_i440fx_0_10_machine_options); -static void isapc_machine_options(QEMUMachine *m) +static void isapc_machine_options(MachineClass *m) { pc_common_machine_options(m); m->desc = "ISA-only PC"; @@ -968,7 +968,7 @@ DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa, #ifdef CONFIG_XEN -static void xenfv_machine_options(QEMUMachine *m) +static void xenfv_machine_options(MachineClass *m) { pc_common_machine_options(m); m->desc = "Xen Fully-virtualized PC"; diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index dcd728cc07..6a9fe58500 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -414,7 +414,7 @@ static void pc_q35_init_1_4(MachineState *machine) pc_q35_init(machine); } -static void pc_q35_machine_options(QEMUMachine *m) +static void pc_q35_machine_options(MachineClass *m) { pc_default_machine_options(m); m->family = "pc_q35"; @@ -423,7 +423,7 @@ static void pc_q35_machine_options(QEMUMachine *m) m->units_per_default_bus = 1; } -static void pc_q35_2_4_machine_options(QEMUMachine *m) +static void pc_q35_2_4_machine_options(MachineClass *m) { pc_q35_machine_options(m); m->default_machine_opts = "firmware=bios-256k.bin"; @@ -435,7 +435,7 @@ DEFINE_PC_MACHINE(v2_4, "pc-q35-2.4", pc_q35_init, pc_q35_2_4_machine_options); -static void pc_q35_2_3_machine_options(QEMUMachine *m) +static void pc_q35_2_3_machine_options(MachineClass *m) { pc_q35_2_4_machine_options(m); m->alias = NULL; @@ -446,7 +446,7 @@ DEFINE_PC_MACHINE(v2_3, "pc-q35-2.3", pc_q35_init_2_3, pc_q35_2_3_machine_options); -static void pc_q35_2_2_machine_options(QEMUMachine *m) +static void pc_q35_2_2_machine_options(MachineClass *m) { pc_q35_2_3_machine_options(m); SET_MACHINE_COMPAT(m, PC_COMPAT_2_2); @@ -456,7 +456,7 @@ DEFINE_PC_MACHINE(v2_2, "pc-q35-2.2", pc_q35_init_2_2, pc_q35_2_2_machine_options); -static void pc_q35_2_1_machine_options(QEMUMachine *m) +static void pc_q35_2_1_machine_options(MachineClass *m) { pc_q35_2_2_machine_options(m); m->default_display = NULL; @@ -467,7 +467,7 @@ DEFINE_PC_MACHINE(v2_1, "pc-q35-2.1", pc_q35_init_2_1, pc_q35_2_1_machine_options); -static void pc_q35_2_0_machine_options(QEMUMachine *m) +static void pc_q35_2_0_machine_options(MachineClass *m) { pc_q35_2_1_machine_options(m); SET_MACHINE_COMPAT(m, PC_COMPAT_2_0); @@ -477,7 +477,7 @@ DEFINE_PC_MACHINE(v2_0, "pc-q35-2.0", pc_q35_init_2_0, pc_q35_2_0_machine_options); -static void pc_q35_1_7_machine_options(QEMUMachine *m) +static void pc_q35_1_7_machine_options(MachineClass *m) { pc_q35_2_0_machine_options(m); m->default_machine_opts = NULL; @@ -488,7 +488,7 @@ DEFINE_PC_MACHINE(v1_7, "pc-q35-1.7", pc_q35_init_1_7, pc_q35_1_7_machine_options); -static void pc_q35_1_6_machine_options(QEMUMachine *m) +static void pc_q35_1_6_machine_options(MachineClass *m) { pc_q35_machine_options(m); SET_MACHINE_COMPAT(m, PC_COMPAT_1_6); @@ -498,7 +498,7 @@ DEFINE_PC_MACHINE(v1_6, "pc-q35-1.6", pc_q35_init_1_6, pc_q35_1_6_machine_options); -static void pc_q35_1_5_machine_options(QEMUMachine *m) +static void pc_q35_1_5_machine_options(MachineClass *m) { pc_q35_1_6_machine_options(m); SET_MACHINE_COMPAT(m, PC_COMPAT_1_5); @@ -508,7 +508,7 @@ DEFINE_PC_MACHINE(v1_5, "pc-q35-1.5", pc_q35_init_1_5, pc_q35_1_5_machine_options); -static void pc_q35_1_4_machine_options(QEMUMachine *m) +static void pc_q35_1_4_machine_options(MachineClass *m) { pc_q35_1_5_machine_options(m); m->hot_add_cpu = NULL; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index c4f080878d..f3bf500629 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -517,12 +517,12 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); .value = stringify(0),\ }, -static inline void pc_common_machine_options(QEMUMachine *m) +static inline void pc_common_machine_options(MachineClass *m) { m->default_boot_order = "cad"; } -static inline void pc_default_machine_options(QEMUMachine *m) +static inline void pc_default_machine_options(MachineClass *m) { pc_common_machine_options(m); m->hot_add_cpu = pc_hot_add_cpu; @@ -530,13 +530,21 @@ static inline void pc_default_machine_options(QEMUMachine *m) } #define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \ + static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \ + { \ + MachineClass *mc = MACHINE_CLASS(oc); \ + optsfn(mc); \ + mc->name = namestr; \ + mc->init = initfn; \ + } \ + static const TypeInfo pc_machine_type_##suffix = { \ + .name = namestr TYPE_MACHINE_SUFFIX, \ + .parent = TYPE_PC_MACHINE, \ + .class_init = pc_machine_##suffix##_class_init, \ + }; \ static void pc_machine_init_##suffix(void) \ { \ - static QEMUMachine m = { }; \ - optsfn(&m); \ - m.name = namestr; \ - m.init = initfn; \ - qemu_register_pc_machine(&m); \ + type_register(&pc_machine_type_##suffix); \ } \ machine_init(pc_machine_init_##suffix) -- cgit v1.2.3 From d644b11657ae047d50d8ea9ce285ecd6dae04ca2 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 15 May 2015 14:18:57 -0300 Subject: pc: Remove qemu_register_pc_machine() function The helper is not needed anymore, as the PC machine classes are registered using QOM directly. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc.c | 45 --------------------------------------------- include/hw/i386/pc.h | 2 -- 2 files changed, 47 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 769eb25048..aeed45d583 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1543,51 +1543,6 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name) } } -static void pc_generic_machine_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - QEMUMachine *qm = data; - - mc->family = qm->family; - mc->name = qm->name; - mc->alias = qm->alias; - mc->desc = qm->desc; - mc->init = qm->init; - mc->reset = qm->reset; - 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; - mc->use_virtcon = qm->use_virtcon; - mc->use_sclp = qm->use_sclp; - mc->no_floppy = qm->no_floppy; - mc->no_cdrom = qm->no_cdrom; - mc->no_sdcard = qm->no_sdcard; - mc->is_default = qm->is_default; - mc->default_machine_opts = qm->default_machine_opts; - mc->default_boot_order = qm->default_boot_order; - mc->default_display = qm->default_display; - mc->compat_props = qm->compat_props; - mc->hw_version = qm->hw_version; -} - -void qemu_register_pc_machine(QEMUMachine *m) -{ - char *name = g_strconcat(m->name, TYPE_MACHINE_SUFFIX, NULL); - TypeInfo ti = { - .name = name, - .parent = TYPE_PC_MACHINE, - .class_init = pc_generic_machine_class_init, - .class_data = (void *)m, - }; - - type_register(&ti); - g_free(name); -} - static void pc_dimm_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index f3bf500629..0510aeac89 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -73,8 +73,6 @@ typedef struct PCMachineClass PCMachineClass; #define PC_MACHINE_CLASS(klass) \ OBJECT_CLASS_CHECK(PCMachineClass, (klass), TYPE_PC_MACHINE) -void qemu_register_pc_machine(QEMUMachine *m); - /* PC-style peripherals (also used by other machines). */ typedef struct PcPciInfo { -- cgit v1.2.3 From d48f4fa69eb3efb03a2efe2e4606a97a17cf222f Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 15 May 2015 14:18:58 -0300 Subject: machine: Remove unused fields from QEMUMachine This removes the following fields from QEMUMachine: family, alias, reset, hot_add_cpu, units_per_default_bus, no_serial, no_parallel, use_virtcon, use_sclp, no_floppy, no_cdrom, default_display, compat_props, and hw_version. The only users of those fields were already converted to use QOM and MachineClass directly, so they are not needed anymore. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/boards.h | 15 +-------------- vl.c | 15 --------------- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/include/hw/boards.h b/include/hw/boards.h index 1f118811a2..ff79797ce4 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -19,31 +19,18 @@ typedef void QEMUMachineHotAddCPUFunc(const int64_t id, Error **errp); typedef int QEMUMachineGetKvmtypeFunc(const char *arg); struct QEMUMachine { - const char *family; /* NULL iff @name identifies a standalone machtype */ const char *name; - const char *alias; const char *desc; QEMUMachineInitFunc *init; - QEMUMachineResetFunc *reset; - 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, - use_virtcon:1, - use_sclp:1, - no_floppy:1, - no_cdrom:1, + unsigned int no_sdcard:1, has_dynamic_sysbus:1; int is_default; const char *default_machine_opts; const char *default_boot_order; - const char *default_display; - GlobalProperty *compat_props; - const char *hw_version; }; void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, diff --git a/vl.c b/vl.c index 26b1e7e28c..1d4c0890f2 100644 --- a/vl.c +++ b/vl.c @@ -1314,32 +1314,17 @@ static void machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); QEMUMachine *qm = data; - - mc->family = qm->family; mc->name = qm->name; - mc->alias = qm->alias; mc->desc = qm->desc; mc->init = qm->init; - mc->reset = qm->reset; - 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; - mc->use_virtcon = qm->use_virtcon; - mc->use_sclp = qm->use_sclp; - mc->no_floppy = qm->no_floppy; - mc->no_cdrom = qm->no_cdrom; mc->no_sdcard = qm->no_sdcard; mc->has_dynamic_sysbus = qm->has_dynamic_sysbus; mc->is_default = qm->is_default; mc->default_machine_opts = qm->default_machine_opts; mc->default_boot_order = qm->default_boot_order; - mc->default_display = qm->default_display; - mc->compat_props = qm->compat_props; - mc->hw_version = qm->hw_version; } int qemu_register_machine(QEMUMachine *m) -- cgit v1.2.3 From 72d164aa73b7c8d22a63b8ee789f97e4a8d2aa5c Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 15 May 2015 14:18:59 -0300 Subject: piix: Add kvmclock_enabled, pci_enabled globals This looks like a step backwards, but it will allow pc-0.1[0123] and isapc to follow the same compat+init pattern used by the other machine-types, allowing us to generate all init function using the same macro later. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 052fca26ef..cdc0443937 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -59,6 +59,7 @@ static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; +static bool pci_enabled = true; static bool has_acpi_build = true; static bool rsdp_in_ram = true; static int legacy_acpi_table_size; @@ -71,11 +72,10 @@ static bool smbios_uuid_encoded = true; */ static bool gigabyte_align = true; static bool has_reserved_memory = true; +static bool kvmclock_enabled = true; /* PC hardware initialisation */ -static void pc_init1(MachineState *machine, - int pci_enabled, - int kvmclock_enabled) +static void pc_init1(MachineState *machine) { PCMachineState *pc_machine = PC_MACHINE(machine); MemoryRegion *system_memory = get_system_memory(); @@ -307,7 +307,7 @@ static void pc_init1(MachineState *machine, static void pc_init_pci(MachineState *machine) { - pc_init1(machine, 1, 1); + pc_init1(machine); } static void pc_compat_2_3(MachineState *machine) @@ -430,6 +430,13 @@ static void pc_init_pci_2_2(MachineState *machine) pc_init_pci(machine); } +/* PC compat function for pc-0.10 to pc-0.13 */ +static void pc_compat_0_13(MachineState *machine) +{ + pc_compat_1_2(machine); + kvmclock_enabled = false; +} + static void pc_init_pci_2_1(MachineState *machine) { pc_compat_2_1(machine); @@ -482,12 +489,13 @@ static void pc_init_pci_1_2(MachineState *machine) /* PC init function for pc-0.10 to pc-0.13 */ static void pc_init_pci_no_kvmclock(MachineState *machine) { - pc_compat_1_2(machine); - pc_init1(machine, 1, 0); + pc_compat_0_13(machine); + pc_init_pci(machine); } static void pc_init_isa(MachineState *machine) { + pci_enabled = false; has_acpi_build = false; smbios_defaults = false; gigabyte_align = false; @@ -500,7 +508,7 @@ static void pc_init_isa(MachineState *machine) } x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, 1 << KVM_FEATURE_PV_EOI); enable_compat_apic_id_mode(); - pc_init1(machine, 0, 1); + pc_init1(machine); } #ifdef CONFIG_XEN -- cgit v1.2.3 From 211b5b1d0a31f2f7593d6858a0b10487fb7b7fac Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 15 May 2015 14:19:00 -0300 Subject: piix: Eliminate pc_init_pci() The function is not needed anymore, we can simply call pc_init1() directly. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index cdc0443937..01f938f83d 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -305,11 +305,6 @@ static void pc_init1(MachineState *machine) } } -static void pc_init_pci(MachineState *machine) -{ - pc_init1(machine); -} - static void pc_compat_2_3(MachineState *machine) { } @@ -421,13 +416,13 @@ static void pc_compat_1_2(MachineState *machine) static void pc_init_pci_2_3(MachineState *machine) { pc_compat_2_3(machine); - pc_init_pci(machine); + pc_init1(machine); } static void pc_init_pci_2_2(MachineState *machine) { pc_compat_2_2(machine); - pc_init_pci(machine); + pc_init1(machine); } /* PC compat function for pc-0.10 to pc-0.13 */ @@ -440,57 +435,57 @@ static void pc_compat_0_13(MachineState *machine) static void pc_init_pci_2_1(MachineState *machine) { pc_compat_2_1(machine); - pc_init_pci(machine); + pc_init1(machine); } static void pc_init_pci_2_0(MachineState *machine) { pc_compat_2_0(machine); - pc_init_pci(machine); + pc_init1(machine); } static void pc_init_pci_1_7(MachineState *machine) { pc_compat_1_7(machine); - pc_init_pci(machine); + pc_init1(machine); } static void pc_init_pci_1_6(MachineState *machine) { pc_compat_1_6(machine); - pc_init_pci(machine); + pc_init1(machine); } static void pc_init_pci_1_5(MachineState *machine) { pc_compat_1_5(machine); - pc_init_pci(machine); + pc_init1(machine); } static void pc_init_pci_1_4(MachineState *machine) { pc_compat_1_4(machine); - pc_init_pci(machine); + pc_init1(machine); } static void pc_init_pci_1_3(MachineState *machine) { pc_compat_1_3(machine); - pc_init_pci(machine); + pc_init1(machine); } /* PC machine init function for pc-0.14 to pc-1.2 */ static void pc_init_pci_1_2(MachineState *machine) { pc_compat_1_2(machine); - pc_init_pci(machine); + pc_init1(machine); } /* PC init function for pc-0.10 to pc-0.13 */ static void pc_init_pci_no_kvmclock(MachineState *machine) { pc_compat_0_13(machine); - pc_init_pci(machine); + pc_init1(machine); } static void pc_init_isa(MachineState *machine) @@ -516,7 +511,7 @@ static void pc_xen_hvm_init(MachineState *machine) { PCIBus *bus; - pc_init_pci(machine); + pc_init1(machine); bus = pci_find_primary_bus(); if (bus != NULL) { @@ -543,7 +538,7 @@ static void pc_i440fx_2_4_machine_options(MachineClass *m) m->is_default = 1; } -DEFINE_PC_MACHINE(v2_4, "pc-i440fx-2.4", pc_init_pci, +DEFINE_PC_MACHINE(v2_4, "pc-i440fx-2.4", pc_init1, pc_i440fx_2_4_machine_options) -- cgit v1.2.3 From 99fbeafee8b568e796863980365080abdb8d675e Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 15 May 2015 14:19:01 -0300 Subject: pc: Generate init functions with a macro All pc-i440fx and pc-q35 init functions simply call the corresponding compat function and then call the main init function. Use a macro to generate that code. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 154 +++++++++++++++++------------------------------------- hw/i386/pc_q35.c | 92 ++++++++++---------------------- 2 files changed, 76 insertions(+), 170 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 01f938f83d..e77486c62c 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -413,18 +413,6 @@ static void pc_compat_1_2(MachineState *machine) x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, 1 << KVM_FEATURE_PV_EOI); } -static void pc_init_pci_2_3(MachineState *machine) -{ - pc_compat_2_3(machine); - pc_init1(machine); -} - -static void pc_init_pci_2_2(MachineState *machine) -{ - pc_compat_2_2(machine); - pc_init1(machine); -} - /* PC compat function for pc-0.10 to pc-0.13 */ static void pc_compat_0_13(MachineState *machine) { @@ -432,62 +420,6 @@ static void pc_compat_0_13(MachineState *machine) kvmclock_enabled = false; } -static void pc_init_pci_2_1(MachineState *machine) -{ - pc_compat_2_1(machine); - pc_init1(machine); -} - -static void pc_init_pci_2_0(MachineState *machine) -{ - pc_compat_2_0(machine); - pc_init1(machine); -} - -static void pc_init_pci_1_7(MachineState *machine) -{ - pc_compat_1_7(machine); - pc_init1(machine); -} - -static void pc_init_pci_1_6(MachineState *machine) -{ - pc_compat_1_6(machine); - pc_init1(machine); -} - -static void pc_init_pci_1_5(MachineState *machine) -{ - pc_compat_1_5(machine); - pc_init1(machine); -} - -static void pc_init_pci_1_4(MachineState *machine) -{ - pc_compat_1_4(machine); - pc_init1(machine); -} - -static void pc_init_pci_1_3(MachineState *machine) -{ - pc_compat_1_3(machine); - pc_init1(machine); -} - -/* PC machine init function for pc-0.14 to pc-1.2 */ -static void pc_init_pci_1_2(MachineState *machine) -{ - pc_compat_1_2(machine); - pc_init1(machine); -} - -/* PC init function for pc-0.10 to pc-0.13 */ -static void pc_init_pci_no_kvmclock(MachineState *machine) -{ - pc_compat_0_13(machine); - pc_init1(machine); -} - static void pc_init_isa(MachineState *machine) { pci_enabled = false; @@ -520,6 +452,16 @@ static void pc_xen_hvm_init(MachineState *machine) } #endif +#define DEFINE_I440FX_MACHINE(suffix, name, compatfn, optionfn) \ + static void pc_init_##suffix(MachineState *machine) \ + { \ + void (*compat)(MachineState *m) = (compatfn); \ + if (compat) { \ + compat(machine); \ + } \ + pc_init1(machine); \ + } \ + DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn) static void pc_i440fx_machine_options(MachineClass *m) { @@ -538,8 +480,8 @@ static void pc_i440fx_2_4_machine_options(MachineClass *m) m->is_default = 1; } -DEFINE_PC_MACHINE(v2_4, "pc-i440fx-2.4", pc_init1, - pc_i440fx_2_4_machine_options) +DEFINE_I440FX_MACHINE(v2_4, "pc-i440fx-2.4", NULL, + pc_i440fx_2_4_machine_options) static void pc_i440fx_2_3_machine_options(MachineClass *m) @@ -550,8 +492,8 @@ static void pc_i440fx_2_3_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_2_3); } -DEFINE_PC_MACHINE(v2_3, "pc-i440fx-2.3", pc_init_pci_2_3, - pc_i440fx_2_3_machine_options); +DEFINE_I440FX_MACHINE(v2_3, "pc-i440fx-2.3", pc_compat_2_3, + pc_i440fx_2_3_machine_options); static void pc_i440fx_2_2_machine_options(MachineClass *m) @@ -560,8 +502,8 @@ static void pc_i440fx_2_2_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_2_2); } -DEFINE_PC_MACHINE(v2_2, "pc-i440fx-2.2", pc_init_pci_2_2, - pc_i440fx_2_2_machine_options); +DEFINE_I440FX_MACHINE(v2_2, "pc-i440fx-2.2", pc_compat_2_2, + pc_i440fx_2_2_machine_options); static void pc_i440fx_2_1_machine_options(MachineClass *m) @@ -571,8 +513,8 @@ static void pc_i440fx_2_1_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_2_1); } -DEFINE_PC_MACHINE(v2_1, "pc-i440fx-2.1", pc_init_pci_2_1, - pc_i440fx_2_1_machine_options); +DEFINE_I440FX_MACHINE(v2_1, "pc-i440fx-2.1", pc_compat_2_1, + pc_i440fx_2_1_machine_options); @@ -582,8 +524,8 @@ static void pc_i440fx_2_0_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_2_0); } -DEFINE_PC_MACHINE(v2_0, "pc-i440fx-2.0", pc_init_pci_2_0, - pc_i440fx_2_0_machine_options); +DEFINE_I440FX_MACHINE(v2_0, "pc-i440fx-2.0", pc_compat_2_0, + pc_i440fx_2_0_machine_options); static void pc_i440fx_1_7_machine_options(MachineClass *m) @@ -593,8 +535,8 @@ static void pc_i440fx_1_7_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_1_7); } -DEFINE_PC_MACHINE(v1_7, "pc-i440fx-1.7", pc_init_pci_1_7, - pc_i440fx_1_7_machine_options); +DEFINE_I440FX_MACHINE(v1_7, "pc-i440fx-1.7", pc_compat_1_7, + pc_i440fx_1_7_machine_options); static void pc_i440fx_1_6_machine_options(MachineClass *m) @@ -603,8 +545,8 @@ static void pc_i440fx_1_6_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_1_6); } -DEFINE_PC_MACHINE(v1_6, "pc-i440fx-1.6", pc_init_pci_1_6, - pc_i440fx_1_6_machine_options); +DEFINE_I440FX_MACHINE(v1_6, "pc-i440fx-1.6", pc_compat_1_6, + pc_i440fx_1_6_machine_options); static void pc_i440fx_1_5_machine_options(MachineClass *m) @@ -613,8 +555,8 @@ static void pc_i440fx_1_5_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_1_5); } -DEFINE_PC_MACHINE(v1_5, "pc-i440fx-1.5", pc_init_pci_1_5, - pc_i440fx_1_5_machine_options); +DEFINE_I440FX_MACHINE(v1_5, "pc-i440fx-1.5", pc_compat_1_5, + pc_i440fx_1_5_machine_options); static void pc_i440fx_1_4_machine_options(MachineClass *m) @@ -624,8 +566,8 @@ static void pc_i440fx_1_4_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_1_4); } -DEFINE_PC_MACHINE(v1_4, "pc-i440fx-1.4", pc_init_pci_1_4, - pc_i440fx_1_4_machine_options); +DEFINE_I440FX_MACHINE(v1_4, "pc-i440fx-1.4", pc_compat_1_4, + pc_i440fx_1_4_machine_options); #define PC_COMPAT_1_3 \ @@ -655,8 +597,8 @@ static void pc_i440fx_1_3_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_1_3); } -DEFINE_PC_MACHINE(v1_3, "pc-1.3", pc_init_pci_1_3, - pc_i440fx_1_3_machine_options); +DEFINE_I440FX_MACHINE(v1_3, "pc-1.3", pc_compat_1_3, + pc_i440fx_1_3_machine_options); #define PC_COMPAT_1_2 \ @@ -693,8 +635,8 @@ static void pc_i440fx_1_2_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_1_2); } -DEFINE_PC_MACHINE(v1_2, "pc-1.2", pc_init_pci_1_2, - pc_i440fx_1_2_machine_options); +DEFINE_I440FX_MACHINE(v1_2, "pc-1.2", pc_compat_1_2, + pc_i440fx_1_2_machine_options); #define PC_COMPAT_1_1 \ @@ -735,8 +677,8 @@ static void pc_i440fx_1_1_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_1_1); } -DEFINE_PC_MACHINE(v1_1, "pc-1.1", pc_init_pci_1_2, - pc_i440fx_1_1_machine_options); +DEFINE_I440FX_MACHINE(v1_1, "pc-1.1", pc_compat_1_2, + pc_i440fx_1_1_machine_options); #define PC_COMPAT_1_0 \ @@ -766,8 +708,8 @@ static void pc_i440fx_1_0_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_1_0); } -DEFINE_PC_MACHINE(v1_0, "pc-1.0", pc_init_pci_1_2, - pc_i440fx_1_0_machine_options); +DEFINE_I440FX_MACHINE(v1_0, "pc-1.0", pc_compat_1_2, + pc_i440fx_1_0_machine_options); #define PC_COMPAT_0_15 \ @@ -780,8 +722,8 @@ static void pc_i440fx_0_15_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_0_15); } -DEFINE_PC_MACHINE(v0_15, "pc-0.15", pc_init_pci_1_2, - pc_i440fx_0_15_machine_options); +DEFINE_I440FX_MACHINE(v0_15, "pc-0.15", pc_compat_1_2, + pc_i440fx_0_15_machine_options); #define PC_COMPAT_0_14 \ @@ -819,8 +761,8 @@ static void pc_i440fx_0_14_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_0_14); } -DEFINE_PC_MACHINE(v0_14, "pc-0.14", pc_init_pci_1_2, - pc_i440fx_0_14_machine_options); +DEFINE_I440FX_MACHINE(v0_14, "pc-0.14", pc_compat_1_2, + pc_i440fx_0_14_machine_options); #define PC_COMPAT_0_13 \ @@ -854,8 +796,8 @@ static void pc_i440fx_0_13_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_0_13); } -DEFINE_PC_MACHINE(v0_13, "pc-0.13", pc_init_pci_no_kvmclock, - pc_i440fx_0_13_machine_options); +DEFINE_I440FX_MACHINE(v0_13, "pc-0.13", pc_compat_0_13, + pc_i440fx_0_13_machine_options); #define PC_COMPAT_0_12 \ @@ -889,8 +831,8 @@ static void pc_i440fx_0_12_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_0_12); } -DEFINE_PC_MACHINE(v0_12, "pc-0.12", pc_init_pci_no_kvmclock, - pc_i440fx_0_12_machine_options); +DEFINE_I440FX_MACHINE(v0_12, "pc-0.12", pc_compat_0_13, + pc_i440fx_0_12_machine_options); #define PC_COMPAT_0_11 \ @@ -920,8 +862,8 @@ static void pc_i440fx_0_11_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_0_11); } -DEFINE_PC_MACHINE(v0_11, "pc-0.11", pc_init_pci_no_kvmclock, - pc_i440fx_0_11_machine_options); +DEFINE_I440FX_MACHINE(v0_11, "pc-0.11", pc_compat_0_13, + pc_i440fx_0_11_machine_options); #define PC_COMPAT_0_10 \ @@ -955,8 +897,8 @@ static void pc_i440fx_0_10_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_0_10); } -DEFINE_PC_MACHINE(v0_10, "pc-0.10", pc_init_pci_no_kvmclock, - pc_i440fx_0_10_machine_options); +DEFINE_I440FX_MACHINE(v0_10, "pc-0.10", pc_compat_0_13, + pc_i440fx_0_10_machine_options); static void isapc_machine_options(MachineClass *m) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 6a9fe58500..68b4867d31 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -366,53 +366,17 @@ static void pc_compat_1_4(MachineState *machine) x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ); } -static void pc_q35_init_2_3(MachineState *machine) -{ - pc_compat_2_3(machine); - pc_q35_init(machine); -} - -static void pc_q35_init_2_2(MachineState *machine) -{ - pc_compat_2_2(machine); - pc_q35_init(machine); -} - -static void pc_q35_init_2_1(MachineState *machine) -{ - pc_compat_2_1(machine); - pc_q35_init(machine); -} - -static void pc_q35_init_2_0(MachineState *machine) -{ - pc_compat_2_0(machine); - pc_q35_init(machine); -} +#define DEFINE_Q35_MACHINE(suffix, name, compatfn, optionfn) \ + static void pc_init_##suffix(MachineState *machine) \ + { \ + void (*compat)(MachineState *m) = (compatfn); \ + if (compat) { \ + compat(machine); \ + } \ + pc_q35_init(machine); \ + } \ + DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn) -static void pc_q35_init_1_7(MachineState *machine) -{ - pc_compat_1_7(machine); - pc_q35_init(machine); -} - -static void pc_q35_init_1_6(MachineState *machine) -{ - pc_compat_1_6(machine); - pc_q35_init(machine); -} - -static void pc_q35_init_1_5(MachineState *machine) -{ - pc_compat_1_5(machine); - pc_q35_init(machine); -} - -static void pc_q35_init_1_4(MachineState *machine) -{ - pc_compat_1_4(machine); - pc_q35_init(machine); -} static void pc_q35_machine_options(MachineClass *m) { @@ -431,8 +395,8 @@ static void pc_q35_2_4_machine_options(MachineClass *m) m->alias = "q35"; } -DEFINE_PC_MACHINE(v2_4, "pc-q35-2.4", pc_q35_init, - pc_q35_2_4_machine_options); +DEFINE_Q35_MACHINE(v2_4, "pc-q35-2.4", NULL, + pc_q35_2_4_machine_options); static void pc_q35_2_3_machine_options(MachineClass *m) @@ -442,8 +406,8 @@ static void pc_q35_2_3_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_2_3); } -DEFINE_PC_MACHINE(v2_3, "pc-q35-2.3", pc_q35_init_2_3, - pc_q35_2_3_machine_options); +DEFINE_Q35_MACHINE(v2_3, "pc-q35-2.3", pc_compat_2_3, + pc_q35_2_3_machine_options); static void pc_q35_2_2_machine_options(MachineClass *m) @@ -452,8 +416,8 @@ static void pc_q35_2_2_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_2_2); } -DEFINE_PC_MACHINE(v2_2, "pc-q35-2.2", pc_q35_init_2_2, - pc_q35_2_2_machine_options); +DEFINE_Q35_MACHINE(v2_2, "pc-q35-2.2", pc_compat_2_2, + pc_q35_2_2_machine_options); static void pc_q35_2_1_machine_options(MachineClass *m) @@ -463,8 +427,8 @@ static void pc_q35_2_1_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_2_1); } -DEFINE_PC_MACHINE(v2_1, "pc-q35-2.1", pc_q35_init_2_1, - pc_q35_2_1_machine_options); +DEFINE_Q35_MACHINE(v2_1, "pc-q35-2.1", pc_compat_2_1, + pc_q35_2_1_machine_options); static void pc_q35_2_0_machine_options(MachineClass *m) @@ -473,8 +437,8 @@ static void pc_q35_2_0_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_2_0); } -DEFINE_PC_MACHINE(v2_0, "pc-q35-2.0", pc_q35_init_2_0, - pc_q35_2_0_machine_options); +DEFINE_Q35_MACHINE(v2_0, "pc-q35-2.0", pc_compat_2_0, + pc_q35_2_0_machine_options); static void pc_q35_1_7_machine_options(MachineClass *m) @@ -484,8 +448,8 @@ static void pc_q35_1_7_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_1_7); } -DEFINE_PC_MACHINE(v1_7, "pc-q35-1.7", pc_q35_init_1_7, - pc_q35_1_7_machine_options); +DEFINE_Q35_MACHINE(v1_7, "pc-q35-1.7", pc_compat_1_7, + pc_q35_1_7_machine_options); static void pc_q35_1_6_machine_options(MachineClass *m) @@ -494,8 +458,8 @@ static void pc_q35_1_6_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_1_6); } -DEFINE_PC_MACHINE(v1_6, "pc-q35-1.6", pc_q35_init_1_6, - pc_q35_1_6_machine_options); +DEFINE_Q35_MACHINE(v1_6, "pc-q35-1.6", pc_compat_1_6, + pc_q35_1_6_machine_options); static void pc_q35_1_5_machine_options(MachineClass *m) @@ -504,8 +468,8 @@ static void pc_q35_1_5_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_1_5); } -DEFINE_PC_MACHINE(v1_5, "pc-q35-1.5", pc_q35_init_1_5, - pc_q35_1_5_machine_options); +DEFINE_Q35_MACHINE(v1_5, "pc-q35-1.5", pc_compat_1_5, + pc_q35_1_5_machine_options); static void pc_q35_1_4_machine_options(MachineClass *m) @@ -515,5 +479,5 @@ static void pc_q35_1_4_machine_options(MachineClass *m) SET_MACHINE_COMPAT(m, PC_COMPAT_1_4); } -DEFINE_PC_MACHINE(v1_4, "pc-q35-1.4", pc_q35_init_1_4, - pc_q35_1_4_machine_options); +DEFINE_Q35_MACHINE(v1_4, "pc-q35-1.4", pc_compat_1_4, + pc_q35_1_4_machine_options); -- cgit v1.2.3 From 2332333c9738b442fbbd5b83a1eaa6be656ab9b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Fri, 29 May 2015 21:57:32 +0200 Subject: pc: acpi: fix pvpanic for buggy guests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the old times, we always had pvpanic in ACPI and a _STA method told the guest not to use it. Automatic generation dropped the _STA method as the specification says that missing _STA means enabled and working. Some guests (Linux) had buggy drivers and this change made them unable to utilize pvpanic. A Linux patch is posted as well, but I think it's worth to make pvpanic useable on old guests at the price of three lines and few bytes of SSDT. The old _STA method was Method (_STA, 0, NotSerialized) { Store (PEST, Local0) If (LEqual (Local0, Zero)) { Return (Zero) } Else { Return (0x0F) }} Igor pointed out that we don't need to use a method to return a constant and that 0xB (don't show in UI) is the common definition now. Also, the device used to be PEVT. (PEVT as in "panic event"?) Signed-off-by: Radim Krčmář Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 3d19de68fc..283d02e7a7 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -733,7 +733,7 @@ build_ssdt(GArray *table_data, GArray *linker, if (misc->pvpanic_port) { scope = aml_scope("\\_SB.PCI0.ISA"); - dev = aml_device("PEVR"); + dev = aml_device("PEVT"); aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0001"))); crs = aml_resource_template(); @@ -748,6 +748,9 @@ build_ssdt(GArray *table_data, GArray *linker, aml_append(field, aml_named_field("PEPT", 8)); aml_append(dev, field); + /* device present, functioning, decoding, not shown in UI */ + aml_append(dev, aml_name_decl("_STA", aml_int(0xB))); + method = aml_method("RDPT", 0); aml_append(method, aml_store(aml_name("PEPT"), aml_local(0))); aml_append(method, aml_return(aml_local(0))); -- cgit v1.2.3 From 6b8f1020540c27246277377aa2c3331ad2bfb160 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 26 May 2015 16:34:47 +0200 Subject: virtio: move host_features Move host_features from the individual transport proxies into the virtio device. Transports may continue to add feature bits during device plugging. This should it make easier to offer different sets of host features for virtio-1/transitional support. Tested-by: Shannon Zhao Signed-off-by: Cornelia Huck Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/s390x/s390-virtio-bus.c | 18 ++---------------- hw/s390x/s390-virtio-bus.h | 1 - hw/s390x/virtio-ccw.c | 29 ++++++----------------------- hw/s390x/virtio-ccw.h | 4 ---- hw/virtio/virtio-bus.c | 18 +++++------------- hw/virtio/virtio-mmio.c | 22 +++------------------- hw/virtio/virtio-pci.c | 17 ++++------------- hw/virtio/virtio-pci.h | 1 - hw/virtio/virtio.c | 17 +++++++++-------- include/hw/virtio/virtio-bus.h | 1 - include/hw/virtio/virtio.h | 1 + 11 files changed, 30 insertions(+), 99 deletions(-) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 0e35ac970a..74e27e89b7 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -139,8 +139,6 @@ static void s390_virtio_device_init(VirtIOS390Device *dev, bus->dev_offs += dev_len; - dev->host_features = virtio_bus_get_vdev_features(&dev->bus, - dev->host_features); s390_virtio_device_sync(dev); s390_virtio_reset_idx(dev); if (dev->qdev.hotplugged) { @@ -433,7 +431,8 @@ void s390_virtio_device_sync(VirtIOS390Device *dev) cur_offs += num_vq * VIRTIO_VQCONFIG_LEN; /* Sync feature bitmap */ - address_space_stl_le(&address_space_memory, cur_offs, dev->host_features, + address_space_stl_le(&address_space_memory, cur_offs, + dev->vdev->host_features, MEMTXATTRS_UNSPECIFIED, NULL); dev->feat_offs = cur_offs + dev->feat_len; @@ -528,12 +527,6 @@ static void virtio_s390_notify(DeviceState *d, uint16_t vector) s390_virtio_irq(0, token); } -static unsigned virtio_s390_get_features(DeviceState *d) -{ - VirtIOS390Device *dev = to_virtio_s390_device(d); - return dev->host_features; -} - /**************** S390 Virtio Bus Device Descriptions *******************/ static void s390_virtio_net_class_init(ObjectClass *klass, void *data) @@ -626,16 +619,10 @@ static void s390_virtio_busdev_reset(DeviceState *dev) virtio_reset(_dev->vdev); } -static Property virtio_s390_properties[] = { - DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features), - DEFINE_PROP_END_OF_LIST(), -}; - static void virtio_s390_device_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->props = virtio_s390_properties; dc->realize = s390_virtio_busdev_realize; dc->bus_type = TYPE_S390_VIRTIO_BUS; dc->reset = s390_virtio_busdev_reset; @@ -733,7 +720,6 @@ static void virtio_s390_bus_class_init(ObjectClass *klass, void *data) BusClass *bus_class = BUS_CLASS(klass); bus_class->max_dev = 1; k->notify = virtio_s390_notify; - k->get_features = virtio_s390_get_features; } static const TypeInfo virtio_s390_bus_info = { diff --git a/hw/s390x/s390-virtio-bus.h b/hw/s390x/s390-virtio-bus.h index 96b1890b4c..7ad295e68f 100644 --- a/hw/s390x/s390-virtio-bus.h +++ b/hw/s390x/s390-virtio-bus.h @@ -92,7 +92,6 @@ struct VirtIOS390Device { ram_addr_t feat_offs; uint8_t feat_len; VirtIODevice *vdev; - uint32_t host_features; VirtioBusState bus; }; diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index f5f327c173..6e9f8c164f 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -381,8 +381,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) + sizeof(features.features), MEMTXATTRS_UNSPECIFIED, NULL); - if (features.index < ARRAY_SIZE(dev->host_features)) { - features.features = dev->host_features[features.index]; + if (features.index == 0) { + features.features = vdev->host_features; } else { /* Return zeroes if the guest supports more feature bits. */ features.features = 0; @@ -417,7 +417,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) ccw.cda, MEMTXATTRS_UNSPECIFIED, NULL); - if (features.index < ARRAY_SIZE(dev->host_features)) { + if (features.index == 0) { virtio_set_features(vdev, features.features); } else { /* @@ -1071,14 +1071,6 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector) } } -static unsigned virtio_ccw_get_features(DeviceState *d) -{ - VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); - - /* Only the first 32 feature bits are used. */ - return dev->host_features[0]; -} - static void virtio_ccw_reset(DeviceState *d) { VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); @@ -1390,14 +1382,12 @@ static void virtio_ccw_device_plugged(DeviceState *d) { VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); SubchDev *sch = dev->sch; + VirtIODevice *vdev = virtio_ccw_get_vdev(sch); sch->id.cu_model = virtio_bus_get_vdev_id(&dev->bus); - /* Only the first 32 feature bits are used. */ - virtio_add_feature(&dev->host_features[0], VIRTIO_F_NOTIFY_ON_EMPTY); - virtio_add_feature(&dev->host_features[0], VIRTIO_F_BAD_FEATURE); - dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus, - dev->host_features[0]); + virtio_add_feature(&vdev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY); + virtio_add_feature(&vdev->host_features, VIRTIO_F_BAD_FEATURE); css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, d->hotplugged, 1); @@ -1648,16 +1638,10 @@ static void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev, object_unparent(OBJECT(dev)); } -static Property virtio_ccw_properties[] = { - DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]), - DEFINE_PROP_END_OF_LIST(), -}; - static void virtio_ccw_device_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->props = virtio_ccw_properties; dc->realize = virtio_ccw_busdev_realize; dc->exit = virtio_ccw_busdev_exit; dc->bus_type = TYPE_VIRTUAL_CSS_BUS; @@ -1722,7 +1706,6 @@ static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data) bus_class->max_dev = 1; k->notify = virtio_ccw_notify; - k->get_features = virtio_ccw_get_features; k->vmstate_change = virtio_ccw_vmstate_change; k->query_guest_notifiers = virtio_ccw_query_guest_notifiers; k->set_host_notifier = virtio_ccw_set_host_notifier; diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h index 4fceda735a..ad3af7626a 100644 --- a/hw/s390x/virtio-ccw.h +++ b/hw/s390x/virtio-ccw.h @@ -68,9 +68,6 @@ typedef struct VirtIOCCWDeviceClass { int (*exit)(VirtioCcwDevice *dev); } VirtIOCCWDeviceClass; -/* Change here if we want to support more feature bits. */ -#define VIRTIO_CCW_FEATURE_SIZE 1 - /* Performance improves when virtqueue kick processing is decoupled from the * vcpu thread using ioeventfd for some devices. */ #define VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT 1 @@ -88,7 +85,6 @@ struct VirtioCcwDevice { DeviceState parent_obj; SubchDev *sch; char *bus_id; - uint32_t host_features[VIRTIO_CCW_FEATURE_SIZE]; VirtioBusState bus; bool ioeventfd_started; bool ioeventfd_disabled; diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c index be886e75af..fac452bd1d 100644 --- a/hw/virtio/virtio-bus.c +++ b/hw/virtio/virtio-bus.c @@ -44,12 +44,17 @@ int virtio_bus_device_plugged(VirtIODevice *vdev) BusState *qbus = BUS(qdev_get_parent_bus(qdev)); VirtioBusState *bus = VIRTIO_BUS(qbus); VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); + DPRINTF("%s: plug device.\n", qbus->name); if (klass->device_plugged != NULL) { klass->device_plugged(qbus->parent); } + /* Get the features of the plugged device. */ + assert(vdc->get_features != NULL); + vdev->host_features = vdc->get_features(vdev, vdev->host_features); return 0; } @@ -96,19 +101,6 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus) return vdev->config_len; } -/* Get the features of the plugged device. */ -uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus, - uint32_t requested_features) -{ - VirtIODevice *vdev = virtio_bus_get_device(bus); - VirtioDeviceClass *k; - - assert(vdev != NULL); - k = VIRTIO_DEVICE_GET_CLASS(vdev); - assert(k->get_features != NULL); - return k->get_features(vdev, requested_features); -} - /* Get bad features of the plugged device. */ uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus) { diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index 10123f34b2..1817a07845 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -80,7 +80,6 @@ typedef struct { SysBusDevice parent_obj; MemoryRegion iomem; qemu_irq irq; - uint32_t host_features; /* Guest accessible state needing migration and reset */ uint32_t host_features_sel; uint32_t guest_features_sel; @@ -147,7 +146,7 @@ static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size) if (proxy->host_features_sel) { return 0; } - return proxy->host_features; + return vdev->host_features; case VIRTIO_MMIO_QUEUENUMMAX: if (!virtio_queue_get_num(vdev, vdev->queue_sel)) { return 0; @@ -306,13 +305,6 @@ static void virtio_mmio_update_irq(DeviceState *opaque, uint16_t vector) qemu_set_irq(proxy->irq, level); } -static unsigned int virtio_mmio_get_features(DeviceState *opaque) -{ - VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque); - - return proxy->host_features; -} - static int virtio_mmio_load_config(DeviceState *opaque, QEMUFile *f) { VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque); @@ -348,10 +340,9 @@ static void virtio_mmio_reset(DeviceState *d) static void virtio_mmio_device_plugged(DeviceState *opaque) { VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque); + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - virtio_add_feature(&proxy->host_features, VIRTIO_F_NOTIFY_ON_EMPTY); - proxy->host_features = virtio_bus_get_vdev_features(&proxy->bus, - proxy->host_features); + virtio_add_feature(&vdev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY); } static void virtio_mmio_realizefn(DeviceState *d, Error **errp) @@ -367,16 +358,10 @@ static void virtio_mmio_realizefn(DeviceState *d, Error **errp) sysbus_init_mmio(sbd, &proxy->iomem); } -static Property virtio_mmio_properties[] = { - DEFINE_VIRTIO_COMMON_FEATURES(VirtIOMMIOProxy, host_features), - DEFINE_PROP_END_OF_LIST(), -}; - static void virtio_mmio_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->props = virtio_mmio_properties; dc->realize = virtio_mmio_realizefn; dc->reset = virtio_mmio_reset; set_bit(DEVICE_CATEGORY_MISC, dc->categories); @@ -399,7 +384,6 @@ static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data) k->notify = virtio_mmio_update_irq; k->save_config = virtio_mmio_save_config; k->load_config = virtio_mmio_load_config; - k->get_features = virtio_mmio_get_features; k->device_plugged = virtio_mmio_device_plugged; k->has_variable_vring_alignment = true; bus_class->max_dev = 1; diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index c931790dd7..8ea723106d 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -306,7 +306,7 @@ static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr) switch (addr) { case VIRTIO_PCI_HOST_FEATURES: - ret = proxy->host_features; + ret = vdev->host_features; break; case VIRTIO_PCI_GUEST_FEATURES: ret = vdev->guest_features; @@ -434,12 +434,6 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, } } -static unsigned virtio_pci_get_features(DeviceState *d) -{ - VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); - return proxy->host_features; -} - static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy, unsigned int queue_no, unsigned int vector, @@ -924,6 +918,7 @@ static void virtio_pci_device_plugged(DeviceState *d) VirtioBusState *bus = &proxy->bus; uint8_t *config; uint32_t size; + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); config = proxy->pci_dev.config; if (proxy->class_code) { @@ -958,10 +953,8 @@ static void virtio_pci_device_plugged(DeviceState *d) proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD; } - virtio_add_feature(&proxy->host_features, VIRTIO_F_NOTIFY_ON_EMPTY); - virtio_add_feature(&proxy->host_features, VIRTIO_F_BAD_FEATURE); - proxy->host_features = virtio_bus_get_vdev_features(bus, - proxy->host_features); + virtio_add_feature(&vdev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY); + virtio_add_feature(&vdev->host_features, VIRTIO_F_BAD_FEATURE); } static void virtio_pci_device_unplugged(DeviceState *d) @@ -999,7 +992,6 @@ static void virtio_pci_reset(DeviceState *qdev) static Property virtio_pci_properties[] = { DEFINE_PROP_BIT("virtio-pci-bus-master-bug-migration", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT, false), - DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), DEFINE_PROP_END_OF_LIST(), }; @@ -1469,7 +1461,6 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data) k->load_config = virtio_pci_load_config; k->save_queue = virtio_pci_save_queue; k->load_queue = virtio_pci_load_queue; - k->get_features = virtio_pci_get_features; k->query_guest_notifiers = virtio_pci_query_guest_notifiers; k->set_host_notifier = virtio_pci_set_host_notifier; k->set_guest_notifiers = virtio_pci_set_guest_notifiers; diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h index 3bac016999..de394687ef 100644 --- a/hw/virtio/virtio-pci.h +++ b/hw/virtio/virtio-pci.h @@ -91,7 +91,6 @@ struct VirtIOPCIProxy { uint32_t flags; uint32_t class_code; uint32_t nvectors; - uint32_t host_features; bool ioeventfd_disabled; bool ioeventfd_started; VirtIOIRQFD *vector_irqfd; diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 6985e76b64..96d9c6a199 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -970,13 +970,10 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) int virtio_set_features(VirtIODevice *vdev, uint32_t val) { - BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); - VirtioBusClass *vbusk = VIRTIO_BUS_GET_CLASS(qbus); VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); - uint32_t supported_features = vbusk->get_features(qbus->parent); - bool bad = (val & ~supported_features) != 0; + bool bad = (val & ~(vdev->host_features)) != 0; - val &= supported_features; + val &= vdev->host_features; if (k->set_features) { k->set_features(vdev, val); } @@ -990,7 +987,6 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) int32_t config_len; uint32_t num; uint32_t features; - uint32_t supported_features; BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); @@ -1016,9 +1012,8 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) qemu_get_be32s(f, &features); if (virtio_set_features(vdev, features) < 0) { - supported_features = k->get_features(qbus->parent); error_report("Features 0x%x unsupported. Allowed features: 0x%x", - features, supported_features); + features, vdev->host_features); return -1; } config_len = qemu_get_be32(f); @@ -1351,6 +1346,11 @@ static void virtio_device_unrealize(DeviceState *dev, Error **errp) vdev->bus_name = NULL; } +static Property virtio_properties[] = { + DEFINE_VIRTIO_COMMON_FEATURES(VirtIODevice, host_features), + DEFINE_PROP_END_OF_LIST(), +}; + static void virtio_device_class_init(ObjectClass *klass, void *data) { /* Set the default value here. */ @@ -1359,6 +1359,7 @@ static void virtio_device_class_init(ObjectClass *klass, void *data) dc->realize = virtio_device_realize; dc->unrealize = virtio_device_unrealize; dc->bus_type = TYPE_VIRTIO_BUS; + dc->props = virtio_properties; } static const TypeInfo virtio_device_info = { diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h index a4588ca4d9..d4ccdf27a3 100644 --- a/include/hw/virtio/virtio-bus.h +++ b/include/hw/virtio/virtio-bus.h @@ -47,7 +47,6 @@ typedef struct VirtioBusClass { int (*load_config)(DeviceState *d, QEMUFile *f); int (*load_queue)(DeviceState *d, int n, QEMUFile *f); int (*load_done)(DeviceState *d, QEMUFile *f); - unsigned (*get_features)(DeviceState *d); bool (*query_guest_notifiers)(DeviceState *d); int (*set_guest_notifiers)(DeviceState *d, int nvqs, bool assign); int (*set_host_notifier)(DeviceState *d, int n, bool assigned); diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index ba74765d0b..f1f9ca5b17 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -74,6 +74,7 @@ struct VirtIODevice uint8_t isr; uint16_t queue_sel; uint32_t guest_features; + uint32_t host_features; size_t config_len; void *config; uint16_t config_vector; -- cgit v1.2.3 From 13644819c5bf322ae4c2a415aca77d5dbde95fe8 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 29 May 2015 11:29:39 +0200 Subject: virtio-ccw: Don't advertise VIRTIO_F_BAD_FEATURE This was copied from virtio-pci, but it doesn't make much sense for ccw, as it doesn't have to handle the broken implementations this bit is supposed to deal with. Remove it. Signed-off-by: Cornelia Huck Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/s390x/virtio-ccw.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 6e9f8c164f..b7c07ef62e 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1387,7 +1387,6 @@ static void virtio_ccw_device_plugged(DeviceState *d) sch->id.cu_model = virtio_bus_get_vdev_id(&dev->bus); virtio_add_feature(&vdev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY); - virtio_add_feature(&vdev->host_features, VIRTIO_F_BAD_FEATURE); css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, d->hotplugged, 1); -- cgit v1.2.3 From cf34f533a161f8ced7322321d70ca00414d47473 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 29 May 2015 11:29:40 +0200 Subject: virtio: move VIRTIO_F_NOTIFY_ON_EMPTY into core Nearly all transports have been offering VIRTIO_F_NOTIFY_ON_EMPTY, s390-virtio being the exception. There's no reason why it shouldn't offer it as well, though (handling is done in core anyway), so let's move it to the common virtio features. While we're changing it anyway, fix the indentation for the DEFINE_VIRTIO_COMMON_FEATURES macro. Signed-off-by: Cornelia Huck Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/s390x/virtio-ccw.c | 3 --- hw/virtio/virtio-mmio.c | 10 ---------- hw/virtio/virtio-pci.c | 1 - include/hw/virtio/virtio.h | 10 ++++++---- 4 files changed, 6 insertions(+), 18 deletions(-) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index b7c07ef62e..e7722659b7 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1382,12 +1382,9 @@ static void virtio_ccw_device_plugged(DeviceState *d) { VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); SubchDev *sch = dev->sch; - VirtIODevice *vdev = virtio_ccw_get_vdev(sch); sch->id.cu_model = virtio_bus_get_vdev_id(&dev->bus); - virtio_add_feature(&vdev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY); - css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, d->hotplugged, 1); } diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index 1817a07845..3008b65aa9 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -336,15 +336,6 @@ static void virtio_mmio_reset(DeviceState *d) /* virtio-mmio device */ -/* This is called by virtio-bus just after the device is plugged. */ -static void virtio_mmio_device_plugged(DeviceState *opaque) -{ - VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque); - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - - virtio_add_feature(&vdev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY); -} - static void virtio_mmio_realizefn(DeviceState *d, Error **errp) { VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d); @@ -384,7 +375,6 @@ static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data) k->notify = virtio_mmio_update_irq; k->save_config = virtio_mmio_save_config; k->load_config = virtio_mmio_load_config; - k->device_plugged = virtio_mmio_device_plugged; k->has_variable_vring_alignment = true; bus_class->max_dev = 1; } diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 8ea723106d..8923ba86e0 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -953,7 +953,6 @@ static void virtio_pci_device_plugged(DeviceState *d) proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD; } - virtio_add_feature(&vdev->host_features, VIRTIO_F_NOTIFY_ON_EMPTY); virtio_add_feature(&vdev->host_features, VIRTIO_F_BAD_FEATURE); } diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index f1f9ca5b17..5244a3e016 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -194,10 +194,12 @@ typedef struct VirtIOSCSIConf VirtIOSCSIConf; typedef struct VirtIORNGConf VirtIORNGConf; #define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \ - DEFINE_PROP_BIT("indirect_desc", _state, _field, \ - VIRTIO_RING_F_INDIRECT_DESC, true), \ - DEFINE_PROP_BIT("event_idx", _state, _field, \ - VIRTIO_RING_F_EVENT_IDX, true) + DEFINE_PROP_BIT("indirect_desc", _state, _field, \ + VIRTIO_RING_F_INDIRECT_DESC, true), \ + DEFINE_PROP_BIT("event_idx", _state, _field, \ + VIRTIO_RING_F_EVENT_IDX, true), \ + DEFINE_PROP_BIT("notify_on_empty", _state, _field, \ + VIRTIO_F_NOTIFY_ON_EMPTY, true) hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n); -- cgit v1.2.3 From da51a335aa61ec0e45879d80f3c5e2ee4f87cd2f Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 29 May 2015 14:15:24 +0800 Subject: virtio-net: adding all queues in .realize() Instead of adding queues for multiqueue during feature set. This patch did this in .realize(), this will help the following patches that count the number of virtqueues used in .device_plugged() callback. Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/virtio-net.c | 59 +++++++++++++++-------------------------------------- 1 file changed, 17 insertions(+), 42 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 3af6faf4c8..3edb1c4144 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1301,39 +1301,8 @@ static void virtio_net_tx_bh(void *opaque) static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue) { - VirtIODevice *vdev = VIRTIO_DEVICE(n); - int i, max = multiqueue ? n->max_queues : 1; - n->multiqueue = multiqueue; - for (i = 2; i < n->max_queues * 2 + 1; i++) { - virtio_del_queue(vdev, i); - } - - for (i = 1; i < max; i++) { - n->vqs[i].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx); - if (n->vqs[i].tx_timer) { - n->vqs[i].tx_vq = - virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer); - n->vqs[i].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, - virtio_net_tx_timer, - &n->vqs[i]); - } else { - n->vqs[i].tx_vq = - virtio_add_queue(vdev, 256, virtio_net_handle_tx_bh); - n->vqs[i].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[i]); - } - - n->vqs[i].tx_waiting = 0; - n->vqs[i].n = n; - } - - /* Note: Minux Guests (version 3.2.1) use ctrl vq but don't ack - * VIRTIO_NET_F_CTRL_VQ. Create ctrl vq unconditionally to avoid - * breaking them. - */ - n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl); - virtio_net_set_queues(n); } @@ -1594,9 +1563,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) return; } n->vqs = g_malloc0(sizeof(VirtIONetQueue) * n->max_queues); - n->vqs[0].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx); n->curr_queues = 1; - n->vqs[0].n = n; n->tx_timeout = n->net_conf.txtimer; if (n->net_conf.tx && strcmp(n->net_conf.tx, "timer") @@ -1607,16 +1574,24 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) error_report("Defaulting to \"bh\""); } - if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) { - n->vqs[0].tx_vq = virtio_add_queue(vdev, 256, - virtio_net_handle_tx_timer); - n->vqs[0].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, virtio_net_tx_timer, - &n->vqs[0]); - } else { - n->vqs[0].tx_vq = virtio_add_queue(vdev, 256, - virtio_net_handle_tx_bh); - n->vqs[0].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[0]); + for (i = 0; i < n->max_queues; i++) { + n->vqs[i].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx); + if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) { + n->vqs[i].tx_vq = + virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer); + n->vqs[i].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + virtio_net_tx_timer, + &n->vqs[i]); + } else { + n->vqs[i].tx_vq = + virtio_add_queue(vdev, 256, virtio_net_handle_tx_bh); + n->vqs[i].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[i]); + } + + n->vqs[i].tx_waiting = 0; + n->vqs[i].n = n; } + n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl); qemu_macaddr_default_if_unset(&n->nic_conf.macaddr); memcpy(&n->mac[0], &n->nic_conf.macaddr, sizeof(n->mac)); -- cgit v1.2.3 From e83980455c8c7eb066405de512be7c4bace3ac4d Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 29 May 2015 14:15:25 +0800 Subject: virtio: device_plugged() can fail This patch passes error pointer to transport specific device_plugged() callback. Through this way, device_plugged() can do some transport specific check and fail. This will be uesd by following patches that check the number of virtqueues against the transport limitation. Cc: Cornelia Huck Cc: Christian Borntraeger Cc: Richard Henderson Cc: Alexander Graf Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/s390x/virtio-ccw.c | 2 +- hw/virtio/virtio-bus.c | 5 ++--- hw/virtio/virtio-pci.c | 2 +- hw/virtio/virtio.c | 7 ++++++- include/hw/virtio/virtio-bus.h | 4 ++-- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index e7722659b7..965b03ad9f 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1378,7 +1378,7 @@ static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f) } /* This is called by virtio-bus just after the device is plugged. */ -static void virtio_ccw_device_plugged(DeviceState *d) +static void virtio_ccw_device_plugged(DeviceState *d, Error **errp) { VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); SubchDev *sch = dev->sch; diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c index fac452bd1d..3926f7ee1e 100644 --- a/hw/virtio/virtio-bus.c +++ b/hw/virtio/virtio-bus.c @@ -38,7 +38,7 @@ do { printf("virtio_bus: " fmt , ## __VA_ARGS__); } while (0) #endif /* A VirtIODevice is being plugged */ -int virtio_bus_device_plugged(VirtIODevice *vdev) +void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp) { DeviceState *qdev = DEVICE(vdev); BusState *qbus = BUS(qdev_get_parent_bus(qdev)); @@ -49,13 +49,12 @@ int virtio_bus_device_plugged(VirtIODevice *vdev) DPRINTF("%s: plug device.\n", qbus->name); if (klass->device_plugged != NULL) { - klass->device_plugged(qbus->parent); + klass->device_plugged(qbus->parent, errp); } /* Get the features of the plugged device. */ assert(vdc->get_features != NULL); vdev->host_features = vdc->get_features(vdev, vdev->host_features); - return 0; } /* Reset the virtio_bus */ diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 8923ba86e0..0cc249cef8 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -912,7 +912,7 @@ static int virtio_pci_query_nvectors(DeviceState *d) } /* This is called by virtio-bus just after the device is plugged. */ -static void virtio_pci_device_plugged(DeviceState *d) +static void virtio_pci_device_plugged(DeviceState *d, Error **errp) { VirtIOPCIProxy *proxy = VIRTIO_PCI(d); VirtioBusState *bus = &proxy->bus; diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 96d9c6a199..b50cbef519 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1323,7 +1323,12 @@ static void virtio_device_realize(DeviceState *dev, Error **errp) return; } } - virtio_bus_device_plugged(vdev); + + virtio_bus_device_plugged(vdev, &err); + if (err != NULL) { + error_propagate(errp, err); + return; + } } static void virtio_device_unrealize(DeviceState *dev, Error **errp) diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h index d4ccdf27a3..8811415fa6 100644 --- a/include/hw/virtio/virtio-bus.h +++ b/include/hw/virtio/virtio-bus.h @@ -55,7 +55,7 @@ typedef struct VirtioBusClass { * transport independent init function. * This is called by virtio-bus just after the device is plugged. */ - void (*device_plugged)(DeviceState *d); + void (*device_plugged)(DeviceState *d, Error **errp); /* * transport independent exit function. * This is called by virtio-bus just before the device is unplugged. @@ -74,7 +74,7 @@ struct VirtioBusState { BusState parent_obj; }; -int virtio_bus_device_plugged(VirtIODevice *vdev); +void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp); void virtio_bus_reset(VirtioBusState *bus); void virtio_bus_device_unplugged(VirtIODevice *bus); /* Get the device id of the plugged device. */ -- cgit v1.2.3 From 8ad176aaed24535f535e0fdb03c538c23017535d Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 29 May 2015 14:15:26 +0800 Subject: virtio: introduce virtio_get_num_queues() This patch introduces virtio_get_num_queues() which iterates the vqs array and return the number of virtqueues used by device. Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio.c | 13 +++++++++++++ include/hw/virtio/virtio.h | 1 + 2 files changed, 14 insertions(+) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index b50cbef519..5602285635 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -746,6 +746,19 @@ int virtio_queue_get_num(VirtIODevice *vdev, int n) return vdev->vq[n].vring.num; } +int virtio_get_num_queues(VirtIODevice *vdev) +{ + int i; + + for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { + if (!virtio_queue_get_num(vdev, i)) { + break; + } + } + + return i; +} + int virtio_queue_get_id(VirtQueue *vq) { VirtIODevice *vdev = vq->vdev; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 5244a3e016..dd92fe4979 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -176,6 +176,7 @@ void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr); hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n); void virtio_queue_set_num(VirtIODevice *vdev, int n, int num); int virtio_queue_get_num(VirtIODevice *vdev, int n); +int virtio_get_num_queues(VirtIODevice *vdev); void virtio_queue_set_align(VirtIODevice *vdev, int n, int align); void virtio_queue_notify(VirtIODevice *vdev, int n); uint16_t virtio_queue_vector(VirtIODevice *vdev, int n); -- cgit v1.2.3 From 8dfbaa6ac450c4ec2646b1ca08a4017052a90c1d Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 29 May 2015 14:15:27 +0800 Subject: virtio-ccw: introduce ccw specific queue limit Cc: Alexander Graf Cc: Cornelia Huck Cc: Christian Borntraeger Cc: Richard Henderson Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/s390x/s390-virtio-ccw.c | 2 +- hw/s390x/virtio-ccw.c | 12 ++++++------ include/hw/s390x/s390_flic.h | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index afb539adea..8a565f657a 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -67,7 +67,7 @@ static int virtio_ccw_hcall_notify(const uint64_t *args) if (!sch || !css_subch_visible(sch)) { return -EINVAL; } - if (queue >= VIRTIO_PCI_QUEUE_MAX) { + if (queue >= VIRTIO_CCW_QUEUE_MAX) { return -EINVAL; } virtio_queue_notify(virtio_ccw_get_vdev(sch), queue); diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 965b03ad9f..60d60d6186 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -170,7 +170,7 @@ static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev) return; } vdev = virtio_bus_get_device(&dev->bus); - for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { + for (n = 0; n < VIRTIO_CCW_QUEUE_MAX; n++) { if (!virtio_queue_get_num(vdev, n)) { continue; } @@ -205,7 +205,7 @@ static void virtio_ccw_stop_ioeventfd(VirtioCcwDevice *dev) return; } vdev = virtio_bus_get_device(&dev->bus); - for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { + for (n = 0; n < VIRTIO_CCW_QUEUE_MAX; n++) { if (!virtio_queue_get_num(vdev, n)) { continue; } @@ -266,7 +266,7 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align, { VirtIODevice *vdev = virtio_ccw_get_vdev(sch); - if (index >= VIRTIO_PCI_QUEUE_MAX) { + if (index >= VIRTIO_CCW_QUEUE_MAX) { return -EINVAL; } @@ -291,7 +291,7 @@ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align, virtio_queue_set_vector(vdev, index, index); } /* tell notify handler in case of config change */ - vdev->config_vector = VIRTIO_PCI_QUEUE_MAX; + vdev->config_vector = VIRTIO_CCW_QUEUE_MAX; return 0; } @@ -573,7 +573,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) ccw.cda, MEMTXATTRS_UNSPECIFIED, NULL); - if (vq_config.index >= VIRTIO_PCI_QUEUE_MAX) { + if (vq_config.index >= VIRTIO_CCW_QUEUE_MAX) { ret = -EINVAL; break; } @@ -1025,7 +1025,7 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector) return; } - if (vector < VIRTIO_PCI_QUEUE_MAX) { + if (vector < VIRTIO_CCW_QUEUE_MAX) { if (!dev->indicators) { return; } diff --git a/include/hw/s390x/s390_flic.h b/include/hw/s390x/s390_flic.h index 489d73b9b3..200e7e93fa 100644 --- a/include/hw/s390x/s390_flic.h +++ b/include/hw/s390x/s390_flic.h @@ -17,10 +17,13 @@ #include "hw/s390x/adapter.h" #include "hw/virtio/virtio.h" +#define ADAPTER_ROUTES_MAX_GSI 64 +#define VIRTIO_CCW_QUEUE_MAX ADAPTER_ROUTES_MAX_GSI + typedef struct AdapterRoutes { AdapterInfo adapter; int num_routes; - int gsi[VIRTIO_PCI_QUEUE_MAX]; + int gsi[ADAPTER_ROUTES_MAX_GSI]; } AdapterRoutes; #define TYPE_S390_FLIC_COMMON "s390-flic" -- cgit v1.2.3 From 10ceaa1e8f9f74c917df1fe5db856817a8b26fe7 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 29 May 2015 14:15:28 +0800 Subject: virtio-ccw: validate the number of queues against bus limitation Cc: Cornelia Huck Cc: Christian Borntraeger Cc: Richard Henderson Cc: Alexander Graf Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/s390x/virtio-ccw.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 60d60d6186..ef90feddea 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1381,7 +1381,16 @@ static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f) static void virtio_ccw_device_plugged(DeviceState *d, Error **errp) { VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); + VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); SubchDev *sch = dev->sch; + int n = virtio_get_num_queues(vdev); + + if (virtio_get_num_queues(vdev) > VIRTIO_CCW_QUEUE_MAX) { + error_setg(errp, "The nubmer of virtqueues %d " + "exceeds ccw limit %d", n, + VIRTIO_CCW_QUEUE_MAX); + return; + } sch->id.cu_model = virtio_bus_get_vdev_id(&dev->bus); -- cgit v1.2.3 From 74c85296dc880568005b8e7572e08a39d66bcdca Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 29 May 2015 14:15:29 +0800 Subject: virtio-s390: introduce virito s390 queue limit Cc: Alexander Graf Cc: Richard Henderson Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/s390x/s390-virtio-bus.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 74e27e89b7..0748e30734 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -45,6 +45,8 @@ do { } while (0) #endif +#define VIRTIO_S390_QUEUE_MAX 64 + static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size, VirtIOS390Device *dev); @@ -352,7 +354,7 @@ static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev) VirtIODevice *vdev = dev->vdev; int num_vq; - for (num_vq = 0; num_vq < VIRTIO_PCI_QUEUE_MAX; num_vq++) { + for (num_vq = 0; num_vq < VIRTIO_S390_QUEUE_MAX; num_vq++) { if (!virtio_queue_get_num(vdev, num_vq)) { break; } @@ -475,7 +477,7 @@ VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus, QTAILQ_FOREACH(kid, &bus->bus.children, sibling) { VirtIOS390Device *dev = (VirtIOS390Device *)kid->child; - for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { + for (i = 0; i < VIRTIO_S390_QUEUE_MAX; i++) { if (!virtio_queue_get_addr(dev->vdev, i)) break; if (virtio_queue_get_addr(dev->vdev, i) == mem) { -- cgit v1.2.3 From d820331a0b47cbbdc409b435545aea25e19b57ad Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 29 May 2015 14:15:30 +0800 Subject: virtio-s390: introduce virtio_s390_device_plugged() This patch introduce a virtio-s390 specific device_plugged() function and doing the number of virtqueue validation inside. Cc: Alexander Graf Cc: Richard Henderson Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/s390x/s390-virtio-bus.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 0748e30734..8a6e27eac1 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -529,6 +529,19 @@ static void virtio_s390_notify(DeviceState *d, uint16_t vector) s390_virtio_irq(0, token); } +static void virtio_s390_device_plugged(DeviceState *d, Error **errp) +{ + VirtIOS390Device *dev = to_virtio_s390_device(d); + VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); + int n = virtio_get_num_queues(vdev); + + if (n > VIRTIO_S390_QUEUE_MAX) { + error_setg(errp, "The nubmer of virtqueues %d " + "exceeds s390 limit %d", n, + VIRTIO_S390_QUEUE_MAX); + } +} + /**************** S390 Virtio Bus Device Descriptions *******************/ static void s390_virtio_net_class_init(ObjectClass *klass, void *data) @@ -722,6 +735,7 @@ static void virtio_s390_bus_class_init(ObjectClass *klass, void *data) BusClass *bus_class = BUS_CLASS(klass); bus_class->max_dev = 1; k->notify = virtio_s390_notify; + k->device_plugged = virtio_s390_device_plugged; } static const TypeInfo virtio_s390_bus_info = { -- cgit v1.2.3 From 87b3bd1c858e6cacac4d403da9109ec3a04fe9d0 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 29 May 2015 14:15:31 +0800 Subject: virtio: rename VIRTIO_PCI_QUEUE_MAX to VIRTIO_QUEUE_MAX VIRTIO_PCI_QUEUE_MAX is not only used for pci, so rename it be generic. Cc: Amit Shah Cc: Paolo Bonzini Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/char/virtio-serial-bus.c | 2 +- hw/net/virtio-net.c | 4 ++-- hw/scsi/virtio-scsi.c | 4 ++-- hw/virtio/virtio-mmio.c | 4 ++-- hw/virtio/virtio-pci.c | 10 +++++----- hw/virtio/virtio.c | 28 ++++++++++++++-------------- include/hw/virtio/virtio.h | 2 +- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index 6e2ad8221b..333339ebb7 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -973,7 +973,7 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp) } /* Each port takes 2 queues, and one pair is for the control queue */ - max_supported_ports = VIRTIO_PCI_QUEUE_MAX / 2 - 1; + max_supported_ports = VIRTIO_QUEUE_MAX / 2 - 1; if (vser->serial.max_virtserial_ports > max_supported_ports) { error_setg(errp, "maximum ports supported: %u", max_supported_ports); diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 3edb1c4144..6dca726021 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1555,10 +1555,10 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size); n->max_queues = MAX(n->nic_conf.peers.queues, 1); - if (n->max_queues * 2 + 1 > VIRTIO_PCI_QUEUE_MAX) { + if (n->max_queues * 2 + 1 > VIRTIO_QUEUE_MAX) { error_setg(errp, "Invalid number of queues (= %" PRIu32 "), " "must be a positive integer less than %d.", - n->max_queues, (VIRTIO_PCI_QUEUE_MAX - 1) / 2); + n->max_queues, (VIRTIO_QUEUE_MAX - 1) / 2); virtio_cleanup(vdev); return; } diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index e242fefa84..5818159e64 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -830,10 +830,10 @@ void virtio_scsi_common_realize(DeviceState *dev, Error **errp, sizeof(VirtIOSCSIConfig)); if (s->conf.num_queues == 0 || - s->conf.num_queues > VIRTIO_PCI_QUEUE_MAX - 2) { + s->conf.num_queues > VIRTIO_QUEUE_MAX - 2) { error_setg(errp, "Invalid number of queues (= %" PRIu32 "), " "must be a positive integer less than %d.", - s->conf.num_queues, VIRTIO_PCI_QUEUE_MAX - 2); + s->conf.num_queues, VIRTIO_QUEUE_MAX - 2); virtio_cleanup(vdev); return; } diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index 3008b65aa9..a3cfd305ce 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -236,7 +236,7 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value, proxy->guest_page_shift); break; case VIRTIO_MMIO_QUEUESEL: - if (value < VIRTIO_PCI_QUEUE_MAX) { + if (value < VIRTIO_QUEUE_MAX) { vdev->queue_sel = value; } break; @@ -256,7 +256,7 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value, } break; case VIRTIO_MMIO_QUEUENOTIFY: - if (value < VIRTIO_PCI_QUEUE_MAX) { + if (value < VIRTIO_QUEUE_MAX) { virtio_queue_notify(vdev, value); } break; diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 0cc249cef8..d1ddc39b6f 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -171,7 +171,7 @@ static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy) return; } - for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { + for (n = 0; n < VIRTIO_QUEUE_MAX; n++) { if (!virtio_queue_get_num(vdev, n)) { continue; } @@ -207,7 +207,7 @@ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy) return; } - for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { + for (n = 0; n < VIRTIO_QUEUE_MAX; n++) { if (!virtio_queue_get_num(vdev, n)) { continue; } @@ -243,11 +243,11 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) virtio_queue_set_addr(vdev, vdev->queue_sel, pa); break; case VIRTIO_PCI_QUEUE_SEL: - if (val < VIRTIO_PCI_QUEUE_MAX) + if (val < VIRTIO_QUEUE_MAX) vdev->queue_sel = val; break; case VIRTIO_PCI_QUEUE_NOTIFY: - if (val < VIRTIO_PCI_QUEUE_MAX) { + if (val < VIRTIO_QUEUE_MAX) { virtio_queue_notify(vdev, val); } break; @@ -744,7 +744,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) bool with_irqfd = msix_enabled(&proxy->pci_dev) && kvm_msi_via_irqfd_enabled(); - nvqs = MIN(nvqs, VIRTIO_PCI_QUEUE_MAX); + nvqs = MIN(nvqs, VIRTIO_QUEUE_MAX); /* When deassigning, pass a consistent nvqs value * to avoid leaking notifiers. diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 5602285635..a0637d9763 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -600,7 +600,7 @@ void virtio_reset(void *opaque) vdev->config_vector = VIRTIO_NO_VECTOR; virtio_notify_vector(vdev, vdev->config_vector); - for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { + for(i = 0; i < VIRTIO_QUEUE_MAX; i++) { vdev->vq[i].vring.desc = 0; vdev->vq[i].vring.avail = 0; vdev->vq[i].vring.used = 0; @@ -750,7 +750,7 @@ int virtio_get_num_queues(VirtIODevice *vdev) { int i; - for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { + for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { if (!virtio_queue_get_num(vdev, i)) { break; } @@ -762,7 +762,7 @@ int virtio_get_num_queues(VirtIODevice *vdev) int virtio_queue_get_id(VirtQueue *vq) { VirtIODevice *vdev = vq->vdev; - assert(vq >= &vdev->vq[0] && vq < &vdev->vq[VIRTIO_PCI_QUEUE_MAX]); + assert(vq >= &vdev->vq[0] && vq < &vdev->vq[VIRTIO_QUEUE_MAX]); return vq - &vdev->vq[0]; } @@ -798,7 +798,7 @@ void virtio_queue_notify(VirtIODevice *vdev, int n) uint16_t virtio_queue_vector(VirtIODevice *vdev, int n) { - return n < VIRTIO_PCI_QUEUE_MAX ? vdev->vq[n].vector : + return n < VIRTIO_QUEUE_MAX ? vdev->vq[n].vector : VIRTIO_NO_VECTOR; } @@ -806,7 +806,7 @@ void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector) { VirtQueue *vq = &vdev->vq[n]; - if (n < VIRTIO_PCI_QUEUE_MAX) { + if (n < VIRTIO_QUEUE_MAX) { if (vdev->vector_queues && vdev->vq[n].vector != VIRTIO_NO_VECTOR) { QLIST_REMOVE(vq, node); @@ -824,12 +824,12 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, { int i; - for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { + for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { if (vdev->vq[i].vring.num == 0) break; } - if (i == VIRTIO_PCI_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE) + if (i == VIRTIO_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE) abort(); vdev->vq[i].vring.num = queue_size; @@ -841,7 +841,7 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, void virtio_del_queue(VirtIODevice *vdev, int n) { - if (n < 0 || n >= VIRTIO_PCI_QUEUE_MAX) { + if (n < 0 || n >= VIRTIO_QUEUE_MAX) { abort(); } @@ -951,14 +951,14 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) qemu_put_be32(f, vdev->config_len); qemu_put_buffer(f, vdev->config, vdev->config_len); - for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { + for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { if (vdev->vq[i].vring.num == 0) break; } qemu_put_be32(f, i); - for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { + for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { if (vdev->vq[i].vring.num == 0) break; @@ -1019,7 +1019,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) qemu_get_8s(f, &vdev->status); qemu_get_8s(f, &vdev->isr); qemu_get_be16s(f, &vdev->queue_sel); - if (vdev->queue_sel >= VIRTIO_PCI_QUEUE_MAX) { + if (vdev->queue_sel >= VIRTIO_QUEUE_MAX) { return -1; } qemu_get_be32s(f, &features); @@ -1045,7 +1045,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) num = qemu_get_be32(f); - if (num > VIRTIO_PCI_QUEUE_MAX) { + if (num > VIRTIO_QUEUE_MAX) { error_report("Invalid number of PCI queues: 0x%x", num); return -1; } @@ -1171,9 +1171,9 @@ void virtio_init(VirtIODevice *vdev, const char *name, vdev->isr = 0; vdev->queue_sel = 0; vdev->config_vector = VIRTIO_NO_VECTOR; - vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX); + vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_QUEUE_MAX); vdev->vm_running = runstate_is_running(); - for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { + for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { vdev->vq[i].vector = VIRTIO_NO_VECTOR; vdev->vq[i].vdev = vdev; vdev->vq[i].queue_index = i; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index dd92fe4979..4411dcafa2 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -48,7 +48,7 @@ typedef struct VirtQueueElement struct iovec out_sg[VIRTQUEUE_MAX_SIZE]; } VirtQueueElement; -#define VIRTIO_PCI_QUEUE_MAX 64 +#define VIRTIO_QUEUE_MAX 64 #define VIRTIO_NO_VECTOR 0xffff -- cgit v1.2.3 From b829c2a98f1f67308eb02fcddb52d8fa67775f18 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 29 May 2015 14:15:32 +0800 Subject: virtio: increase the queue limit to 1024 Increase the queue limit to 1024. But virtio-ccw and s390-virtio won't support this, this is done through failing device_plugged() for those two transports if the number of virtqueues is greater than 64. Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/virtio/virtio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 4411dcafa2..45d6e5b01e 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -48,7 +48,7 @@ typedef struct VirtQueueElement struct iovec out_sg[VIRTQUEUE_MAX_SIZE]; } VirtQueueElement; -#define VIRTIO_QUEUE_MAX 64 +#define VIRTIO_QUEUE_MAX 1024 #define VIRTIO_NO_VECTOR 0xffff -- cgit v1.2.3 From fd53c87cf6651b0dfe9f5107cfe77d2f697bd4f6 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Thu, 28 May 2015 22:04:08 +0200 Subject: i386/pc: pc_basic_device_init(): delegate FDC creation request This patch introduces no observable change, but it allows the callers of pc_basic_device_init(), ie. pc_init1() and pc_q35_init(), to request (or not request) the creation of the FDC explicitly. At the moment both callers pass constant create_fdctrl=true (hence no observable change). Assuming a board passes create_fdctrl=false, "floppy" will be NULL on output, and (beyond the FDC not being created) that NULL will be passed on to pc_cmos_init(). Luckily, pc_cmos_init() already handles that case. Cc: Markus Armbruster Cc: Paolo Bonzini Cc: Gerd Hoffmann Cc: John Snow Cc: "Gabriel L. Somlo" Cc: "Michael S. Tsirkin" Cc: Kevin Wolf Cc: qemu-block@nongnu.org Signed-off-by: Laszlo Ersek Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Markus Armbruster --- hw/i386/pc.c | 3 ++- hw/i386/pc_piix.c | 2 +- hw/i386/pc_q35.c | 2 +- include/hw/i386/pc.h | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index aeed45d583..b2fc501066 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1395,6 +1395,7 @@ static const MemoryRegionOps ioportF0_io_ops = { void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, ISADevice **rtc_state, + bool create_fdctrl, ISADevice **floppy, bool no_vmport, uint32 hpet_irqs) @@ -1490,7 +1491,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); } - *floppy = fdctrl_init_isa(isa_bus, fd); + *floppy = create_fdctrl ? fdctrl_init_isa(isa_bus, fd) : NULL; } void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index e77486c62c..6e7fa424b1 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -242,7 +242,7 @@ static void pc_init1(MachineState *machine) } /* init basic PC hardware */ - pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, + pc_basic_device_init(isa_bus, gsi, &rtc_state, true, &floppy, (pc_machine->vmport != ON_OFF_AUTO_ON), 0x4); pc_nic_init(isa_bus, pci_bus); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 68b4867d31..9ca317cc43 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -250,7 +250,7 @@ static void pc_q35_init(MachineState *machine) } /* init basic PC hardware */ - pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, + pc_basic_device_init(isa_bus, gsi, &rtc_state, true, &floppy, (pc_machine->vmport != ON_OFF_AUTO_ON), 0xff0104); /* connect pm stuff to lpc */ diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 0510aeac89..27bd748eab 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -197,6 +197,7 @@ qemu_irq *pc_allocate_cpu_irq(void); DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus); void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, ISADevice **rtc_state, + bool create_fdctrl, ISADevice **floppy, bool no_vmport, uint32 hpet_irqs); -- cgit v1.2.3 From 936a7c1cf7410a3bab97c98301054921d47a8918 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Thu, 28 May 2015 22:04:09 +0200 Subject: i386/pc: '-drive if=floppy' should imply a board-default FDC Even if board code decides not to request the creation of the FDC (keyed off board-level factors, to be determined later), we should create the FDC nevertheless if the user passes '-drive if=floppy' on the command line. Otherwise '-drive if=floppy' would break without explicit '-device isa-fdc' on such boards. Cc: Markus Armbruster Cc: Paolo Bonzini Cc: Gerd Hoffmann Cc: John Snow Cc: "Gabriel L. Somlo" Cc: "Michael S. Tsirkin" Cc: Kevin Wolf Cc: qemu-block@nongnu.org Signed-off-by: Laszlo Ersek Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Markus Armbruster --- hw/i386/pc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index b2fc501066..1eb1db0372 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1490,6 +1490,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); + create_fdctrl |= !!fd[i]; } *floppy = create_fdctrl ? fdctrl_init_isa(isa_bus, fd) : NULL; } -- cgit v1.2.3 From 6cd2234ccbacf2825372142a2658bf318ce2f848 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Thu, 28 May 2015 22:04:10 +0200 Subject: i386/pc_q35: don't insist on board FDC if there's no default floppy The "no_floppy = 1" machine class setting causes "default_floppy" in main() to become zero. Consequently, default_drive() will not call drive_add() and drive_new() for IF_FLOPPY, index=0, meaning that no default floppy drive will be created for the virtual machine. In that case, board code should also not insist on the creation of the board-default FDC. The board-default FDC will still be created if the user requests a floppy drive with "-drive if=floppy". Additionally, separate FDCs can be specified manually with "-device isa-fdc". They allow the -device isa-fdc,driveA=... syntax that is more flexible than the one required by the board-default FDC: -global isa-fdc.driveA=... This patch doesn't change the behavior observably, as all Q35 machine types have "no_floppy = 0". Cc: Markus Armbruster Cc: Paolo Bonzini Cc: Gerd Hoffmann Cc: John Snow Cc: "Gabriel L. Somlo" Cc: "Michael S. Tsirkin" Cc: Kevin Wolf Cc: qemu-block@nongnu.org Signed-off-by: Laszlo Ersek Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Markus Armbruster --- hw/i386/pc_q35.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 9ca317cc43..9f036c81b9 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -89,6 +89,7 @@ static void pc_q35_init(MachineState *machine) PcGuestInfo *guest_info; ram_addr_t lowmem; DriveInfo *hd[MAX_SATA_PORTS]; + MachineClass *mc = MACHINE_GET_CLASS(machine); /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping @@ -163,7 +164,6 @@ static void pc_q35_init(MachineState *machine) guest_info->legacy_acpi_table_size = 0; if (smbios_defaults) { - MachineClass *mc = MACHINE_GET_CLASS(machine); /* These values are guest ABI, do not change */ smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)", mc->name, smbios_legacy_mode, smbios_uuid_encoded); @@ -250,7 +250,7 @@ static void pc_q35_init(MachineState *machine) } /* init basic PC hardware */ - pc_basic_device_init(isa_bus, gsi, &rtc_state, true, &floppy, + pc_basic_device_init(isa_bus, gsi, &rtc_state, !mc->no_floppy, &floppy, (pc_machine->vmport != ON_OFF_AUTO_ON), 0xff0104); /* connect pm stuff to lpc */ -- cgit v1.2.3 From ea96bc629cbd52be98b2967a4b4f72e91dfc3ee4 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Thu, 28 May 2015 22:04:11 +0200 Subject: i386: drop FDC in pc-q35-2.4+ if neither it nor floppy drives are wanted It is Very annoying to carry forward an outdatEd coNtroller with a mOdern Machine type. Hence, let us not instantiate the FDC when all of the following apply: - the machine type is pc-q35-2.4 or later, - "-device isa-fdc" is not passed on the command line (nor in the config file), - no "-drive if=floppy,..." is requested. Cc: Markus Armbruster Cc: Paolo Bonzini Cc: Gerd Hoffmann Cc: John Snow Cc: "Gabriel L. Somlo" Cc: "Michael S. Tsirkin" Cc: Kevin Wolf Cc: qemu-block@nongnu.org Suggested-by: Markus Armbruster Signed-off-by: Laszlo Ersek Acked-by: Paolo Bonzini Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Markus Armbruster --- hw/i386/pc_q35.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 9f036c81b9..66220b352b 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -392,6 +392,7 @@ static void pc_q35_2_4_machine_options(MachineClass *m) pc_q35_machine_options(m); m->default_machine_opts = "firmware=bios-256k.bin"; m->default_display = "std"; + m->no_floppy = 1; m->alias = "q35"; } -- cgit v1.2.3 From c3bdc56c183f6ca6baa502bd7861583ca98b333b Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 27 May 2015 19:55:55 +0200 Subject: acpi: Simplify printing to dynamic string build_append_namestringv() and aml_string() first calculate the resulting string's length with vsnprintf(NULL, ...), then allocate, then print for real. Simply use g_strdup_vprintf() or g_vasprintf() instead. Signed-off-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: John Snow Reviewed-by: Igor Mammedov --- hw/acpi/aml-build.c | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 323b7bc179..4cc0c61fa7 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -19,6 +19,7 @@ * with this program; if not, see . */ +#include #include #include #include @@ -59,7 +60,6 @@ static void build_append_array(GArray *array, GArray *val) static void build_append_nameseg(GArray *array, const char *seg) { - /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */ int len; len = strlen(seg); @@ -73,22 +73,12 @@ build_append_nameseg(GArray *array, const char *seg) static void GCC_FMT_ATTR(2, 0) build_append_namestringv(GArray *array, const char *format, va_list ap) { - /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */ char *s; - int len; - va_list va_len; char **segs; char **segs_iter; int seg_count = 0; - va_copy(va_len, ap); - len = vsnprintf(NULL, 0, format, va_len); - va_end(va_len); - len += 1; - s = g_new(typeof(*s), len); - - len = vsnprintf(s, len, format, ap); - + s = g_strdup_vprintf(format, ap); segs = g_strsplit(s, ".", 0); g_free(s); @@ -753,22 +743,15 @@ Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const char *name) Aml *aml_string(const char *name_format, ...) { Aml *var = aml_opcode(0x0D /* StringPrefix */); - va_list ap, va_len; + va_list ap; char *s; int len; va_start(ap, name_format); - va_copy(va_len, ap); - len = vsnprintf(NULL, 0, name_format, va_len); - va_end(va_len); - len += 1; - s = g_new0(typeof(*s), len); - - len = vsnprintf(s, len, name_format, ap); + len = g_vasprintf(&s, name_format, ap); va_end(ap); - g_array_append_vals(var->buf, s, len); - build_append_byte(var->buf, 0x0); /* NullChar */ + g_array_append_vals(var->buf, s, len + 1); g_free(s); return var; -- cgit v1.2.3 From 38d40ff10f71657ea913a63d1f8477be368b92c1 Mon Sep 17 00:00:00 2001 From: Pavel Fedin Date: Wed, 27 May 2015 15:59:59 +0300 Subject: Add stream ID to MSI write GICv3 ITS distinguishes between devices by using hardwired device IDs passed on the bus. This patch implements passing these IDs in qemu. SMMU is also known to use stream IDs, therefore this addition can also be useful for implementing platforms with SMMU. Signed-off-by: Pavel Fedin Reviewed-by: Michael S. Tsirkin Changes from v1: - Added bus number to the stream ID - Added stream ID not only to MSI-X, but also to plain MSI. Some common code was made into msi_send_message() function. Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci/msi.c | 10 +++++++++- hw/pci/msix.c | 3 +-- include/exec/memattrs.h | 2 ++ include/hw/pci/msi.h | 1 + 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/hw/pci/msi.c b/hw/pci/msi.c index 2949938223..c111dbaff6 100644 --- a/hw/pci/msi.c +++ b/hw/pci/msi.c @@ -291,8 +291,16 @@ void msi_notify(PCIDevice *dev, unsigned int vector) "notify vector 0x%x" " address: 0x%"PRIx64" data: 0x%"PRIx32"\n", vector, msg.address, msg.data); + msi_send_message(dev, msg); +} + +void msi_send_message(PCIDevice *dev, MSIMessage msg) +{ + MemTxAttrs attrs = {}; + + attrs.stream_id = (pci_bus_num(dev->bus) << 8) | dev->devfn; address_space_stl_le(&dev->bus_master_as, msg.address, msg.data, - MEMTXATTRS_UNSPECIFIED, NULL); + attrs, NULL); } /* Normally called by pci_default_write_config(). */ diff --git a/hw/pci/msix.c b/hw/pci/msix.c index 9935f98ae5..7716bf3649 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -443,8 +443,7 @@ void msix_notify(PCIDevice *dev, unsigned vector) msg = msix_get_message(dev, vector); - address_space_stl_le(&dev->bus_master_as, msg.address, msg.data, - MEMTXATTRS_UNSPECIFIED, NULL); + msi_send_message(dev, msg); } void msix_reset(PCIDevice *dev) diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h index 1389b4b01d..96dc440423 100644 --- a/include/exec/memattrs.h +++ b/include/exec/memattrs.h @@ -33,6 +33,8 @@ typedef struct MemTxAttrs { unsigned int secure:1; /* Memory access is usermode (unprivileged) */ unsigned int user:1; + /* Stream ID (for MSI for example) */ + unsigned int stream_id:16; } MemTxAttrs; /* Bus masters which don't specify any attributes will get this, diff --git a/include/hw/pci/msi.h b/include/hw/pci/msi.h index 81a3848a31..50e452bd05 100644 --- a/include/hw/pci/msi.h +++ b/include/hw/pci/msi.h @@ -39,6 +39,7 @@ int msi_init(struct PCIDevice *dev, uint8_t offset, void msi_uninit(struct PCIDevice *dev); void msi_reset(PCIDevice *dev); void msi_notify(PCIDevice *dev, unsigned int vector); +void msi_send_message(PCIDevice *dev, MSIMessage msg); void msi_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int len); unsigned int msi_nr_vectors_allocated(const PCIDevice *dev); -- cgit v1.2.3 From 116694c34aa794a994051fce55bfee418fe1521d Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Tue, 26 May 2015 16:51:05 -0400 Subject: Extend TPM TIS interface to support TPM 2 Following the recent upgrade to version 1.3, extend the TPM TIS interface with capabilities introduced for support of a TPM 2. TPM TIS for TPM 2 introduced the following extensions beyond the TPM TIS 1.3 (used for TPM 1.2): - A new 32bit interface Id register was introduced. - New flags for the status (STS) register were defined. - New flags for the capability flags were defined. Support the above if a TPM TIS 1.3 for TPM 2 is used with a TPM 2 on the backend side. Support the old TPM TIS 1.3 configuration if a TPM 1.2 is being used. A subsequent patch will then determine which TPM version is being used in the backend. Signed-off-by: Stefan Berger Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- backends/tpm.c | 14 ++++++ hw/tpm/tpm_int.h | 1 + hw/tpm/tpm_passthrough.c | 14 ++++++ hw/tpm/tpm_tis.c | 108 +++++++++++++++++++++++++++++++++++++++---- hw/tpm/tpm_tis.h | 1 + include/sysemu/tpm.h | 6 +++ include/sysemu/tpm_backend.h | 23 +++++++++ 7 files changed, 158 insertions(+), 9 deletions(-) diff --git a/backends/tpm.c b/backends/tpm.c index 36c5d46f0a..f3ab3b30bd 100644 --- a/backends/tpm.c +++ b/backends/tpm.c @@ -96,6 +96,20 @@ bool tpm_backend_get_tpm_established_flag(TPMBackend *s) return k->ops->get_tpm_established_flag(s); } +int tpm_backend_reset_tpm_established_flag(TPMBackend *s, uint8_t locty) +{ + TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s); + + return k->ops->reset_tpm_established_flag(s, locty); +} + +TPMVersion tpm_backend_get_tpm_version(TPMBackend *s) +{ + TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s); + + return k->ops->get_tpm_version(s); +} + static bool tpm_backend_prop_get_opened(Object *obj, Error **errp) { TPMBackend *s = TPM_BACKEND(obj); diff --git a/hw/tpm/tpm_int.h b/hw/tpm/tpm_int.h index 2b35fe21ec..9866c7962a 100644 --- a/hw/tpm/tpm_int.h +++ b/hw/tpm/tpm_int.h @@ -29,6 +29,7 @@ struct TPMState { char *backend; TPMBackend *be_driver; + TPMVersion be_tpm_version; }; #define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS) diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c index 73ca906282..f1361d2cb6 100644 --- a/hw/tpm/tpm_passthrough.c +++ b/hw/tpm/tpm_passthrough.c @@ -267,6 +267,13 @@ static bool tpm_passthrough_get_tpm_established_flag(TPMBackend *tb) return false; } +static int tpm_passthrough_reset_tpm_established_flag(TPMBackend *tb, + uint8_t locty) +{ + /* only a TPM 2.0 will support this */ + return 0; +} + static bool tpm_passthrough_get_startup_error(TPMBackend *tb) { TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); @@ -324,6 +331,11 @@ static const char *tpm_passthrough_create_desc(void) return "Passthrough TPM backend driver"; } +static TPMVersion tpm_passthrough_get_tpm_version(TPMBackend *tb) +{ + return TPM_VERSION_1_2; +} + /* * A basic test of a TPM device. We expect a well formatted response header * (error response is fine) within one second. @@ -540,6 +552,8 @@ static const TPMDriverOps tpm_passthrough_driver = { .deliver_request = tpm_passthrough_deliver_request, .cancel_cmd = tpm_passthrough_cancel_cmd, .get_tpm_established_flag = tpm_passthrough_get_tpm_established_flag, + .reset_tpm_established_flag = tpm_passthrough_reset_tpm_established_flag, + .get_tpm_version = tpm_passthrough_get_tpm_version, }; static void tpm_passthrough_inst_init(Object *obj) diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c index b8235d5c9f..e8047571c1 100644 --- a/hw/tpm/tpm_tis.c +++ b/hw/tpm/tpm_tis.c @@ -17,6 +17,9 @@ * supports version 1.3, 21 March 2013 * In the developers menu choose the PC Client section then find the TIS * specification. + * + * TPM TIS for TPM 2 implementation following TCG PC Client Platform + * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43 */ #include "sysemu/tpm_backend.h" @@ -49,6 +52,7 @@ #define TPM_TIS_REG_INTF_CAPABILITY 0x14 #define TPM_TIS_REG_STS 0x18 #define TPM_TIS_REG_DATA_FIFO 0x24 +#define TPM_TIS_REG_INTERFACE_ID 0x30 #define TPM_TIS_REG_DATA_XFIFO 0x80 #define TPM_TIS_REG_DATA_XFIFO_END 0xbc #define TPM_TIS_REG_DID_VID 0xf00 @@ -57,6 +61,12 @@ /* vendor-specific registers */ #define TPM_TIS_REG_DEBUG 0xf90 +#define TPM_TIS_STS_TPM_FAMILY_MASK (0x3 << 26)/* TPM 2.0 */ +#define TPM_TIS_STS_TPM_FAMILY1_2 (0 << 26) /* TPM 2.0 */ +#define TPM_TIS_STS_TPM_FAMILY2_0 (1 << 26) /* TPM 2.0 */ +#define TPM_TIS_STS_RESET_ESTABLISHMENT_BIT (1 << 25) /* TPM 2.0 */ +#define TPM_TIS_STS_COMMAND_CANCEL (1 << 24) /* TPM 2.0 */ + #define TPM_TIS_STS_VALID (1 << 7) #define TPM_TIS_STS_COMMAND_READY (1 << 6) #define TPM_TIS_STS_TPM_GO (1 << 5) @@ -102,15 +112,42 @@ #endif #define TPM_TIS_CAP_INTERFACE_VERSION1_3 (2 << 28) +#define TPM_TIS_CAP_INTERFACE_VERSION1_3_FOR_TPM2_0 (3 << 28) #define TPM_TIS_CAP_DATA_TRANSFER_64B (3 << 9) #define TPM_TIS_CAP_DATA_TRANSFER_LEGACY (0 << 9) #define TPM_TIS_CAP_BURST_COUNT_DYNAMIC (0 << 8) #define TPM_TIS_CAP_INTERRUPT_LOW_LEVEL (1 << 4) /* support is mandatory */ -#define TPM_TIS_CAPABILITIES_SUPPORTED (TPM_TIS_CAP_INTERRUPT_LOW_LEVEL | \ - TPM_TIS_CAP_BURST_COUNT_DYNAMIC | \ - TPM_TIS_CAP_DATA_TRANSFER_64B | \ - TPM_TIS_CAP_INTERFACE_VERSION1_3 | \ - TPM_TIS_INTERRUPTS_SUPPORTED) +#define TPM_TIS_CAPABILITIES_SUPPORTED1_3 \ + (TPM_TIS_CAP_INTERRUPT_LOW_LEVEL | \ + TPM_TIS_CAP_BURST_COUNT_DYNAMIC | \ + TPM_TIS_CAP_DATA_TRANSFER_64B | \ + TPM_TIS_CAP_INTERFACE_VERSION1_3 | \ + TPM_TIS_INTERRUPTS_SUPPORTED) + +#define TPM_TIS_CAPABILITIES_SUPPORTED2_0 \ + (TPM_TIS_CAP_INTERRUPT_LOW_LEVEL | \ + TPM_TIS_CAP_BURST_COUNT_DYNAMIC | \ + TPM_TIS_CAP_DATA_TRANSFER_64B | \ + TPM_TIS_CAP_INTERFACE_VERSION1_3_FOR_TPM2_0 | \ + TPM_TIS_INTERRUPTS_SUPPORTED) + +#define TPM_TIS_IFACE_ID_INTERFACE_TIS1_3 (0xf) /* TPM 2.0 */ +#define TPM_TIS_IFACE_ID_INTERFACE_FIFO (0x0) /* TPM 2.0 */ +#define TPM_TIS_IFACE_ID_INTERFACE_VER_FIFO (0 << 4) /* TPM 2.0 */ +#define TPM_TIS_IFACE_ID_CAP_5_LOCALITIES (1 << 8) /* TPM 2.0 */ +#define TPM_TIS_IFACE_ID_CAP_TIS_SUPPORTED (1 << 13) /* TPM 2.0 */ +#define TPM_TIS_IFACE_ID_INT_SEL_LOCK (1 << 19) /* TPM 2.0 */ + +#define TPM_TIS_IFACE_ID_SUPPORTED_FLAGS1_3 \ + (TPM_TIS_IFACE_ID_INTERFACE_TIS1_3 | \ + (~0 << 4)/* all of it is don't care */) + +/* if backend was a TPM 2.0: */ +#define TPM_TIS_IFACE_ID_SUPPORTED_FLAGS2_0 \ + (TPM_TIS_IFACE_ID_INTERFACE_FIFO | \ + TPM_TIS_IFACE_ID_INTERFACE_VER_FIFO | \ + TPM_TIS_IFACE_ID_CAP_5_LOCALITIES | \ + TPM_TIS_IFACE_ID_CAP_TIS_SUPPORTED) #define TPM_TIS_TPM_DID 0x0001 #define TPM_TIS_TPM_VID PCI_VENDOR_ID_IBM @@ -154,7 +191,8 @@ static void tpm_tis_show_buffer(const TPMSizedBuffer *sb, const char *string) /* * Set the given flags in the STS register by clearing the register but - * preserving the SELFTEST_DONE flag and then setting the new flags. + * preserving the SELFTEST_DONE and TPM_FAMILY_MASK flags and then setting + * the new flags. * * The SELFTEST_DONE flag is acquired from the backend that determines it by * peeking into TPM commands. @@ -166,7 +204,7 @@ static void tpm_tis_show_buffer(const TPMSizedBuffer *sb, const char *string) */ static void tpm_tis_sts_set(TPMLocality *l, uint32_t flags) { - l->sts &= TPM_TIS_STS_SELFTEST_DONE; + l->sts &= TPM_TIS_STS_SELFTEST_DONE | TPM_TIS_STS_TPM_FAMILY_MASK; l->sts |= flags; } @@ -489,7 +527,17 @@ static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr, val = tis->loc[locty].ints; break; case TPM_TIS_REG_INTF_CAPABILITY: - val = TPM_TIS_CAPABILITIES_SUPPORTED; + switch (s->be_tpm_version) { + case TPM_VERSION_UNSPEC: + val = 0; + break; + case TPM_VERSION_1_2: + val = TPM_TIS_CAPABILITIES_SUPPORTED1_3; + break; + case TPM_VERSION_2_0: + val = TPM_TIS_CAPABILITIES_SUPPORTED2_0; + break; + } break; case TPM_TIS_REG_STS: if (tis->active_locty == locty) { @@ -536,6 +584,9 @@ static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr, shift = 0; /* no more adjustments */ } break; + case TPM_TIS_REG_INTERFACE_ID: + val = tis->loc[locty].iface_id; + break; case TPM_TIS_REG_DID_VID: val = (TPM_TIS_TPM_DID << 16) | TPM_TIS_TPM_VID; break; @@ -736,6 +787,25 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr, break; } + if (s->be_tpm_version == TPM_VERSION_2_0) { + /* some flags that are only supported for TPM 2 */ + if (val & TPM_TIS_STS_COMMAND_CANCEL) { + if (tis->loc[locty].state == TPM_TIS_STATE_EXECUTION) { + /* + * request the backend to cancel. Some backends may not + * support it + */ + tpm_backend_cancel_cmd(s->be_driver); + } + } + + if (val & TPM_TIS_STS_RESET_ESTABLISHMENT_BIT) { + if (locty == 3 || locty == 4) { + tpm_backend_reset_tpm_established_flag(s->be_driver, locty); + } + } + } + val &= (TPM_TIS_STS_COMMAND_READY | TPM_TIS_STS_TPM_GO | TPM_TIS_STS_RESPONSE_RETRY); @@ -860,6 +930,13 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr, } } break; + case TPM_TIS_REG_INTERFACE_ID: + if (val & TPM_TIS_IFACE_ID_INT_SEL_LOCK) { + for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) { + tis->loc[l].iface_id |= TPM_TIS_IFACE_ID_INT_SEL_LOCK; + } + } + break; } } @@ -894,6 +971,8 @@ static void tpm_tis_reset(DeviceState *dev) TPMTISEmuState *tis = &s->s.tis; int c; + s->be_tpm_version = tpm_backend_get_tpm_version(s->be_driver); + tpm_backend_reset(s->be_driver); tis->active_locty = TPM_TIS_NO_LOCALITY; @@ -902,7 +981,18 @@ static void tpm_tis_reset(DeviceState *dev) for (c = 0; c < TPM_TIS_NUM_LOCALITIES; c++) { tis->loc[c].access = TPM_TIS_ACCESS_TPM_REG_VALID_STS; - tis->loc[c].sts = 0; + switch (s->be_tpm_version) { + case TPM_VERSION_UNSPEC: + break; + case TPM_VERSION_1_2: + tis->loc[c].sts = TPM_TIS_STS_TPM_FAMILY1_2; + tis->loc[c].iface_id = TPM_TIS_IFACE_ID_SUPPORTED_FLAGS1_3; + break; + case TPM_VERSION_2_0: + tis->loc[c].sts = TPM_TIS_STS_TPM_FAMILY2_0; + tis->loc[c].iface_id = TPM_TIS_IFACE_ID_SUPPORTED_FLAGS2_0; + break; + } tis->loc[c].inte = TPM_TIS_INT_POLARITY_LOW_LEVEL; tis->loc[c].ints = 0; tis->loc[c].state = TPM_TIS_STATE_IDLE; diff --git a/hw/tpm/tpm_tis.h b/hw/tpm/tpm_tis.h index db78d51e4f..a1df41fa21 100644 --- a/hw/tpm/tpm_tis.h +++ b/hw/tpm/tpm_tis.h @@ -42,6 +42,7 @@ typedef struct TPMLocality { TPMTISState state; uint8_t access; uint32_t sts; + uint32_t iface_id; uint32_t inte; uint32_t ints; diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h index 9b81ce9189..848df412db 100644 --- a/include/sysemu/tpm.h +++ b/include/sysemu/tpm.h @@ -20,6 +20,12 @@ int tpm_config_parse(QemuOptsList *opts_list, const char *optarg); int tpm_init(void); void tpm_cleanup(void); +typedef enum TPMVersion { + TPM_VERSION_UNSPEC = 0, + TPM_VERSION_1_2 = 1, + TPM_VERSION_2_0 = 2, +} TPMVersion; + #define TYPE_TPM_TIS "tpm-tis" static inline bool tpm_find(void) diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h index 540ee25477..0a366be0f2 100644 --- a/include/sysemu/tpm_backend.h +++ b/include/sysemu/tpm_backend.h @@ -88,6 +88,10 @@ struct TPMDriverOps { void (*cancel_cmd)(TPMBackend *t); bool (*get_tpm_established_flag)(TPMBackend *t); + + int (*reset_tpm_established_flag)(TPMBackend *t, uint8_t locty); + + TPMVersion (*get_tpm_version)(TPMBackend *t); }; @@ -191,6 +195,15 @@ void tpm_backend_cancel_cmd(TPMBackend *s); */ bool tpm_backend_get_tpm_established_flag(TPMBackend *s); +/** + * tpm_backend_reset_tpm_established_flag: + * @s: the backend + * @locty: the locality number + * + * Reset the TPM establishment flag. + */ +int tpm_backend_reset_tpm_established_flag(TPMBackend *s, uint8_t locty); + /** * tpm_backend_open: * @s: the backend to open @@ -201,6 +214,16 @@ bool tpm_backend_get_tpm_established_flag(TPMBackend *s); */ void tpm_backend_open(TPMBackend *s, Error **errp); +/** + * tpm_backend_get_tpm_version: + * @s: the backend to call into + * + * Get the TPM Version that is emulated at the backend. + * + * Returns TPMVersion. + */ +TPMVersion tpm_backend_get_tpm_version(TPMBackend *s); + TPMBackend *qemu_find_tpm(const char *id); const TPMDriverOps *tpm_get_backend_driver(const char *type); -- cgit v1.2.3 From 56a3c24ffc11955ddc7bb21362ca8069a3fc8c55 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Tue, 26 May 2015 16:51:06 -0400 Subject: tpm: Probe for connected TPM 1.2 or TPM 2 In the TPM passthrough backend driver, modify the probing code so that we can check whether a TPM 1.2 or TPM 2 is being used and adapt the behavior of the TPM TIS accordingly. Move the code that tested for a TPM 1.2 into tpm_utils.c and extend it with test for probing for TPM 2. Have the function return the version of TPM found. Signed-off-by: Stefan Berger Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/tpm/Makefile.objs | 2 +- hw/tpm/tpm_int.h | 6 +++ hw/tpm/tpm_passthrough.c | 59 +++------------------- hw/tpm/tpm_util.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++ hw/tpm/tpm_util.h | 28 +++++++++++ 5 files changed, 167 insertions(+), 54 deletions(-) create mode 100644 hw/tpm/tpm_util.c create mode 100644 hw/tpm/tpm_util.h diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs index 99f5983143..64cecc3b67 100644 --- a/hw/tpm/Makefile.objs +++ b/hw/tpm/Makefile.objs @@ -1,2 +1,2 @@ common-obj-$(CONFIG_TPM_TIS) += tpm_tis.o -common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o +common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o tpm_util.o diff --git a/hw/tpm/tpm_int.h b/hw/tpm/tpm_int.h index 9866c7962a..f2f285b3cc 100644 --- a/hw/tpm/tpm_int.h +++ b/hw/tpm/tpm_int.h @@ -66,4 +66,10 @@ struct tpm_resp_hdr { #define TPM_ORD_ContinueSelfTest 0x53 #define TPM_ORD_GetTicks 0xf1 + +/* TPM2 defines */ +#define TPM2_ST_NO_SESSIONS 0x8001 + +#define TPM2_CC_ReadClock 0x00000181 + #endif /* TPM_TPM_INT_H */ diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c index f1361d2cb6..8d8523a535 100644 --- a/hw/tpm/tpm_passthrough.c +++ b/hw/tpm/tpm_passthrough.c @@ -33,6 +33,7 @@ #include "hw/i386/pc.h" #include "sysemu/tpm_backend_int.h" #include "tpm_tis.h" +#include "tpm_util.h" #define DEBUG_TPM 0 @@ -69,6 +70,8 @@ struct TPMPassthruState { bool tpm_op_canceled; int cancel_fd; bool had_startup_error; + + TPMVersion tpm_version; }; typedef struct TPMPassthruState TPMPassthruState; @@ -333,59 +336,9 @@ static const char *tpm_passthrough_create_desc(void) static TPMVersion tpm_passthrough_get_tpm_version(TPMBackend *tb) { - return TPM_VERSION_1_2; -} - -/* - * A basic test of a TPM device. We expect a well formatted response header - * (error response is fine) within one second. - */ -static int tpm_passthrough_test_tpmdev(int fd) -{ - struct tpm_req_hdr req = { - .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND), - .len = cpu_to_be32(sizeof(req)), - .ordinal = cpu_to_be32(TPM_ORD_GetTicks), - }; - struct tpm_resp_hdr *resp; - fd_set readfds; - int n; - struct timeval tv = { - .tv_sec = 1, - .tv_usec = 0, - }; - unsigned char buf[1024]; - - n = write(fd, &req, sizeof(req)); - if (n < 0) { - return errno; - } - if (n != sizeof(req)) { - return EFAULT; - } - - FD_ZERO(&readfds); - FD_SET(fd, &readfds); - - /* wait for a second */ - n = select(fd + 1, &readfds, NULL, NULL, &tv); - if (n != 1) { - return errno; - } - - n = read(fd, &buf, sizeof(buf)); - if (n < sizeof(struct tpm_resp_hdr)) { - return EFAULT; - } - - resp = (struct tpm_resp_hdr *)buf; - /* check the header */ - if (be16_to_cpu(resp->tag) != TPM_TAG_RSP_COMMAND || - be32_to_cpu(resp->len) != n) { - return EBADMSG; - } + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); - return 0; + return tpm_pt->tpm_version; } /* @@ -455,7 +408,7 @@ static int tpm_passthrough_handle_device_opts(QemuOpts *opts, TPMBackend *tb) goto err_free_parameters; } - if (tpm_passthrough_test_tpmdev(tpm_pt->tpm_fd)) { + if (tpm_util_test_tpmdev(tpm_pt->tpm_fd, &tpm_pt->tpm_version)) { error_report("'%s' is not a TPM device.", tpm_pt->tpm_dev); goto err_close_tpmdev; diff --git a/hw/tpm/tpm_util.c b/hw/tpm/tpm_util.c new file mode 100644 index 0000000000..4ace5852e0 --- /dev/null +++ b/hw/tpm/tpm_util.c @@ -0,0 +1,126 @@ +/* + * TPM utility functions + * + * Copyright (c) 2010 - 2015 IBM Corporation + * Authors: + * Stefan Berger + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + */ + +#include "tpm_util.h" +#include "tpm_int.h" + +/* + * A basic test of a TPM device. We expect a well formatted response header + * (error response is fine) within one second. + */ +static int tpm_util_test(int fd, + unsigned char *request, + size_t requestlen, + uint16_t *return_tag) +{ + struct tpm_resp_hdr *resp; + fd_set readfds; + int n; + struct timeval tv = { + .tv_sec = 1, + .tv_usec = 0, + }; + unsigned char buf[1024]; + + n = write(fd, request, requestlen); + if (n < 0) { + return errno; + } + if (n != requestlen) { + return EFAULT; + } + + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + + /* wait for a second */ + n = select(fd + 1, &readfds, NULL, NULL, &tv); + if (n != 1) { + return errno; + } + + n = read(fd, &buf, sizeof(buf)); + if (n < sizeof(struct tpm_resp_hdr)) { + return EFAULT; + } + + resp = (struct tpm_resp_hdr *)buf; + /* check the header */ + if (be32_to_cpu(resp->len) != n) { + return EBADMSG; + } + + *return_tag = be16_to_cpu(resp->tag); + + return 0; +} + +/* + * Probe for the TPM device in the back + * Returns 0 on success with the version of the probed TPM set, 1 on failure. + */ +int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version) +{ + /* + * Sending a TPM1.2 command to a TPM2 should return a TPM1.2 + * header (tag = 0xc4) and error code (TPM_BADTAG = 0x1e) + * + * Sending a TPM2 command to a TPM 2 will give a TPM 2 tag in the + * header. + * Sending a TPM2 command to a TPM 1.2 will give a TPM 1.2 tag + * in the header and an error code. + */ + const struct tpm_req_hdr test_req = { + .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND), + .len = cpu_to_be32(sizeof(test_req)), + .ordinal = cpu_to_be32(TPM_ORD_GetTicks), + }; + + const struct tpm_req_hdr test_req_tpm2 = { + .tag = cpu_to_be16(TPM2_ST_NO_SESSIONS), + .len = cpu_to_be32(sizeof(test_req_tpm2)), + .ordinal = cpu_to_be32(TPM2_CC_ReadClock), + }; + uint16_t return_tag; + int ret; + + /* Send TPM 2 command */ + ret = tpm_util_test(tpm_fd, (unsigned char *)&test_req_tpm2, + sizeof(test_req_tpm2), &return_tag); + /* TPM 2 would respond with a tag of TPM2_ST_NO_SESSIONS */ + if (!ret && return_tag == TPM2_ST_NO_SESSIONS) { + *tpm_version = TPM_VERSION_2_0; + return 0; + } + + /* Send TPM 1.2 command */ + ret = tpm_util_test(tpm_fd, (unsigned char *)&test_req, + sizeof(test_req), &return_tag); + if (!ret && return_tag == TPM_TAG_RSP_COMMAND) { + *tpm_version = TPM_VERSION_1_2; + /* this is a TPM 1.2 */ + return 0; + } + + *tpm_version = TPM_VERSION_UNSPEC; + + return 1; +} diff --git a/hw/tpm/tpm_util.h b/hw/tpm/tpm_util.h new file mode 100644 index 0000000000..e7f354a52d --- /dev/null +++ b/hw/tpm/tpm_util.h @@ -0,0 +1,28 @@ +/* + * TPM utility functions + * + * Copyright (c) 2010 - 2015 IBM Corporation + * Authors: + * Stefan Berger + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + */ +#ifndef TPM_TPM_UTILS_H +#define TPM_TPM_UTILS_H + +#include "sysemu/tpm_backend.h" + +int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version); + +#endif /* TPM_TPM_UTILS_H */ -- cgit v1.2.3 From 5cb18b3d7bff2a83275ee98af2a14eb9e21c93ab Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Tue, 26 May 2015 16:51:07 -0400 Subject: TPM2 ACPI table support Add a TPM2 ACPI table if a TPM 2 is used in the backend. Also add an SSDT for the TPM 2. Rename tpm_find() to tpm_get_version() and have this function return the version of the TPM found, TPMVersion_Unspec if no TPM is found. Use the version number to build version specific ACPI tables. Signed-off-by: Stefan Berger Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/Makefile.objs | 2 +- hw/i386/acpi-build.c | 38 ++++++++++++-- hw/i386/ssdt-tpm.dsl | 16 +----- hw/i386/ssdt-tpm.hex.generated | 26 +++++++--- hw/i386/ssdt-tpm2.dsl | 29 +++++++++++ hw/i386/ssdt-tpm2.hex.generated | 109 ++++++++++++++++++++++++++++++++++++++++ hw/tpm/tpm_tis.c | 11 ++++ include/hw/acpi/acpi-defs.h | 18 +++++++ include/hw/acpi/tpm.h | 5 ++ include/sysemu/tpm.h | 11 +++- 10 files changed, 237 insertions(+), 28 deletions(-) create mode 100644 hw/i386/ssdt-tpm2.dsl create mode 100644 hw/i386/ssdt-tpm2.hex.generated diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index e058a39147..0be5d97c59 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -9,7 +9,7 @@ obj-y += kvmvapic.o obj-y += acpi-build.o hw/i386/acpi-build.o: hw/i386/acpi-build.c \ hw/i386/acpi-dsdt.hex hw/i386/q35-acpi-dsdt.hex \ - hw/i386/ssdt-tpm.hex + hw/i386/ssdt-tpm.hex hw/i386/ssdt-tpm2.hex iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \ ; then echo "$(2)"; else echo "$(3)"; fi ;) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 283d02e7a7..2c7399b9db 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -41,6 +41,7 @@ #include "hw/acpi/memory_hotplug.h" #include "sysemu/tpm.h" #include "hw/acpi/tpm.h" +#include "sysemu/tpm_backend.h" /* Supported chipsets: */ #include "hw/acpi/piix4.h" @@ -106,7 +107,7 @@ typedef struct AcpiPmInfo { typedef struct AcpiMiscInfo { bool has_hpet; - bool has_tpm; + TPMVersion tpm_version; const unsigned char *dsdt_code; unsigned dsdt_size; uint16_t pvpanic_port; @@ -234,7 +235,7 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) static void acpi_get_misc_info(AcpiMiscInfo *info) { info->has_hpet = hpet_find(); - info->has_tpm = tpm_find(); + info->tpm_version = tpm_get_version(); info->pvpanic_port = pvpanic_port(); info->applesmc_io_base = applesmc_port(); } @@ -414,6 +415,7 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu, } #include "hw/i386/ssdt-tpm.hex" +#include "hw/i386/ssdt-tpm2.hex" /* Assign BSEL property to all buses. In the future, this can be changed * to only assign to buses that support hotplug. @@ -1029,6 +1031,25 @@ build_tpm_ssdt(GArray *table_data, GArray *linker) memcpy(tpm_ptr, ssdt_tpm_aml, sizeof(ssdt_tpm_aml)); } +static void +build_tpm2(GArray *table_data, GArray *linker) +{ + Acpi20TPM2 *tpm2_ptr; + void *tpm_ptr; + + tpm_ptr = acpi_data_push(table_data, sizeof(ssdt_tpm2_aml)); + memcpy(tpm_ptr, ssdt_tpm2_aml, sizeof(ssdt_tpm2_aml)); + + tpm2_ptr = acpi_data_push(table_data, sizeof *tpm2_ptr); + + tpm2_ptr->platform_class = cpu_to_le16(TPM2_ACPI_CLASS_CLIENT); + tpm2_ptr->control_area_address = cpu_to_le64(0); + tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO); + + build_header(linker, table_data, + (void *)tpm2_ptr, "TPM2", sizeof(*tpm2_ptr), 4); +} + typedef enum { MEM_AFFINITY_NOFLAGS = 0, MEM_AFFINITY_ENABLED = (1 << 0), @@ -1343,12 +1364,21 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables) acpi_add_table(table_offsets, tables_blob); build_hpet(tables_blob, tables->linker); } - if (misc.has_tpm) { + if (misc.tpm_version != TPM_VERSION_UNSPEC) { acpi_add_table(table_offsets, tables_blob); build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog); acpi_add_table(table_offsets, tables_blob); - build_tpm_ssdt(tables_blob, tables->linker); + switch (misc.tpm_version) { + case TPM_VERSION_1_2: + build_tpm_ssdt(tables_blob, tables->linker); + break; + case TPM_VERSION_2_0: + build_tpm2(tables_blob, tables->linker); + break; + default: + assert(false); + } } if (guest_info->numa_nodes) { acpi_add_table(table_offsets, tables_blob); diff --git a/hw/i386/ssdt-tpm.dsl b/hw/i386/ssdt-tpm.dsl index 75d96910bf..d81478c1b5 100644 --- a/hw/i386/ssdt-tpm.dsl +++ b/hw/i386/ssdt-tpm.dsl @@ -25,19 +25,5 @@ DefinitionBlock ( 0x1 // OEM Revision ) { - Scope(\_SB) { - /* TPM with emulated TPM TIS interface */ - Device (TPM) { - Name (_HID, EisaID ("PNP0C31")) - Name (_CRS, ResourceTemplate () - { - Memory32Fixed (ReadWrite, TPM_TIS_ADDR_BASE, TPM_TIS_ADDR_SIZE) - // older Linux tpm_tis drivers do not work with IRQ - //IRQNoFlags () {TPM_TIS_IRQ} - }) - Method (_STA, 0, NotSerialized) { - Return (0x0F) - } - } - } +#include "ssdt-tpm-common.dsl" } diff --git a/hw/i386/ssdt-tpm.hex.generated b/hw/i386/ssdt-tpm.hex.generated index e84dc6cfc0..874418c946 100644 --- a/hw/i386/ssdt-tpm.hex.generated +++ b/hw/i386/ssdt-tpm.hex.generated @@ -3,12 +3,12 @@ static unsigned char ssdt_tpm_aml[] = { 0x53, 0x44, 0x54, -0x5d, +0x6b, 0x0, 0x0, 0x0, 0x1, -0x1c, +0x37, 0x42, 0x58, 0x50, @@ -36,15 +36,26 @@ static unsigned char ssdt_tpm_aml[] = { 0x14, 0x20, 0x10, -0x38, +0x46, +0x4, 0x5c, +0x2f, +0x3, 0x5f, 0x53, 0x42, 0x5f, +0x50, +0x43, +0x49, +0x30, +0x49, +0x53, +0x41, +0x5f, 0x5b, 0x82, -0x30, +0x33, 0x54, 0x50, 0x4d, @@ -65,9 +76,9 @@ static unsigned char ssdt_tpm_aml[] = { 0x52, 0x53, 0x11, -0x11, +0x14, 0xa, -0xe, +0x11, 0x86, 0x9, 0x0, @@ -80,6 +91,9 @@ static unsigned char ssdt_tpm_aml[] = { 0x50, 0x0, 0x0, +0x22, +0x20, +0x0, 0x79, 0x0, 0x14, diff --git a/hw/i386/ssdt-tpm2.dsl b/hw/i386/ssdt-tpm2.dsl new file mode 100644 index 0000000000..58bbbf806d --- /dev/null +++ b/hw/i386/ssdt-tpm2.dsl @@ -0,0 +1,29 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ +#include "hw/acpi/tpm.h" + +ACPI_EXTRACT_ALL_CODE ssdt_tpm2_aml + +DefinitionBlock ( + "ssdt-tpm2.aml", // Output Filename + "SSDT", // Signature + 0x01, // SSDT Compliance Revision + "BXPC", // OEMID + "BXSSDT", // TABLE ID + 0x1 // OEM Revision + ) +{ +#include "ssdt-tpm-common.dsl" +} diff --git a/hw/i386/ssdt-tpm2.hex.generated b/hw/i386/ssdt-tpm2.hex.generated new file mode 100644 index 0000000000..9ea827151a --- /dev/null +++ b/hw/i386/ssdt-tpm2.hex.generated @@ -0,0 +1,109 @@ +static unsigned char ssdt_tpm2_aml[] = { +0x53, +0x53, +0x44, +0x54, +0x6b, +0x0, +0x0, +0x0, +0x1, +0x37, +0x42, +0x58, +0x50, +0x43, +0x0, +0x0, +0x42, +0x58, +0x53, +0x53, +0x44, +0x54, +0x0, +0x0, +0x1, +0x0, +0x0, +0x0, +0x49, +0x4e, +0x54, +0x4c, +0x7, +0x11, +0x14, +0x20, +0x10, +0x46, +0x4, +0x5c, +0x2f, +0x3, +0x5f, +0x53, +0x42, +0x5f, +0x50, +0x43, +0x49, +0x30, +0x49, +0x53, +0x41, +0x5f, +0x5b, +0x82, +0x33, +0x54, +0x50, +0x4d, +0x5f, +0x8, +0x5f, +0x48, +0x49, +0x44, +0xc, +0x41, +0xd0, +0xc, +0x31, +0x8, +0x5f, +0x43, +0x52, +0x53, +0x11, +0x14, +0xa, +0x11, +0x86, +0x9, +0x0, +0x1, +0x0, +0x0, +0xd4, +0xfe, +0x0, +0x50, +0x0, +0x0, +0x22, +0x20, +0x0, +0x79, +0x0, +0x14, +0x9, +0x5f, +0x53, +0x54, +0x41, +0x0, +0xa4, +0xa, +0xf +}; diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c index e8047571c1..0806b5f82e 100644 --- a/hw/tpm/tpm_tis.c +++ b/hw/tpm/tpm_tis.c @@ -32,6 +32,7 @@ #include "tpm_tis.h" #include "qemu-common.h" #include "qemu/main-loop.h" +#include "sysemu/tpm_backend.h" #define DEBUG_TIS 0 @@ -961,6 +962,16 @@ static int tpm_tis_do_startup_tpm(TPMState *s) return tpm_backend_startup_tpm(s->be_driver); } +/* + * Get the TPMVersion of the backend device being used + */ +TPMVersion tpm_tis_get_tpm_version(Object *obj) +{ + TPMState *s = TPM(obj); + + return tpm_backend_get_tpm_version(s->be_driver); +} + /* * This function is called when the machine starts, resets or due to * S3 resume. diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h index f503ec4a97..59cf277434 100644 --- a/include/hw/acpi/acpi-defs.h +++ b/include/hw/acpi/acpi-defs.h @@ -450,6 +450,9 @@ typedef struct AcpiTableMcfg AcpiTableMcfg; /* * TCPA Description Table + * + * Following Level 00, Rev 00.37 of specs: + * http://www.trustedcomputinggroup.org/resources/tcg_acpi_specification */ struct Acpi20Tcpa { ACPI_TABLE_HEADER_DEF /* ACPI common table header */ @@ -459,6 +462,21 @@ struct Acpi20Tcpa { } QEMU_PACKED; typedef struct Acpi20Tcpa Acpi20Tcpa; +/* + * TPM2 + * + * Following Level 00, Rev 00.37 of specs: + * http://www.trustedcomputinggroup.org/resources/tcg_acpi_specification + */ +struct Acpi20TPM2 { + ACPI_TABLE_HEADER_DEF + uint16_t platform_class; + uint16_t reserved; + uint64_t control_area_address; + uint32_t start_method; +} QEMU_PACKED; +typedef struct Acpi20TPM2 Acpi20TPM2; + /* DMAR - DMA Remapping table r2.2 */ struct AcpiTableDmar { ACPI_TABLE_HEADER_DEF diff --git a/include/hw/acpi/tpm.h b/include/hw/acpi/tpm.h index 792fcbf5b1..6d516c6a7f 100644 --- a/include/hw/acpi/tpm.h +++ b/include/hw/acpi/tpm.h @@ -26,4 +26,9 @@ #define TPM_TCPA_ACPI_CLASS_CLIENT 0 #define TPM_TCPA_ACPI_CLASS_SERVER 1 +#define TPM2_ACPI_CLASS_CLIENT 0 +#define TPM2_ACPI_CLASS_SERVER 1 + +#define TPM2_START_METHOD_MMIO 6 + #endif /* HW_ACPI_TPM_H */ diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h index 848df412db..c1438907de 100644 --- a/include/sysemu/tpm.h +++ b/include/sysemu/tpm.h @@ -26,11 +26,18 @@ typedef enum TPMVersion { TPM_VERSION_2_0 = 2, } TPMVersion; +TPMVersion tpm_tis_get_tpm_version(Object *obj); + #define TYPE_TPM_TIS "tpm-tis" -static inline bool tpm_find(void) +static inline TPMVersion tpm_get_version(void) { - return object_resolve_path_type("", TYPE_TPM_TIS, NULL); + Object *obj = object_resolve_path_type("", TYPE_TPM_TIS, NULL); + + if (obj) { + return tpm_tis_get_tpm_version(obj); + } + return TPM_VERSION_UNSPEC; } #endif /* QEMU_TPM_H */ -- cgit v1.2.3 From c08cf0704247aa55e9b0bb14cf34d845629e0e3e Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Mon, 25 May 2015 18:33:40 +0300 Subject: acpi: add aml_add() term Add encoding for ACPI DefAdd Opcode. Reviewed-by: Igor Mammedov Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Shannon Zhao --- hw/acpi/aml-build.c | 10 ++++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 11 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 4cc0c61fa7..f29c71a4fd 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -455,6 +455,16 @@ Aml *aml_or(Aml *arg1, Aml *arg2) return var; } +/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAdd */ +Aml *aml_add(Aml *arg1, Aml *arg2) +{ + Aml *var = aml_opcode(0x72 /* AddOp */); + aml_append(var, arg1); + aml_append(var, arg2); + build_append_byte(var->buf, 0x00 /* NullNameOp */); + return var; +} + /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */ Aml *aml_notify(Aml *arg1, Aml *arg2) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 9773bfd06b..42448ae111 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -202,6 +202,7 @@ Aml *aml_arg(int pos); Aml *aml_store(Aml *val, Aml *target); Aml *aml_and(Aml *arg1, Aml *arg2); Aml *aml_or(Aml *arg1, Aml *arg2); +Aml *aml_add(Aml *arg1, Aml *arg2); Aml *aml_notify(Aml *arg1, Aml *arg2); Aml *aml_call1(const char *method, Aml *arg1); Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2); -- cgit v1.2.3 From 96396e2858fd8a0b4ee218c9894b5a67d22d97d9 Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Mon, 25 May 2015 18:33:41 +0300 Subject: acpi: add aml_lless() term Add encoding for ACPI DefLLess Opcode. Reviewed-by: Shannon Zhao Reviewed-by: Igor Mammedov Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 9 +++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 10 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index f29c71a4fd..5e95098e88 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -455,6 +455,15 @@ Aml *aml_or(Aml *arg1, Aml *arg2) return var; } +/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLLess */ +Aml *aml_lless(Aml *arg1, Aml *arg2) +{ + Aml *var = aml_opcode(0x95 /* LLessOp */); + aml_append(var, arg1); + aml_append(var, arg2); + return var; +} + /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAdd */ Aml *aml_add(Aml *arg1, Aml *arg2) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 42448ae111..3007cb561a 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -202,6 +202,7 @@ Aml *aml_arg(int pos); Aml *aml_store(Aml *val, Aml *target); Aml *aml_and(Aml *arg1, Aml *arg2); Aml *aml_or(Aml *arg1, Aml *arg2); +Aml *aml_lless(Aml *arg1, Aml *arg2); Aml *aml_add(Aml *arg1, Aml *arg2); Aml *aml_notify(Aml *arg1, Aml *arg2); Aml *aml_call1(const char *method, Aml *arg1); -- cgit v1.2.3 From 928b8996576875f9364f77c5a41f12cd55c7b9f7 Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Mon, 25 May 2015 18:33:42 +0300 Subject: acpi: add aml_index() term Add encoding for ACPI DefIndex Opcode. Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Shannon Zhao --- hw/acpi/aml-build.c | 10 ++++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 11 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 5e95098e88..ea70f43d65 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -474,6 +474,16 @@ Aml *aml_add(Aml *arg1, Aml *arg2) return var; } +/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIndex */ +Aml *aml_index(Aml *arg1, Aml *idx) +{ + Aml *var = aml_opcode(0x88 /* IndexOp */); + aml_append(var, arg1); + aml_append(var, idx); + build_append_byte(var->buf, 0x00 /* NullNameOp */); + return var; +} + /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */ Aml *aml_notify(Aml *arg1, Aml *arg2) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 3007cb561a..d0de08f9ab 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -204,6 +204,7 @@ Aml *aml_and(Aml *arg1, Aml *arg2); Aml *aml_or(Aml *arg1, Aml *arg2); Aml *aml_lless(Aml *arg1, Aml *arg2); Aml *aml_add(Aml *arg1, Aml *arg2); +Aml *aml_index(Aml *arg1, Aml *idx); Aml *aml_notify(Aml *arg1, Aml *arg2); Aml *aml_call1(const char *method, Aml *arg1); Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2); -- cgit v1.2.3 From a57dddddd2f93b87852fac2ed41a31c45e6d192a Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Mon, 25 May 2015 18:33:43 +0300 Subject: acpi: add aml_shiftleft() term Add encoding for ACPI DefShiftLeft Opcode. Reviewed-by: Igor Mammedov Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Shannon Zhao --- hw/acpi/aml-build.c | 10 ++++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 11 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index ea70f43d65..5c140e04c9 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -455,6 +455,16 @@ Aml *aml_or(Aml *arg1, Aml *arg2) return var; } +/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftLeft */ +Aml *aml_shiftleft(Aml *arg1, Aml *count) +{ + Aml *var = aml_opcode(0x79 /* ShiftLeftOp */); + aml_append(var, arg1); + aml_append(var, count); + build_append_byte(var->buf, 0x00); /* NullNameOp */ + return var; +} + /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLLess */ Aml *aml_lless(Aml *arg1, Aml *arg2) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index d0de08f9ab..f2100cb7fd 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -202,6 +202,7 @@ Aml *aml_arg(int pos); Aml *aml_store(Aml *val, Aml *target); Aml *aml_and(Aml *arg1, Aml *arg2); Aml *aml_or(Aml *arg1, Aml *arg2); +Aml *aml_shiftleft(Aml *arg1, Aml *count); Aml *aml_lless(Aml *arg1, Aml *arg2); Aml *aml_add(Aml *arg1, Aml *arg2); Aml *aml_index(Aml *arg1, Aml *idx); -- cgit v1.2.3 From f7bd7b8eb6573ed22bfc51e148455a1c0a1e36d0 Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Mon, 25 May 2015 18:33:44 +0300 Subject: acpi: add aml_shiftright() term Add encoding for ACPI DefShiftRight Opcode. Reviewed-by: Igor Mammedov Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Shannon Zhao --- hw/acpi/aml-build.c | 10 ++++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 11 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 5c140e04c9..045a4e2ee3 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -465,6 +465,16 @@ Aml *aml_shiftleft(Aml *arg1, Aml *count) return var; } +/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftRight */ +Aml *aml_shiftright(Aml *arg1, Aml *count) +{ + Aml *var = aml_opcode(0x7A /* ShiftRightOp */); + aml_append(var, arg1); + aml_append(var, count); + build_append_byte(var->buf, 0x00); /* NullNameOp */ + return var; +} + /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLLess */ Aml *aml_lless(Aml *arg1, Aml *arg2) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index f2100cb7fd..9abb4c39d1 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -203,6 +203,7 @@ Aml *aml_store(Aml *val, Aml *target); Aml *aml_and(Aml *arg1, Aml *arg2); Aml *aml_or(Aml *arg1, Aml *arg2); Aml *aml_shiftleft(Aml *arg1, Aml *count); +Aml *aml_shiftright(Aml *arg1, Aml *count); Aml *aml_lless(Aml *arg1, Aml *arg2); Aml *aml_add(Aml *arg1, Aml *arg2); Aml *aml_index(Aml *arg1, Aml *idx); -- cgit v1.2.3 From af39d5363f373e6c1168a0e84658d6e4ef57fa8c Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Mon, 25 May 2015 18:33:45 +0300 Subject: acpi: add aml_increment() term Add encoding for ACPI DefIncrement Opcode. Reviewed-by: Shannon Zhao Reviewed-by: Igor Mammedov Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 8 ++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 9 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 045a4e2ee3..f26466aedd 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -494,6 +494,14 @@ Aml *aml_add(Aml *arg1, Aml *arg2) return var; } +/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIncrement */ +Aml *aml_increment(Aml *arg) +{ + Aml *var = aml_opcode(0x75 /* IncrementOp */); + aml_append(var, arg); + return var; +} + /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIndex */ Aml *aml_index(Aml *arg1, Aml *idx) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 9abb4c39d1..1a891a20da 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -206,6 +206,7 @@ Aml *aml_shiftleft(Aml *arg1, Aml *count); Aml *aml_shiftright(Aml *arg1, Aml *count); Aml *aml_lless(Aml *arg1, Aml *arg2); Aml *aml_add(Aml *arg1, Aml *arg2); +Aml *aml_increment(Aml *arg); Aml *aml_index(Aml *arg1, Aml *idx); Aml *aml_notify(Aml *arg1, Aml *arg2); Aml *aml_call1(const char *method, Aml *arg1); -- cgit v1.2.3 From 68e6b0af784dda4efd9d4e2e9d3b03a31ca1408c Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Mon, 25 May 2015 18:33:46 +0300 Subject: acpi: add aml_while() term Add encoding for ACPI DefWhile Opcode. Reviewed-by: Shannon Zhao Reviewed-by: Igor Mammedov Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/acpi/aml-build.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 1a891a20da..e3afa13678 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -266,6 +266,7 @@ Aml *aml_device(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_method(const char *name, int arg_count); Aml *aml_if(Aml *predicate); Aml *aml_else(void); +Aml *aml_while(Aml *predicate); Aml *aml_package(uint8_t num_elements); Aml *aml_buffer(int buffer_size, uint8_t *byte_list); Aml *aml_resource_template(void); -- cgit v1.2.3 From afcf905cff7971324c2706600ead35a1f41f417a Mon Sep 17 00:00:00 2001 From: Shannon Zhao Date: Mon, 25 May 2015 15:14:37 +0800 Subject: hw/acpi/aml-build: Fix memory leak Signed-off-by: Shannon Zhao Signed-off-by: Shannon Zhao Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov --- hw/acpi/aml-build.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index f26466aedd..2bebf23db2 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -296,6 +296,7 @@ static void aml_free(gpointer data, gpointer user_data) { Aml *var = data; build_free_array(var->buf); + g_free(var); } Aml *init_aml_allocator(void) -- cgit v1.2.3 From 434027badb421863b85ffdb4769966533c001cfa Mon Sep 17 00:00:00 2001 From: Ying-Shiuan Pan Date: Tue, 12 May 2015 11:10:50 +0300 Subject: virtio-mmio: ioeventfd support set_host_notifier and set_guest_notifiers supported by virtio-mmio now. Most code copied from virtio-pci. This makes it possible to use vhost-net with virtio-mmio, improving performance by about 30%. The kvm-arm does not yet support irqfd, need to fix the hard-coded part after kvm-arm gets irqfd support. Signed-off-by: Ying-Shiuan Pan Signed-off-by: Pavel Fedin Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio-mmio.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index a3cfd305ce..c8f72947d4 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -22,7 +22,9 @@ #include "hw/sysbus.h" #include "hw/virtio/virtio.h" #include "qemu/host-utils.h" +#include "sysemu/kvm.h" #include "hw/virtio/virtio-bus.h" +#include "qemu/error-report.h" /* #define DEBUG_VIRTIO_MMIO */ @@ -86,8 +88,96 @@ typedef struct { uint32_t guest_page_shift; /* virtio-bus */ VirtioBusState bus; + bool ioeventfd_disabled; + bool ioeventfd_started; } VirtIOMMIOProxy; +static int virtio_mmio_set_host_notifier_internal(VirtIOMMIOProxy *proxy, + int n, bool assign, + bool set_handler) +{ + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + VirtQueue *vq = virtio_get_queue(vdev, n); + EventNotifier *notifier = virtio_queue_get_host_notifier(vq); + int r = 0; + + if (assign) { + r = event_notifier_init(notifier, 1); + if (r < 0) { + error_report("%s: unable to init event notifier: %d", + __func__, r); + return r; + } + virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler); + memory_region_add_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUENOTIFY, 4, + true, n, notifier); + } else { + memory_region_del_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUENOTIFY, 4, + true, n, notifier); + virtio_queue_set_host_notifier_fd_handler(vq, false, false); + event_notifier_cleanup(notifier); + } + return r; +} + +static void virtio_mmio_start_ioeventfd(VirtIOMMIOProxy *proxy) +{ + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + int n, r; + + if (!kvm_eventfds_enabled() || + proxy->ioeventfd_disabled || + proxy->ioeventfd_started) { + return; + } + + for (n = 0; n < VIRTIO_QUEUE_MAX; n++) { + if (!virtio_queue_get_num(vdev, n)) { + continue; + } + + r = virtio_mmio_set_host_notifier_internal(proxy, n, true, true); + if (r < 0) { + goto assign_error; + } + } + proxy->ioeventfd_started = true; + return; + +assign_error: + while (--n >= 0) { + if (!virtio_queue_get_num(vdev, n)) { + continue; + } + + r = virtio_mmio_set_host_notifier_internal(proxy, n, false, false); + assert(r >= 0); + } + proxy->ioeventfd_started = false; + error_report("%s: failed. Fallback to a userspace (slower).", __func__); +} + +static void virtio_mmio_stop_ioeventfd(VirtIOMMIOProxy *proxy) +{ + int r; + int n; + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + + if (!proxy->ioeventfd_started) { + return; + } + + for (n = 0; n < VIRTIO_QUEUE_MAX; n++) { + if (!virtio_queue_get_num(vdev, n)) { + continue; + } + + r = virtio_mmio_set_host_notifier_internal(proxy, n, false, false); + assert(r >= 0); + } + proxy->ioeventfd_started = false; +} + static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size) { VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque; @@ -265,7 +355,16 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value, virtio_update_irq(vdev); break; case VIRTIO_MMIO_STATUS: + if (!(value & VIRTIO_CONFIG_S_DRIVER_OK)) { + virtio_mmio_stop_ioeventfd(proxy); + } + virtio_set_status(vdev, value & 0xff); + + if (value & VIRTIO_CONFIG_S_DRIVER_OK) { + virtio_mmio_start_ioeventfd(proxy); + } + if (vdev->status == 0) { virtio_reset(vdev); } @@ -328,12 +427,92 @@ static void virtio_mmio_reset(DeviceState *d) { VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d); + virtio_mmio_stop_ioeventfd(proxy); virtio_bus_reset(&proxy->bus); proxy->host_features_sel = 0; proxy->guest_features_sel = 0; proxy->guest_page_shift = 0; } +static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign, + bool with_irqfd) +{ + VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d); + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); + VirtQueue *vq = virtio_get_queue(vdev, n); + EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); + + if (assign) { + int r = event_notifier_init(notifier, 0); + if (r < 0) { + return r; + } + virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd); + } else { + virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd); + event_notifier_cleanup(notifier); + } + + if (vdc->guest_notifier_mask) { + vdc->guest_notifier_mask(vdev, n, !assign); + } + + return 0; +} + +static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs, + bool assign) +{ + VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d); + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + /* TODO: need to check if kvm-arm supports irqfd */ + bool with_irqfd = false; + int r, n; + + nvqs = MIN(nvqs, VIRTIO_QUEUE_MAX); + + for (n = 0; n < nvqs; n++) { + if (!virtio_queue_get_num(vdev, n)) { + break; + } + + r = virtio_mmio_set_guest_notifier(d, n, assign, with_irqfd); + if (r < 0) { + goto assign_error; + } + } + + return 0; + +assign_error: + /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */ + assert(assign); + while (--n >= 0) { + virtio_mmio_set_guest_notifier(d, n, !assign, false); + } + return r; +} + +static int virtio_mmio_set_host_notifier(DeviceState *opaque, int n, + bool assign) +{ + VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque); + + /* Stop using ioeventfd for virtqueue kick if the device starts using host + * notifiers. This makes it easy to avoid stepping on each others' toes. + */ + proxy->ioeventfd_disabled = assign; + if (assign) { + virtio_mmio_stop_ioeventfd(proxy); + } + /* We don't need to start here: it's not needed because backend + * currently only stops on status change away from ok, + * reset, vmstop and such. If we do add code to start here, + * need to check vmstate, device state etc. */ + return virtio_mmio_set_host_notifier_internal(proxy, n, assign, false); +} + /* virtio-mmio device */ static void virtio_mmio_realizefn(DeviceState *d, Error **errp) @@ -375,6 +554,8 @@ static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data) k->notify = virtio_mmio_update_irq; k->save_config = virtio_mmio_save_config; k->load_config = virtio_mmio_load_config; + k->set_host_notifier = virtio_mmio_set_host_notifier; + k->set_guest_notifiers = virtio_mmio_set_guest_notifiers; k->has_variable_vring_alignment = true; bus_class->max_dev = 1; } -- cgit v1.2.3 From fdba6d967e00864edd21275a6ee1d23a383510e8 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 1 Jun 2015 10:45:39 +0200 Subject: qdev: add 64bit properties Needed for virtio features which go from 32bit to 64bit with virtio 1.0 Signed-off-by: Gerd Hoffmann Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/core/qdev-properties.c | 58 ++++++++++++++++++++++++++++++++++++++++++++ include/hw/qdev-properties.h | 10 ++++++++ 2 files changed, 68 insertions(+) diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 570d5f0bad..a1606deaca 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -125,6 +125,64 @@ PropertyInfo qdev_prop_bit = { .set = prop_set_bit, }; +/* Bit64 */ + +static uint64_t qdev_get_prop_mask64(Property *prop) +{ + assert(prop->info == &qdev_prop_bit); + return 0x1 << prop->bitnr; +} + +static void bit64_prop_set(DeviceState *dev, Property *props, bool val) +{ + uint64_t *p = qdev_get_prop_ptr(dev, props); + uint64_t mask = qdev_get_prop_mask64(props); + if (val) { + *p |= mask; + } else { + *p &= ~mask; + } +} + +static void prop_get_bit64(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + uint64_t *p = qdev_get_prop_ptr(dev, prop); + bool value = (*p & qdev_get_prop_mask64(prop)) != 0; + + visit_type_bool(v, &value, name, errp); +} + +static void prop_set_bit64(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + Error *local_err = NULL; + bool value; + + if (dev->realized) { + qdev_prop_set_after_realize(dev, name, errp); + return; + } + + visit_type_bool(v, &value, name, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + bit64_prop_set(dev, prop, value); +} + +PropertyInfo qdev_prop_bit64 = { + .name = "bool", + .description = "on/off", + .get = prop_get_bit64, + .set = prop_set_bit64, +}; + /* --- bool --- */ static void get_bool(Object *obj, Visitor *v, void *opaque, diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index d67dad5f77..0cfff1c77c 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -6,6 +6,7 @@ /*** qdev-properties.c ***/ extern PropertyInfo qdev_prop_bit; +extern PropertyInfo qdev_prop_bit64; extern PropertyInfo qdev_prop_bool; extern PropertyInfo qdev_prop_uint8; extern PropertyInfo qdev_prop_uint16; @@ -50,6 +51,15 @@ extern PropertyInfo qdev_prop_arraylen; .qtype = QTYPE_QBOOL, \ .defval = (bool)_defval, \ } +#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) { \ + .name = (_name), \ + .info = &(qdev_prop_bit), \ + .bitnr = (_bit), \ + .offset = offsetof(_state, _field) \ + + type_check(uint64_t, typeof_field(_state, _field)), \ + .qtype = QTYPE_QBOOL, \ + .defval = (bool)_defval, \ + } #define DEFINE_PROP_BOOL(_name, _state, _field, _defval) { \ .name = (_name), \ -- cgit v1.2.3 From 019a3edbb25f1571e876f8af1ce4c55412939e5d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 1 Jun 2015 10:45:40 +0200 Subject: virtio: make features 64bit wide Make features 64bit wide everywhere. On migration a full 64bit guest_features field is sent if one of the high bits is set, in addition to the lower 32bit guest_features field which must stay for compatibility reasons. That way we send the lower 32 feature bits twice, but the code is simpler because we don't have to split and compose the 64bit features into two 32bit fields. Signed-off-by: Gerd Hoffmann Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/9pfs/virtio-9p-device.c | 2 +- hw/block/virtio-blk.c | 2 +- hw/char/virtio-serial-bus.c | 2 +- hw/input/virtio-input.c | 2 +- hw/net/virtio-net.c | 18 +++++++++------- hw/scsi/vhost-scsi.c | 4 ++-- hw/scsi/virtio-scsi.c | 4 ++-- hw/virtio/virtio-balloon.c | 2 +- hw/virtio/virtio-rng.c | 2 +- hw/virtio/virtio.c | 51 +++++++++++++++++++++++++++++++++++++++------ include/hw/virtio/virtio.h | 32 ++++++++++++++-------------- 11 files changed, 81 insertions(+), 40 deletions(-) diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index 30492ecb02..60f9ff9a31 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -21,7 +21,7 @@ #include "virtio-9p-coth.h" #include "hw/virtio/virtio-access.h" -static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features) +static uint64_t virtio_9p_get_features(VirtIODevice *vdev, uint64_t features) { virtio_add_feature(&features, VIRTIO_9P_MOUNT_TAG); return features; diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index e6afe9763d..cd539aa11c 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -718,7 +718,7 @@ static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config) aio_context_release(blk_get_aio_context(s->blk)); } -static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features) +static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features) { VirtIOBlock *s = VIRTIO_BLK(vdev); diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index 333339ebb7..f893523ef1 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -498,7 +498,7 @@ static void handle_input(VirtIODevice *vdev, VirtQueue *vq) } } -static uint32_t get_features(VirtIODevice *vdev, uint32_t features) +static uint64_t get_features(VirtIODevice *vdev, uint64_t features) { VirtIOSerial *vser; diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c index e615c5cc7c..c4f4b3c150 100644 --- a/hw/input/virtio-input.c +++ b/hw/input/virtio-input.c @@ -166,7 +166,7 @@ static void virtio_input_set_config(VirtIODevice *vdev, virtio_notify_config(vdev); } -static uint32_t virtio_input_get_features(VirtIODevice *vdev, uint32_t f) +static uint64_t virtio_input_get_features(VirtIODevice *vdev, uint64_t f) { return f; } diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 6dca726021..012ab7fae8 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -435,7 +435,7 @@ static void virtio_net_set_queues(VirtIONet *n) static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue); -static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features) +static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features) { VirtIONet *n = VIRTIO_NET(vdev); NetClientState *nc = qemu_get_queue(n->nic); @@ -468,9 +468,9 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features) return vhost_net_get_features(get_vhost_net(nc->peer), features); } -static uint32_t virtio_net_bad_features(VirtIODevice *vdev) +static uint64_t virtio_net_bad_features(VirtIODevice *vdev) { - uint32_t features = 0; + uint64_t features = 0; /* Linux kernel 2.6.25. It understood MAC (as everyone must), * but also these: */ @@ -1032,10 +1032,12 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t if (i == 0) return -1; error_report("virtio-net unexpected empty queue: " - "i %zd mergeable %d offset %zd, size %zd, " - "guest hdr len %zd, host hdr len %zd guest features 0x%x", - i, n->mergeable_rx_bufs, offset, size, - n->guest_hdr_len, n->host_hdr_len, vdev->guest_features); + "i %zd mergeable %d offset %zd, size %zd, " + "guest hdr len %zd, host hdr len %zd " + "guest features 0x%" PRIx64, + i, n->mergeable_rx_bufs, offset, size, + n->guest_hdr_len, n->host_hdr_len, + vdev->guest_features); exit(1); } @@ -1518,7 +1520,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx, vdev, idx, mask); } -static void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features) +static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features) { int i, config_size = 0; virtio_add_feature(&host_features, VIRTIO_NET_F_MAC); diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index 335f4429a9..9c76486fa9 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -151,8 +151,8 @@ static void vhost_scsi_stop(VHostSCSI *s) vhost_dev_disable_notifiers(&s->dev, vdev); } -static uint32_t vhost_scsi_get_features(VirtIODevice *vdev, - uint32_t features) +static uint64_t vhost_scsi_get_features(VirtIODevice *vdev, + uint64_t features) { VHostSCSI *s = VHOST_SCSI(vdev); diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 5818159e64..b0dee295d8 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -628,8 +628,8 @@ static void virtio_scsi_set_config(VirtIODevice *vdev, vs->cdb_size = virtio_ldl_p(vdev, &scsiconf->cdb_size); } -static uint32_t virtio_scsi_get_features(VirtIODevice *vdev, - uint32_t requested_features) +static uint64_t virtio_scsi_get_features(VirtIODevice *vdev, + uint64_t requested_features) { VirtIOSCSI *s = VIRTIO_SCSI(vdev); diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index cfff542f38..f915c7bd73 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -310,7 +310,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev, trace_virtio_balloon_set_config(dev->actual, oldactual); } -static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f) +static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f) { f |= (1 << VIRTIO_BALLOON_F_STATS_VQ); return f; diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index 06e71782b2..420c39fb50 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -99,7 +99,7 @@ static void handle_input(VirtIODevice *vdev, VirtQueue *vq) virtio_rng_process(vrng); } -static uint32_t get_features(VirtIODevice *vdev, uint32_t f) +static uint64_t get_features(VirtIODevice *vdev, uint64_t f) { return f; } diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index a0637d9763..596e3d8aaf 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -906,6 +906,13 @@ static bool virtio_device_endian_needed(void *opaque) return vdev->device_endian != virtio_default_endian(); } +static bool virtio_64bit_features_needed(void *opaque) +{ + VirtIODevice *vdev = opaque; + + return (vdev->host_features >> 32) != 0; +} + static const VMStateDescription vmstate_virtio_device_endian = { .name = "virtio/device_endian", .version_id = 1, @@ -916,6 +923,16 @@ static const VMStateDescription vmstate_virtio_device_endian = { } }; +static const VMStateDescription vmstate_virtio_64bit_features = { + .name = "virtio/64bit_features", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT64(guest_features, VirtIODevice), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_virtio = { .name = "virtio", .version_id = 1, @@ -929,6 +946,10 @@ static const VMStateDescription vmstate_virtio = { .vmsd = &vmstate_virtio_device_endian, .needed = &virtio_device_endian_needed }, + { + .vmsd = &vmstate_virtio_64bit_features, + .needed = &virtio_64bit_features_needed + }, { 0 } } }; @@ -938,6 +959,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); + uint32_t guest_features_lo = (vdev->guest_features & 0xffffffff); int i; if (k->save_config) { @@ -947,7 +969,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) qemu_put_8s(f, &vdev->status); qemu_put_8s(f, &vdev->isr); qemu_put_be16s(f, &vdev->queue_sel); - qemu_put_be32s(f, &vdev->guest_features); + qemu_put_be32s(f, &guest_features_lo); qemu_put_be32(f, vdev->config_len); qemu_put_buffer(f, vdev->config, vdev->config_len); @@ -1024,11 +1046,6 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) } qemu_get_be32s(f, &features); - if (virtio_set_features(vdev, features) < 0) { - error_report("Features 0x%x unsupported. Allowed features: 0x%x", - features, vdev->host_features); - return -1; - } config_len = qemu_get_be32(f); /* @@ -1094,6 +1111,28 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) vdev->device_endian = virtio_default_endian(); } + if (virtio_64bit_features_needed(vdev)) { + /* + * Subsection load filled vdev->guest_features. Run them + * through virtio_set_features to sanity-check them against + * host_features. + */ + uint64_t features64 = vdev->guest_features; + if (virtio_set_features(vdev, features64) < 0) { + error_report("Features 0x%" PRIx64 " unsupported. " + "Allowed features: 0x%" PRIx64, + features64, vdev->host_features); + return -1; + } + } else { + if (virtio_set_features(vdev, features) < 0) { + error_report("Features 0x%x unsupported. " + "Allowed features: 0x%" PRIx64, + features, vdev->host_features); + return -1; + } + } + for (i = 0; i < num; i++) { if (vdev->vq[i].pa) { uint16_t nheads; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 45d6e5b01e..7222a904dc 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -73,8 +73,8 @@ struct VirtIODevice uint8_t status; uint8_t isr; uint16_t queue_sel; - uint32_t guest_features; - uint32_t host_features; + uint64_t guest_features; + uint64_t host_features; size_t config_len; void *config; uint16_t config_vector; @@ -96,8 +96,8 @@ typedef struct VirtioDeviceClass { /* This is what a VirtioDevice must implement */ DeviceRealize realize; DeviceUnrealize unrealize; - uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features); - uint32_t (*bad_features)(VirtIODevice *vdev); + uint64_t (*get_features)(VirtIODevice *vdev, uint64_t requested_features); + uint64_t (*bad_features)(VirtIODevice *vdev); void (*set_features)(VirtIODevice *vdev, uint32_t val); void (*get_config)(VirtIODevice *vdev, uint8_t *config); void (*set_config)(VirtIODevice *vdev, const uint8_t *config); @@ -195,12 +195,12 @@ typedef struct VirtIOSCSIConf VirtIOSCSIConf; typedef struct VirtIORNGConf VirtIORNGConf; #define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \ - DEFINE_PROP_BIT("indirect_desc", _state, _field, \ - VIRTIO_RING_F_INDIRECT_DESC, true), \ - DEFINE_PROP_BIT("event_idx", _state, _field, \ - VIRTIO_RING_F_EVENT_IDX, true), \ - DEFINE_PROP_BIT("notify_on_empty", _state, _field, \ - VIRTIO_F_NOTIFY_ON_EMPTY, true) + DEFINE_PROP_BIT64("indirect_desc", _state, _field, \ + VIRTIO_RING_F_INDIRECT_DESC, true), \ + DEFINE_PROP_BIT64("event_idx", _state, _field, \ + VIRTIO_RING_F_EVENT_IDX, true), \ + DEFINE_PROP_BIT64("notify_on_empty", _state, _field, \ + VIRTIO_F_NOTIFY_ON_EMPTY, true) hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n); @@ -227,21 +227,21 @@ void virtio_irq(VirtQueue *vq); VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector); VirtQueue *virtio_vector_next_queue(VirtQueue *vq); -static inline void virtio_add_feature(uint32_t *features, unsigned int fbit) +static inline void virtio_add_feature(uint64_t *features, unsigned int fbit) { - assert(fbit < 32); + assert(fbit < 64); *features |= (1 << fbit); } -static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit) +static inline void virtio_clear_feature(uint64_t *features, unsigned int fbit) { - assert(fbit < 32); + assert(fbit < 64); *features &= ~(1 << fbit); } -static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit) +static inline bool __virtio_has_feature(uint64_t features, unsigned int fbit) { - assert(fbit < 32); + assert(fbit < 64); return !!(features & (1 << fbit)); } -- cgit v1.2.3 From 830d70db692e374b55555f4407f96a1ceefdcc97 Mon Sep 17 00:00:00 2001 From: Ouyang Changchun Date: Thu, 28 May 2015 09:23:06 +0800 Subject: vhost-user: add multi queue support Based on patch by Nikolay Nikolaev: Vhost-user will implement the multi queue support in a similar way to what vhost already has - a separate thread for each queue. To enable the multi queue functionality - a new command line parameter "queues" is introduced for the vhost-user netdev. Signed-off-by: Nikolay Nikolaev Signed-off-by: Changchun Ouyang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- docs/specs/vhost-user.txt | 5 +++++ hw/net/vhost_net.c | 3 ++- hw/virtio/vhost-user.c | 11 ++++++++++- net/vhost-user.c | 37 ++++++++++++++++++++++++------------- qapi-schema.json | 6 +++++- qemu-options.hx | 5 +++-- 6 files changed, 49 insertions(+), 18 deletions(-) diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt index 650bb18186..2c8e9347cc 100644 --- a/docs/specs/vhost-user.txt +++ b/docs/specs/vhost-user.txt @@ -127,6 +127,11 @@ in the ancillary data: If Master is unable to send the full message or receives a wrong reply it will close the connection. An optional reconnection mechanism can be implemented. +Multi queue support +------------------- +The protocol supports multiple queues by setting all index fields in the sent +messages to a properly calculated value. + Message types ------------- diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 47f8b89d51..426b23e7e3 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -157,6 +157,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options) net->dev.nvqs = 2; net->dev.vqs = net->vqs; + net->dev.vq_index = net->nc->queue_index; r = vhost_dev_init(&net->dev, options->opaque, options->backend_type, options->force); @@ -267,7 +268,7 @@ static void vhost_net_stop_one(struct vhost_net *net, for (file.index = 0; file.index < net->dev.nvqs; ++file.index) { const VhostOps *vhost_ops = net->dev.vhost_ops; int r = vhost_ops->vhost_call(&net->dev, VHOST_RESET_OWNER, - NULL); + &file); assert(r >= 0); } } diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index e7ab8293d1..d6f21634ef 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -210,7 +210,12 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, break; case VHOST_SET_OWNER: + break; + case VHOST_RESET_OWNER: + memcpy(&msg.state, arg, sizeof(struct vhost_vring_state)); + msg.state.index += dev->vq_index; + msg.size = sizeof(m.state); break; case VHOST_SET_MEM_TABLE: @@ -253,17 +258,20 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, case VHOST_SET_VRING_NUM: case VHOST_SET_VRING_BASE: memcpy(&msg.state, arg, sizeof(struct vhost_vring_state)); + msg.state.index += dev->vq_index; msg.size = sizeof(m.state); break; case VHOST_GET_VRING_BASE: memcpy(&msg.state, arg, sizeof(struct vhost_vring_state)); + msg.state.index += dev->vq_index; msg.size = sizeof(m.state); need_reply = 1; break; case VHOST_SET_VRING_ADDR: memcpy(&msg.addr, arg, sizeof(struct vhost_vring_addr)); + msg.addr.index += dev->vq_index; msg.size = sizeof(m.addr); break; @@ -271,7 +279,7 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, case VHOST_SET_VRING_CALL: case VHOST_SET_VRING_ERR: file = arg; - msg.u64 = file->index & VHOST_USER_VRING_IDX_MASK; + msg.u64 = (file->index + dev->vq_index) & VHOST_USER_VRING_IDX_MASK; msg.size = sizeof(m.u64); if (ioeventfd_enabled() && file->fd > 0) { fds[fd_num++] = file->fd; @@ -313,6 +321,7 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, error_report("Received bad msg size."); return -1; } + msg.state.index -= dev->vq_index; memcpy(arg, &msg.state, sizeof(struct vhost_vring_state)); break; default: diff --git a/net/vhost-user.c b/net/vhost-user.c index 11899c53c0..8d2672846f 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -121,35 +121,39 @@ static void net_vhost_user_event(void *opaque, int event) case CHR_EVENT_OPENED: vhost_user_start(s); net_vhost_link_down(s, false); - error_report("chardev \"%s\" went up", s->chr->label); + error_report("chardev \"%s\" went up", s->nc.info_str); break; case CHR_EVENT_CLOSED: net_vhost_link_down(s, true); vhost_user_stop(s); - error_report("chardev \"%s\" went down", s->chr->label); + error_report("chardev \"%s\" went down", s->nc.info_str); break; } } static int net_vhost_user_init(NetClientState *peer, const char *device, - const char *name, CharDriverState *chr) + const char *name, CharDriverState *chr, + uint32_t queues) { NetClientState *nc; VhostUserState *s; + int i; - nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name); + for (i = 0; i < queues; i++) { + nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name); - snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user to %s", - chr->label); + snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s", + i, chr->label); - s = DO_UPCAST(VhostUserState, nc, nc); + s = DO_UPCAST(VhostUserState, nc, nc); - /* We don't provide a receive callback */ - s->nc.receive_disabled = 1; - s->chr = chr; - - qemu_chr_add_handlers(s->chr, NULL, NULL, net_vhost_user_event, s); + /* We don't provide a receive callback */ + s->nc.receive_disabled = 1; + s->chr = chr; + s->nc.queue_index = i; + qemu_chr_add_handlers(s->chr, NULL, NULL, net_vhost_user_event, s); + } return 0; } @@ -226,6 +230,7 @@ int net_init_vhost_user(const NetClientOptions *opts, const char *name, NetClientState *peer, Error **errp) { /* FIXME error_setg(errp, ...) on failure */ + uint32_t queues; const NetdevVhostUserOptions *vhost_user_opts; CharDriverState *chr; @@ -244,6 +249,12 @@ int net_init_vhost_user(const NetClientOptions *opts, const char *name, return -1; } + /* number of queues for multiqueue */ + if (vhost_user_opts->has_queues) { + queues = vhost_user_opts->queues; + } else { + queues = 1; + } - return net_vhost_user_init(peer, "vhost_user", name, chr); + return net_vhost_user_init(peer, "vhost_user", name, chr, queues); } diff --git a/qapi-schema.json b/qapi-schema.json index 25df463863..0662a9b445 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2444,12 +2444,16 @@ # # @vhostforce: #optional vhost on for non-MSIX virtio guests (default: false). # +# @queues: #optional number of queues to be created for multiqueue vhost-user +# (default: 1) (Since 2.4) +# # Since 2.1 ## { 'struct': 'NetdevVhostUserOptions', 'data': { 'chardev': 'str', - '*vhostforce': 'bool' } } + '*vhostforce': 'bool', + '*queues': 'uint32' } } ## # @NetClientOptions diff --git a/qemu-options.hx b/qemu-options.hx index dad49cf06a..7edd1f18ce 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1955,13 +1955,14 @@ The hubport netdev lets you connect a NIC to a QEMU "vlan" instead of a single netdev. @code{-net} and @code{-device} with parameter @option{vlan} create the required hub automatically. -@item -netdev vhost-user,chardev=@var{id}[,vhostforce=on|off] +@item -netdev vhost-user,chardev=@var{id}[,vhostforce=on|off][,queues=n] Establish a vhost-user netdev, backed by a chardev @var{id}. The chardev should be a unix domain socket backed one. The vhost-user uses a specifically defined protocol to pass vhost ioctl replacement messages to an application on the other end of the socket. On non-MSIX guests, the feature can be forced with -@var{vhostforce}. +@var{vhostforce}. Use 'queues=@var{n}' to specify the number of queues to +be created for multiqueue vhost-user. Example: @example -- cgit v1.2.3