[Qemu-devel] [PATCH v2 0/2] monitor: add peripheral device del completion support
After inputting device_del command in monitor, we expect to list all hotpluggable devices automatically by pressing tab key. This patchset provides the function to list all peripheral devices such as memory devices. v2: - use object_child_foreach() to simplify the implementation (Andreas) Zhu Guihua (2): qdev: add list built for devices monitor: add del completion for peripheral device hw/core/qdev.c | 13 + include/hw/qdev-core.h | 2 ++ monitor.c | 23 +++ 3 files changed, 38 insertions(+) -- 1.9.3
[Qemu-devel] [PATCH v2 2/2] monitor: add del completion for peripheral device
Add peripheral_device_del_completion() to let peripheral device del completion be possible. Signed-off-by: Zhu Guihua --- monitor.c | 23 +++ 1 file changed, 23 insertions(+) diff --git a/monitor.c b/monitor.c index 667efb7..55f4466 100644 --- a/monitor.c +++ b/monitor.c @@ -4351,6 +4351,28 @@ static void device_del_bus_completion(ReadLineState *rs, BusState *bus, } } +static void peripheral_device_del_completion(ReadLineState *rs, + const char *str, size_t len) +{ +Object *peripheral; +GSList *list = NULL, *item; + +peripheral = object_resolve_path("/machine/peripheral/", NULL); + +if (peripheral == NULL) { +return; +} + +object_child_foreach(peripheral, device_built_list, &list); + +for (item = list; item; item = g_slist_next(item)) { +DeviceState *dev = item->data; +if (!strncmp(str, dev->id, len)) { +readline_add_completion(rs, dev->id); +} +} +} + void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str) { size_t len; @@ -4424,6 +4446,7 @@ void device_del_completion(ReadLineState *rs, int nb_args, const char *str) len = strlen(str); readline_set_completion_index(rs, len); device_del_bus_completion(rs, sysbus_get_default(), str, len); +peripheral_device_del_completion(rs, str, len); } void object_del_completion(ReadLineState *rs, int nb_args, const char *str) -- 1.9.3
[Qemu-devel] [PATCH v2 1/2] qdev: add list built for devices
For peripheral device del completion, add a function to build a list for devices. Signed-off-by: Zhu Guihua --- hw/core/qdev.c | 13 + include/hw/qdev-core.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index fcb1638..041ac38 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -1074,6 +1074,19 @@ void device_reset(DeviceState *dev) } } +int device_built_list(Object *obj, void *opaque) +{ +GSList **list = opaque; +DeviceState *dev = DEVICE(obj); + +if (dev->realized) { +*list = g_slist_append(*list, dev); +} + +return 0; + +} + Object *qdev_get_machine(void) { static Object *dev; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 178fee2..3c30837 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -348,6 +348,8 @@ void qdev_machine_init(void); */ void device_reset(DeviceState *dev); +int device_built_list(Object *obj, void *opaque); + const struct VMStateDescription *qdev_get_vmsd(DeviceState *dev); const char *qdev_fw_name(DeviceState *dev); -- 1.9.3
[Qemu-devel] [PATCH v3 0/2] monitor: add peripheral device del completion support
After inputting device_del command in monitor, we expect to list all hotpluggable devices automatically by pressing tab key. This patchset provides the function to list all peripheral devices such as memory devices. v3: - commit message changes (Igor) - rename function in patch 1 (Igor) - use 'hotpluggable' property to discard non-hotpluggable devices (Igor) v2: - use object_child_foreach() to simplify the implementation (Andreas) Zhu Guihua (2): qdev: add qdev_build_hotpluggable_device_list helper monitor: add del completion for peripheral device hw/core/qdev.c | 14 ++ include/hw/qdev-core.h | 2 ++ monitor.c | 24 3 files changed, 40 insertions(+) -- 1.9.3
[Qemu-devel] [PATCH v3 1/2] qdev: add qdev_build_hotpluggable_device_list helper
For peripheral device del completion, add a function to build a list for hotpluggable devices. Signed-off-by: Zhu Guihua --- hw/core/qdev.c | 14 ++ include/hw/qdev-core.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index fcb1638..5f4b2b9 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -801,6 +801,20 @@ void qdev_alias_all_properties(DeviceState *target, Object *source) } while (class != object_class_by_name(TYPE_DEVICE)); } +int qdev_build_hotpluggable_device_list(Object *obj, void *opaque) +{ +GSList **list = opaque; +DeviceState *dev = DEVICE(obj); +DeviceClass *dc = DEVICE_GET_CLASS(dev); + +if (dev->realized && dc->hotpluggable) { +*list = g_slist_append(*list, dev); +} + +object_child_foreach(obj, qdev_build_hotpluggable_device_list, opaque); +return 0; +} + static bool device_get_realized(Object *obj, Error **errp) { DeviceState *dev = DEVICE(obj); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 178fee2..aa76fdc 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -361,6 +361,8 @@ extern int qdev_hotplug; char *qdev_get_dev_path(DeviceState *dev); +int qdev_build_hotpluggable_device_list(Object *obj, void *opaque); + static inline void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, Error **errp) { -- 1.9.3
[Qemu-devel] [PATCH v3 2/2] monitor: add del completion for peripheral device
Add peripheral_device_del_completion() to let peripheral device del completion be possible. Signed-off-by: Zhu Guihua --- monitor.c | 24 1 file changed, 24 insertions(+) diff --git a/monitor.c b/monitor.c index 667efb7..ffe5405 100644 --- a/monitor.c +++ b/monitor.c @@ -4351,6 +4351,29 @@ static void device_del_bus_completion(ReadLineState *rs, BusState *bus, } } +static void peripheral_device_del_completion(ReadLineState *rs, + const char *str, size_t len) +{ +Object *peripheral; +GSList *list = NULL, *item; + +peripheral = object_resolve_path("/machine/peripheral/", NULL); + +if (peripheral == NULL) { +return; +} + +object_child_foreach(peripheral, qdev_build_hotpluggable_device_list, + &list); + +for (item = list; item; item = g_slist_next(item)) { +DeviceState *dev = item->data; +if (!strncmp(str, dev->id, len)) { +readline_add_completion(rs, dev->id); +} +} +} + void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str) { size_t len; @@ -4424,6 +4447,7 @@ void device_del_completion(ReadLineState *rs, int nb_args, const char *str) len = strlen(str); readline_set_completion_index(rs, len); device_del_bus_completion(rs, sysbus_get_default(), str, len); +peripheral_device_del_completion(rs, str, len); } void object_del_completion(ReadLineState *rs, int nb_args, const char *str) -- 1.9.3
Re: [Qemu-devel] [PATCH v2 37/36] qdev: device_del: search for to be unplugged device in 'peripheral' container
On Thu, 2014-10-02 at 10:08 +, Igor Mammedov wrote: > device_add puts every device with 'id' inside of 'peripheral' > container using id's value as the last component name. > Use it by replacing recursive search on sysbus with path > lookup in 'peripheral' container, which could handle both > BUS and BUS-less device cases. > If I want to delete device without id inside of 'peripheral-anon' container, the command 'device_del' does not work. My suggestion is deleting device by the last component name, is this feasiable? Thanks. Zhu > Signed-off-by: Igor Mammedov > --- > qdev-monitor.c | 13 + > 1 file changed, 9 insertions(+), 4 deletions(-) > > diff --git a/qdev-monitor.c b/qdev-monitor.c > index c721451..754437b 100644 > --- a/qdev-monitor.c > +++ b/qdev-monitor.c > @@ -686,15 +686,20 @@ int do_device_add(Monitor *mon, const QDict *qdict, > QObject **ret_data) > > void qmp_device_del(const char *id, Error **errp) > { > -DeviceState *dev; > +Object *obj; > +char *root_path = object_get_canonical_path(qdev_get_peripheral()); > +char *path = g_strdup_printf("%s/%s", root_path, id); > > -dev = qdev_find_recursive(sysbus_get_default(), id); > -if (!dev) { > +g_free(root_path); > +obj = object_resolve_path_type(path, TYPE_DEVICE, NULL); > +g_free(path); > + > +if (!obj) { > error_set(errp, QERR_DEVICE_NOT_FOUND, id); > return; > } > > -qdev_unplug(dev, errp); > +qdev_unplug(DEVICE(obj), errp); > } > > void qdev_machine_init(void)
Re: [Qemu-devel] [PATCH v2 37/36] qdev: device_del: search for to be unplugged device in 'peripheral' container
On Tue, 2014-10-07 at 15:53 +0200, Igor Mammedov wrote: > On Tue, 07 Oct 2014 15:23:45 +0200 > Andreas Färber wrote: > > > Am 07.10.2014 um 14:10 schrieb Igor Mammedov: > > > On Tue, 7 Oct 2014 19:59:51 +0800 > > > Zhu Guihua wrote: > > > > > >> On Thu, 2014-10-02 at 10:08 +, Igor Mammedov wrote: > > >>> device_add puts every device with 'id' inside of 'peripheral' > > >>> container using id's value as the last component name. > > >>> Use it by replacing recursive search on sysbus with path > > >>> lookup in 'peripheral' container, which could handle both > > >>> BUS and BUS-less device cases. > > >>> > > >> > > >> If I want to delete device without id inside of 'peripheral-anon' > > >> container, the command 'device_del' does not work. > > >> My suggestion is deleting device by the last component name, is this > > >> feasiable? > > > So far device_del was designed to work only with id-ed devices. > > > > > > What's a use-case for unplugging unnamed device from peripheral-anon? > > > > I can think of use cases where you may want to balloon memory or CPUs. > yep currently initial CPUs are created without dev->id and even without > device_add help. > However if/when it's switched to device_add we can make them use > auto-generated IDs so they would go into peripheral section. > That would let us keep peripheral-anon for devices that shouldn't > be unplugged. when device_add pc-dimm, only 'memdev' property is necessary, but the 'id' property is optional. So I execute the command as followings: object_add memory-backend-ram,id=ram0,size=128M device_add pc-dimm,memdev=ram0 Now it is impossible to delete the pc-dimm, because it has no id, and it is inside of 'peripheral-anon' container. Regards, Zhu > > > > > But that seems orthogonal to this series. > > > > Regards, > > Andreas > > >
Re: [Qemu-devel] [PATCH v2 37/36] qdev: device_del: search for to be unplugged device in 'peripheral' container
On Wed, 2014-10-08 at 10:01 +0200, Paolo Bonzini wrote: > Il 08/10/2014 05:49, Zhu Guihua ha scritto: > > when device_add pc-dimm, only 'memdev' property is necessary, but the > > 'id' property is optional. > > > > So I execute the command as followings: > > object_add memory-backend-ram,id=ram0,size=128M > > device_add pc-dimm,memdev=ram0 > > > > Now it is impossible to delete the pc-dimm, because it has no id, and it > > is inside of 'peripheral-anon' container. > > Sure; but that was an explicit choice when you issued device_add. Thanks for your patient explanation。 And I think it is better to make memory-devices without dev->id use auto-generated IDs. Regards, Zhu > > Paolo
Re: [Qemu-devel] [PATCH v3 0/2] monitor: add peripheral device del completion support
ping... On Mon, 2014-10-06 at 19:38 +0800, Zhu Guihua wrote: > After inputting device_del command in monitor, we expect to list all > hotpluggable devices automatically by pressing tab key. This patchset provides > the function to list all peripheral devices such as memory devices. > > v3: > - commit message changes (Igor) > - rename function in patch 1 (Igor) > - use 'hotpluggable' property to discard non-hotpluggable devices (Igor) > > v2: > - use object_child_foreach() to simplify the implementation (Andreas) > > > Zhu Guihua (2): > qdev: add qdev_build_hotpluggable_device_list helper > monitor: add del completion for peripheral device > > hw/core/qdev.c | 14 ++ > include/hw/qdev-core.h | 2 ++ > monitor.c | 24 > 3 files changed, 40 insertions(+) >
Re: [Qemu-devel] [PATCH v3 2/2] monitor: add del completion for peripheral device
On Thu, 2014-10-16 at 13:50 +0200, Igor Mammedov wrote: > On Mon, 6 Oct 2014 19:38:44 +0800 > Zhu Guihua wrote: > > > Add peripheral_device_del_completion() to let peripheral device del > > completion be possible. > > > > Signed-off-by: Zhu Guihua > > --- > > monitor.c | 24 > > 1 file changed, 24 insertions(+) > > > > diff --git a/monitor.c b/monitor.c > > index 667efb7..ffe5405 100644 > > --- a/monitor.c > > +++ b/monitor.c > > @@ -4351,6 +4351,29 @@ static void > > device_del_bus_completion(ReadLineState *rs, BusState *bus, } > > } > > > > +static void peripheral_device_del_completion(ReadLineState *rs, > > + const char *str, size_t > > len) +{ > > +Object *peripheral; > > +GSList *list = NULL, *item; > > + > > +peripheral = object_resolve_path("/machine/peripheral/", NULL); > > + > pls remove unnecessary blank line > > > +if (peripheral == NULL) { > > +return; > > +} > > + > > +object_child_foreach(peripheral, > > qdev_build_hotpluggable_device_list, > > + &list); > > + > > +for (item = list; item; item = g_slist_next(item)) { > > +DeviceState *dev = item->data; > add blank line here, pls. > > > +if (!strncmp(str, dev->id, len)) { > > +readline_add_completion(rs, dev->id); > > +} > > +} > > +} > > + > > void chardev_remove_completion(ReadLineState *rs, int nb_args, const > > char *str) { > > size_t len; > > @@ -4424,6 +4447,7 @@ void device_del_completion(ReadLineState *rs, > > int nb_args, const char *str) len = strlen(str); > > readline_set_completion_index(rs, len); > > device_del_bus_completion(rs, sysbus_get_default(), str, len); > All ID-ed devices that might be available for removal are returned by > following line, so do we still need above recusive bus walker that > gathers duplicate devices from buses? > yeah, we do not need recursive bus walker any more. I will change it, thanks. Regards, Zhu > > +peripheral_device_del_completion(rs, str, len); > > } > > > > void object_del_completion(ReadLineState *rs, int nb_args, const > > char *str) >
[Qemu-devel] [PATCH v4 2/3] monitor: add del completion for peripheral device
Add peripheral_device_del_completion() to let peripheral device del completion be possible. Signed-off-by: Zhu Guihua --- monitor.c | 24 1 file changed, 24 insertions(+) diff --git a/monitor.c b/monitor.c index 2d14f39..9c3fa01 100644 --- a/monitor.c +++ b/monitor.c @@ -4359,6 +4359,29 @@ static void device_del_bus_completion(ReadLineState *rs, BusState *bus, } } +static void peripheral_device_del_completion(ReadLineState *rs, + const char *str, size_t len) +{ +Object *peripheral; +GSList *list = NULL, *item; + +peripheral = object_resolve_path("/machine/peripheral/", NULL); +if (peripheral == NULL) { +return; +} + +object_child_foreach(peripheral, qdev_build_hotpluggable_device_list, + &list); + +for (item = list; item; item = g_slist_next(item)) { +DeviceState *dev = item->data; + +if (dev->id && !strncmp(str, dev->id, len)) { +readline_add_completion(rs, dev->id); +} +} +} + void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str) { size_t len; @@ -4432,6 +4455,7 @@ void device_del_completion(ReadLineState *rs, int nb_args, const char *str) len = strlen(str); readline_set_completion_index(rs, len); device_del_bus_completion(rs, sysbus_get_default(), str, len); +peripheral_device_del_completion(rs, str, len); } void object_del_completion(ReadLineState *rs, int nb_args, const char *str) -- 1.9.3
[Qemu-devel] [PATCH v4 1/3] qdev: add qdev_build_hotpluggable_device_list helper
For peripheral device del completion, add a function to build a list for hotpluggable devices. Signed-off-by: Zhu Guihua --- hw/core/qdev.c | 13 + include/hw/qdev-core.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index a1e9247..9357aba 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -866,6 +866,19 @@ void qdev_alias_all_properties(DeviceState *target, Object *source) } while (class != object_class_by_name(TYPE_DEVICE)); } +int qdev_build_hotpluggable_device_list(Object *obj, void *opaque) +{ +GSList **list = opaque; +DeviceState *dev = DEVICE(obj); + +if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) { +*list = g_slist_append(*list, dev); +} + +object_child_foreach(obj, qdev_build_hotpluggable_device_list, opaque); +return 0; +} + static bool device_get_realized(Object *obj, Error **errp) { DeviceState *dev = DEVICE(obj); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 1fca75c..22820fe 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -360,6 +360,8 @@ extern int qdev_hotplug; char *qdev_get_dev_path(DeviceState *dev); +int qdev_build_hotpluggable_device_list(Object *obj, void *opaque); + void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, Error **errp); -- 1.9.3
[Qemu-devel] [PATCH v4 0/3] monitor: add peripheral device del completion support
After inputting device_del command in monitor, we expect to list all hotpluggable devices automatically by pressing tab key. This patchset provides the function to list all peripheral devices such as memory devices. v4: - delete unused device_del_bus_completion (Igor) - modify the way to get value of hotpluggable property (Igor) v3: - commit message changes (Igor) - rename function in patch 1 (Igor) - use 'hotpluggable' property to discard non-hotpluggable devices (Igor) v2: - use object_child_foreach() to simplify the implementation (Andreas) Zhu Guihua (3): qdev: add qdev_build_hotpluggable_device_list helper monitor: add del completion for peripheral device monitor: delete device_del_bus_completion hw/core/qdev.c | 13 + include/hw/qdev-core.h | 2 ++ monitor.c | 26 +++--- 3 files changed, 30 insertions(+), 11 deletions(-) -- 1.9.3
[Qemu-devel] [PATCH v4 3/3] monitor: delete device_del_bus_completion
device_del_bus_completion() that gathers devices from buses is unused; delete it. Signed-off-by: Zhu Guihua --- monitor.c | 20 1 file changed, 20 deletions(-) diff --git a/monitor.c b/monitor.c index 9c3fa01..42affb7 100644 --- a/monitor.c +++ b/monitor.c @@ -4340,25 +4340,6 @@ void object_add_completion(ReadLineState *rs, int nb_args, const char *str) g_slist_free(list); } -static void device_del_bus_completion(ReadLineState *rs, BusState *bus, - const char *str, size_t len) -{ -BusChild *kid; - -QTAILQ_FOREACH(kid, &bus->children, sibling) { -DeviceState *dev = kid->child; -BusState *dev_child; - -if (dev->id && !strncmp(str, dev->id, len)) { -readline_add_completion(rs, dev->id); -} - -QLIST_FOREACH(dev_child, &dev->child_bus, sibling) { -device_del_bus_completion(rs, dev_child, str, len); -} -} -} - static void peripheral_device_del_completion(ReadLineState *rs, const char *str, size_t len) { @@ -4454,7 +4435,6 @@ void device_del_completion(ReadLineState *rs, int nb_args, const char *str) len = strlen(str); readline_set_completion_index(rs, len); -device_del_bus_completion(rs, sysbus_get_default(), str, len); peripheral_device_del_completion(rs, str, len); } -- 1.9.3
Re: [Qemu-devel] [PATCH v4 2/3] monitor: add del completion for peripheral device
On Sun, 2014-10-19 at 14:37 +0300, Marcel Apfelbaum wrote: > On Fri, 2014-10-17 at 17:35 +0800, Zhu Guihua wrote: > > Add peripheral_device_del_completion() to let peripheral device del > > completion > > be possible. > > > > Signed-off-by: Zhu Guihua > > --- > > monitor.c | 24 > > 1 file changed, 24 insertions(+) > > > > diff --git a/monitor.c b/monitor.c > > index 2d14f39..9c3fa01 100644 > > --- a/monitor.c > > +++ b/monitor.c > > @@ -4359,6 +4359,29 @@ static void device_del_bus_completion(ReadLineState > > *rs, BusState *bus, > > } > > } > > > > +static void peripheral_device_del_completion(ReadLineState *rs, > > + const char *str, size_t len) > > +{ > > +Object *peripheral; > > +GSList *list = NULL, *item; > > + > > +peripheral = object_resolve_path("/machine/peripheral/", NULL); > > +if (peripheral == NULL) { > > +return; > > +} > > + > > +object_child_foreach(peripheral, qdev_build_hotpluggable_device_list, > > + &list); > > + > > +for (item = list; item; item = g_slist_next(item)) { > > +DeviceState *dev = item->data; > > + > > +if (dev->id && !strncmp(str, dev->id, len)) { > > +readline_add_completion(rs, dev->id); > > +} > > + > Hi, > > Am I missing something or g_slist_free(list) > should be somewhere here? > Yes, you are right, g_slist_free(list) should be here. I am sorry to forget to do this. Thanks for your reminding, I will fix this. Regards, Zhu > Thanks, > Marcel > > > > > +} > > + > > void chardev_remove_completion(ReadLineState *rs, int nb_args, const char > > *str) > > { > > size_t len; > > @@ -4432,6 +4455,7 @@ void device_del_completion(ReadLineState *rs, int > > nb_args, const char *str) > > len = strlen(str); > > readline_set_completion_index(rs, len); > > device_del_bus_completion(rs, sysbus_get_default(), str, len); > > +peripheral_device_del_completion(rs, str, len); > > } > > > > void object_del_completion(ReadLineState *rs, int nb_args, const char *str) > > >
[Qemu-devel] [PATCH v5 1/3] qdev: add qdev_build_hotpluggable_device_list helper
For peripheral device del completion, add a function to build a list for hotpluggable devices. Signed-off-by: Zhu Guihua --- hw/core/qdev.c | 13 + include/hw/qdev-core.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index a1e9247..9357aba 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -866,6 +866,19 @@ void qdev_alias_all_properties(DeviceState *target, Object *source) } while (class != object_class_by_name(TYPE_DEVICE)); } +int qdev_build_hotpluggable_device_list(Object *obj, void *opaque) +{ +GSList **list = opaque; +DeviceState *dev = DEVICE(obj); + +if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) { +*list = g_slist_append(*list, dev); +} + +object_child_foreach(obj, qdev_build_hotpluggable_device_list, opaque); +return 0; +} + static bool device_get_realized(Object *obj, Error **errp) { DeviceState *dev = DEVICE(obj); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 1fca75c..22820fe 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -360,6 +360,8 @@ extern int qdev_hotplug; char *qdev_get_dev_path(DeviceState *dev); +int qdev_build_hotpluggable_device_list(Object *obj, void *opaque); + void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, Error **errp); -- 1.9.3
[Qemu-devel] [PATCH v5 2/3] monitor: add del completion for peripheral device
Add peripheral_device_del_completion() to let peripheral device del completion be possible. Signed-off-by: Zhu Guihua --- monitor.c | 26 ++ 1 file changed, 26 insertions(+) diff --git a/monitor.c b/monitor.c index 2d14f39..ac41fa3 100644 --- a/monitor.c +++ b/monitor.c @@ -4359,6 +4359,31 @@ static void device_del_bus_completion(ReadLineState *rs, BusState *bus, } } +static void peripheral_device_del_completion(ReadLineState *rs, + const char *str, size_t len) +{ +Object *peripheral; +GSList *list = NULL, *item; + +peripheral = object_resolve_path("/machine/peripheral/", NULL); +if (peripheral == NULL) { +return; +} + +object_child_foreach(peripheral, qdev_build_hotpluggable_device_list, + &list); + +for (item = list; item; item = g_slist_next(item)) { +DeviceState *dev = item->data; + +if (dev->id && !strncmp(str, dev->id, len)) { +readline_add_completion(rs, dev->id); +} +} + +g_slist_free(list); +} + void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str) { size_t len; @@ -4432,6 +4457,7 @@ void device_del_completion(ReadLineState *rs, int nb_args, const char *str) len = strlen(str); readline_set_completion_index(rs, len); device_del_bus_completion(rs, sysbus_get_default(), str, len); +peripheral_device_del_completion(rs, str, len); } void object_del_completion(ReadLineState *rs, int nb_args, const char *str) -- 1.9.3
[Qemu-devel] [PATCH v5 0/3] monitor: add peripheral device del completion support
After inputting device_del command in monitor, we expect to list all hotpluggable devices automatically by pressing tab key. This patchset provides the function to list all peripheral devices such as memory devices. v5: - In patch 2, make list to free (Marcel) v4: - Delete unused device_del_bus_completion (Igor) - Modify the way to get value of hotpluggable property (Igor) v3: - Commit message changes (Igor) - Rename function in patch 1 (Igor) - Use 'hotpluggable' property to discard non-hotpluggable devices (Igor) v2: - Use object_child_foreach() to simplify the implementation (Andreas) Zhu Guihua (3): qdev: add qdev_build_hotpluggable_device_list helper monitor: add del completion for peripheral device monitor: delete device_del_bus_completion hw/core/qdev.c | 13 + include/hw/qdev-core.h | 2 ++ monitor.c | 28 +--- 3 files changed, 32 insertions(+), 11 deletions(-) -- 1.9.3
[Qemu-devel] [PATCH v5 3/3] monitor: delete device_del_bus_completion
device_del_bus_completion() that gathers devices from buses is unused; delete it. Signed-off-by: Zhu Guihua --- monitor.c | 20 1 file changed, 20 deletions(-) diff --git a/monitor.c b/monitor.c index ac41fa3..2cccd0a 100644 --- a/monitor.c +++ b/monitor.c @@ -4340,25 +4340,6 @@ void object_add_completion(ReadLineState *rs, int nb_args, const char *str) g_slist_free(list); } -static void device_del_bus_completion(ReadLineState *rs, BusState *bus, - const char *str, size_t len) -{ -BusChild *kid; - -QTAILQ_FOREACH(kid, &bus->children, sibling) { -DeviceState *dev = kid->child; -BusState *dev_child; - -if (dev->id && !strncmp(str, dev->id, len)) { -readline_add_completion(rs, dev->id); -} - -QLIST_FOREACH(dev_child, &dev->child_bus, sibling) { -device_del_bus_completion(rs, dev_child, str, len); -} -} -} - static void peripheral_device_del_completion(ReadLineState *rs, const char *str, size_t len) { @@ -4456,7 +4437,6 @@ void device_del_completion(ReadLineState *rs, int nb_args, const char *str) len = strlen(str); readline_set_completion_index(rs, len); -device_del_bus_completion(rs, sysbus_get_default(), str, len); peripheral_device_del_completion(rs, str, len); } -- 1.9.3
[Qemu-devel] [RFC PATCH v2] add memory hotunplug support
From: Hu Tao This patch is to solve a problem that when you add a hot-pluggable memory, you can't remove the memory. Its approach is to set GPE status bit by qemu, then trigger SCI interrupt to notify guest os. Guest os checks device status, and free memory resource if possible, then generate OST. Finally, qemu handles OST events to free dimm device. Signed-off-by: Hu Tao Signed-off-by: Zhu Guihua --- hw/acpi/memory_hotplug.c | 74 +++- hw/acpi/piix4.c | 2 ++ hw/core/qdev.c | 9 + hw/i386/pc.c | 31 + hw/i386/ssdt-mem.dsl | 4 +++ hw/i386/ssdt-misc.dsl| 11 +- hw/mem/pc-dimm.c | 10 ++ include/hw/acpi/memory_hotplug.h | 3 ++ include/qom/object.h | 1 + qdev-monitor.c | 25 +- qom/object.c | 2 +- 11 files changed, 168 insertions(+), 4 deletions(-) diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index ed39241..b43b2b4 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -75,12 +75,14 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr, case 0x14: /* pack and return is_* fields */ val |= mdev->is_enabled ? 1 : 0; val |= mdev->is_inserting ? 2 : 0; +val |= mdev->is_removing ? 4 : 0; trace_mhp_acpi_read_flags(mem_st->selector, val); break; default: val = ~0; break; } + return val; } @@ -126,17 +128,57 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data, info = acpi_memory_device_status(mem_st->selector, mdev); qapi_event_send_acpi_device_ost(info, &error_abort); qapi_free_ACPIOSTInfo(info); +switch (mdev->ost_event) { +case 0x03: /* EJECT */ +switch (mdev->ost_status) { +case 0x0: /* SUCCESS */ +object_unparent(OBJECT(mdev->dimm)); +mdev->is_removing = false; +mdev->dimm = NULL; +break; +case 0x1: /* FAILURE */ +case 0x2: /* UNRECOGNIZED NOTIFY */ +case 0x80: /* EJECT NOT SUPPORTED */ +case 0x81: /* DEVICE IN USE */ +case 0x82: /* DEVICE BUSY */ +case 0x83: /* EJECT_DEPENDENCY_BUSY */ +mdev->is_removing = false; +mdev->is_enabled = true; +break; +case 0x84: /* EJECTION IN PROGRESS */ +break; +default: +break; +} +break; +case 0x103: /* OSPM EJECT */ +switch (mdev->ost_status) { +case 0x0: /* SUCCESS */ +object_unparent(OBJECT(mdev->dimm)); +mdev->is_removing = false; +mdev->dimm = NULL; +break; +case 0x84: /* EJECTION IN PROGRESS */ +mdev->is_enabled = false; +mdev->is_removing = true; +break; +default: +break; +} +} break; case 0x14: mdev = &mem_st->devs[mem_st->selector]; if (data & 2) { /* clear insert event */ mdev->is_inserting = false; trace_mhp_acpi_clear_insert_evt(mem_st->selector); +} else if (data & 4) { /* MRMV */ +mdev->is_enabled = false; } break; } - } + static const MemoryRegionOps acpi_memory_hotplug_ops = { .read = acpi_memory_hotplug_read, .write = acpi_memory_hotplug_write, @@ -195,6 +237,36 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, return; } +void acpi_memory_unplug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, + DeviceState *dev, Error **errp) +{ +MemStatus *mdev; +Error *local_err = NULL; +int slot = object_property_get_int(OBJECT(dev), "slot", &local_err); + +if (local_err) { +error_propagate(errp, local_err); +return; +} + +if (slot >= mem_st->dev_count) { +char *dev_path = object_get_canonical_path(OBJECT(dev)); +error_setg(errp, "acpi_memory_plug_cb: " + "device [%s] returned invalid memory slot[%d]", +dev_path, slot); +g_free(dev_path); +return; +} + +mdev = &mem_st->devs[slot]; +mdev->is_removing = true; + +/* do ACPI magic */ +ar->gpe.sts[0] |= ACPI_MEMORY_HOTPLUG_STATUS; +acpi_update_sci(ar, irq); +return; +} + static const VMStateDescription vmstate_memhp_sts = { .name = "memory hotplug device state", .version_id = 1, diff --git a/hw/acpi/p
[Qemu-devel] [RFC PATCH v2] Add HMP command "info memory-devices"
Provides HMP equivalent of QMP query-memory-devices command. Signed-off-by: Zhu Guihua --- hmp-commands.hx | 2 ++ hmp.c | 43 +++ hmp.h | 1 + monitor.c | 7 +++ 4 files changed, 53 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index f859f8d..0b1a4f7 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1778,6 +1778,8 @@ show qdev device model list show roms @item info tpm show the TPM device +@item info memory-devices +show the memory devices @end table ETEXI diff --git a/hmp.c b/hmp.c index 40a90da..93c1dfe 100644 --- a/hmp.c +++ b/hmp.c @@ -1718,3 +1718,46 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) qapi_free_MemdevList(memdev_list); } + +void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) +{ +Error *err = NULL; +MemoryDeviceInfoList *list = qmp_query_memory_devices(&err); +MemoryDeviceInfoList *elem = list; +MemoryDeviceInfo *info; +PCDIMMDeviceInfo *di; +int i = 0; + +while (elem) { +info = elem->value; + +if (info) { +switch (info->kind) { +case MEMORY_DEVICE_INFO_KIND_DIMM: +di = info->dimm; + +monitor_printf(mon, "MemoryDevice %d\n", i); +monitor_printf(mon, " %s\n", + MemoryDeviceInfoKind_lookup[MEMORY_DEVICE_INFO_KIND_DIMM]); +monitor_printf(mon, " id: %s\n", di->id); +monitor_printf(mon, " addr: %" PRId64 "\n", di->addr); +monitor_printf(mon, " slot: %" PRId64 "\n", di->slot); +monitor_printf(mon, " node: %" PRId64 "\n", di->node); +monitor_printf(mon, " size: %" PRId64 "\n", di->size); +monitor_printf(mon, " memdev: %s\n", di->memdev); +monitor_printf(mon, " hotplugged: %s\n", + di->hotplugged ? "true" : "false"); +monitor_printf(mon, " hotpluggable: %s\n", + di->hotpluggable ? "true" : "false"); +break; +default: +break; +} +} + +elem = elem->next; +i++; +} + +qapi_free_MemoryDeviceInfoList(list); +} diff --git a/hmp.h b/hmp.h index 4fd3c4a..4bb5dca 100644 --- a/hmp.h +++ b/hmp.h @@ -94,6 +94,7 @@ void hmp_cpu_add(Monitor *mon, const QDict *qdict); void hmp_object_add(Monitor *mon, const QDict *qdict); void hmp_object_del(Monitor *mon, const QDict *qdict); void hmp_info_memdev(Monitor *mon, const QDict *qdict); +void hmp_info_memory_devices(Monitor *mon, const QDict *qdict); void object_add_completion(ReadLineState *rs, int nb_args, const char *str); void object_del_completion(ReadLineState *rs, int nb_args, const char *str); void device_add_completion(ReadLineState *rs, int nb_args, const char *str); diff --git a/monitor.c b/monitor.c index 34cee74..fe88e0d 100644 --- a/monitor.c +++ b/monitor.c @@ -2921,6 +2921,13 @@ static mon_cmd_t info_cmds[] = { .mhandler.cmd = hmp_info_memdev, }, { +.name = "memory-devices", +.args_type = "", +.params = "", +.help = "show memory devices", +.mhandler.cmd = hmp_info_memory_devices, +}, +{ .name = NULL, }, }; -- 1.9.3
[Qemu-devel] [RESEND RFC PATCH v2] Add HMP command "info memory-devices"
This patch provides HMP equivalent of QMP query-memory-devices command. By this command "info memory-devices", user can know all information about hotpluggable memmory device such as id. With id of devices, hot removing hotpluggable memory devices becomes possible by command 'device_del'. Change log v1 -> v2: 1. fix bug that accessing info->dimm when MemoryDeviceInfo is not PCDIMMDevice. 2. use enum to replace "dimm", and lookup type name in MemoryDeviceInfoKind_lookup[] instead of opencodding it. Signed-off-by: Zhu Guihua --- hmp-commands.hx | 2 ++ hmp.c | 43 +++ hmp.h | 1 + monitor.c | 7 +++ 4 files changed, 53 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index f859f8d..0b1a4f7 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1778,6 +1778,8 @@ show qdev device model list show roms @item info tpm show the TPM device +@item info memory-devices +show the memory devices @end table ETEXI diff --git a/hmp.c b/hmp.c index 40a90da..93c1dfe 100644 --- a/hmp.c +++ b/hmp.c @@ -1718,3 +1718,46 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) qapi_free_MemdevList(memdev_list); } + +void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) +{ +Error *err = NULL; +MemoryDeviceInfoList *list = qmp_query_memory_devices(&err); +MemoryDeviceInfoList *elem = list; +MemoryDeviceInfo *info; +PCDIMMDeviceInfo *di; +int i = 0; + +while (elem) { +info = elem->value; + +if (info) { +switch (info->kind) { +case MEMORY_DEVICE_INFO_KIND_DIMM: +di = info->dimm; + +monitor_printf(mon, "MemoryDevice %d\n", i); +monitor_printf(mon, " %s\n", + MemoryDeviceInfoKind_lookup[MEMORY_DEVICE_INFO_KIND_DIMM]); +monitor_printf(mon, " id: %s\n", di->id); +monitor_printf(mon, " addr: %" PRId64 "\n", di->addr); +monitor_printf(mon, " slot: %" PRId64 "\n", di->slot); +monitor_printf(mon, " node: %" PRId64 "\n", di->node); +monitor_printf(mon, " size: %" PRId64 "\n", di->size); +monitor_printf(mon, " memdev: %s\n", di->memdev); +monitor_printf(mon, " hotplugged: %s\n", + di->hotplugged ? "true" : "false"); +monitor_printf(mon, " hotpluggable: %s\n", + di->hotpluggable ? "true" : "false"); +break; +default: +break; +} +} + +elem = elem->next; +i++; +} + +qapi_free_MemoryDeviceInfoList(list); +} diff --git a/hmp.h b/hmp.h index 4fd3c4a..4bb5dca 100644 --- a/hmp.h +++ b/hmp.h @@ -94,6 +94,7 @@ void hmp_cpu_add(Monitor *mon, const QDict *qdict); void hmp_object_add(Monitor *mon, const QDict *qdict); void hmp_object_del(Monitor *mon, const QDict *qdict); void hmp_info_memdev(Monitor *mon, const QDict *qdict); +void hmp_info_memory_devices(Monitor *mon, const QDict *qdict); void object_add_completion(ReadLineState *rs, int nb_args, const char *str); void object_del_completion(ReadLineState *rs, int nb_args, const char *str); void device_add_completion(ReadLineState *rs, int nb_args, const char *str); diff --git a/monitor.c b/monitor.c index 34cee74..fe88e0d 100644 --- a/monitor.c +++ b/monitor.c @@ -2921,6 +2921,13 @@ static mon_cmd_t info_cmds[] = { .mhandler.cmd = hmp_info_memdev, }, { +.name = "memory-devices", +.args_type = "", +.params = "", +.help = "show memory devices", +.mhandler.cmd = hmp_info_memory_devices, +}, +{ .name = NULL, }, }; -- 1.9.3
[Qemu-devel] [RFC PATCH v3] Add HMP command "info memory-devices"
Provides HMP equivalent of QMP query-memory-devices command. Signed-off-by: Zhu Guihua --- Changes since v2: - print address in hex. - change the loop control from while to for. - modify some variables' name. - optimize the time to print memory devices' kind. Changes since v1: - fix bug that accessing info->dimm when MemoryDeviceInfo is not PCDIMMDevice. - use enum to replace "dimm", and lookup typename in MemoryDeviceInfoKind_lookup[] instead of opencodding it. hmp-commands.hx | 2 ++ hmp.c | 41 + hmp.h | 1 + monitor.c | 7 +++ 4 files changed, 51 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index f859f8d..0b1a4f7 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1778,6 +1778,8 @@ show qdev device model list show roms @item info tpm show the TPM device +@item info memory-devices +show the memory devices @end table ETEXI diff --git a/hmp.c b/hmp.c index 40a90da..bbeb8be 100644 --- a/hmp.c +++ b/hmp.c @@ -1718,3 +1718,44 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) qapi_free_MemdevList(memdev_list); } + +void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) +{ +Error *err = NULL; +MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err); +MemoryDeviceInfoList *info; +MemoryDeviceInfo *value; +PCDIMMDeviceInfo *di; +int i = 0; + +for (info = info_list; info; info = info->next) { +value = info->value; + +if (value) { +monitor_printf(mon, "Memory device %d\n", i++); +monitor_printf(mon, " %s\n", + MemoryDeviceInfoKind_lookup[value->kind]); + +switch (value->kind) { +case MEMORY_DEVICE_INFO_KIND_DIMM: +di = value->dimm; + +monitor_printf(mon, "id: %s\n", di->id); +monitor_printf(mon, "addr: 0x%lx\n", di->addr); +monitor_printf(mon, "slot: %" PRId64 "\n", di->slot); +monitor_printf(mon, "node: %" PRId64 "\n", di->node); +monitor_printf(mon, "size: %" PRId64 "\n", di->size); +monitor_printf(mon, "memdev: %s\n", di->memdev); +monitor_printf(mon, "hotplugged: %s\n", + di->hotplugged ? "true" : "false"); +monitor_printf(mon, "hotpluggable: %s\n", + di->hotpluggable ? "true" : "false"); +break; +default: +break; +} +} +} + +qapi_free_MemoryDeviceInfoList(info_list); +} diff --git a/hmp.h b/hmp.h index 4fd3c4a..4bb5dca 100644 --- a/hmp.h +++ b/hmp.h @@ -94,6 +94,7 @@ void hmp_cpu_add(Monitor *mon, const QDict *qdict); void hmp_object_add(Monitor *mon, const QDict *qdict); void hmp_object_del(Monitor *mon, const QDict *qdict); void hmp_info_memdev(Monitor *mon, const QDict *qdict); +void hmp_info_memory_devices(Monitor *mon, const QDict *qdict); void object_add_completion(ReadLineState *rs, int nb_args, const char *str); void object_del_completion(ReadLineState *rs, int nb_args, const char *str); void device_add_completion(ReadLineState *rs, int nb_args, const char *str); diff --git a/monitor.c b/monitor.c index 34cee74..fe88e0d 100644 --- a/monitor.c +++ b/monitor.c @@ -2921,6 +2921,13 @@ static mon_cmd_t info_cmds[] = { .mhandler.cmd = hmp_info_memdev, }, { +.name = "memory-devices", +.args_type = "", +.params = "", +.help = "show memory devices", +.mhandler.cmd = hmp_info_memory_devices, +}, +{ .name = NULL, }, }; -- 1.9.3
[Qemu-devel] [PATCH v4] Add HMP command "info memory-devices"
Provides HMP equivalent of QMP query-memory-devices command. Signed-off-by: Zhu Guihua --- Changes since v3: - optimize the time to print memory devices' information. - change output format of di->addr and di->size. Changes since v2: - print address in hex. - change the loop control from while to for. - modify some variables' name. - optimize the time to print memory devices' kind. Changes since v1: - fix bug that accessing info->dimm when MemoryDeviceInfo is not PCDIMMDevice. - use enum to replace "dimm", and lookup typename in MemoryDeviceInfoKind_lookup[] instead of opencodding it. hmp-commands.hx | 2 ++ hmp.c | 38 ++ hmp.h | 1 + monitor.c | 7 +++ 4 files changed, 48 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index f859f8d..0b1a4f7 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1778,6 +1778,8 @@ show qdev device model list show roms @item info tpm show the TPM device +@item info memory-devices +show the memory devices @end table ETEXI diff --git a/hmp.c b/hmp.c index 40a90da..feefeb4 100644 --- a/hmp.c +++ b/hmp.c @@ -1718,3 +1718,41 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) qapi_free_MemdevList(memdev_list); } + +void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) +{ +Error *err = NULL; +MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err); +MemoryDeviceInfoList *info; +MemoryDeviceInfo *value; +PCDIMMDeviceInfo *di; + +for (info = info_list; info; info = info->next) { +value = info->value; + +if (value) { +switch (value->kind) { +case MEMORY_DEVICE_INFO_KIND_DIMM: +di = value->dimm; + +monitor_printf(mon, "Memory device [%s]: %s\n", + MemoryDeviceInfoKind_lookup[value->kind], + di->id); +monitor_printf(mon, " addr: 0x%" PRIx64 "\n", di->addr); +monitor_printf(mon, " slot: %" PRId64 "\n", di->slot); +monitor_printf(mon, " node: %" PRId64 "\n", di->node); +monitor_printf(mon, " size: %" PRIu64 "\n", di->size); +monitor_printf(mon, " memdev: %s\n", di->memdev); +monitor_printf(mon, " hotplugged: %s\n", + di->hotplugged ? "true" : "false"); +monitor_printf(mon, " hotpluggable: %s\n", + di->hotpluggable ? "true" : "false"); +break; +default: +break; +} +} +} + +qapi_free_MemoryDeviceInfoList(info_list); +} diff --git a/hmp.h b/hmp.h index 4fd3c4a..4bb5dca 100644 --- a/hmp.h +++ b/hmp.h @@ -94,6 +94,7 @@ void hmp_cpu_add(Monitor *mon, const QDict *qdict); void hmp_object_add(Monitor *mon, const QDict *qdict); void hmp_object_del(Monitor *mon, const QDict *qdict); void hmp_info_memdev(Monitor *mon, const QDict *qdict); +void hmp_info_memory_devices(Monitor *mon, const QDict *qdict); void object_add_completion(ReadLineState *rs, int nb_args, const char *str); void object_del_completion(ReadLineState *rs, int nb_args, const char *str); void device_add_completion(ReadLineState *rs, int nb_args, const char *str); diff --git a/monitor.c b/monitor.c index 34cee74..fe88e0d 100644 --- a/monitor.c +++ b/monitor.c @@ -2921,6 +2921,13 @@ static mon_cmd_t info_cmds[] = { .mhandler.cmd = hmp_info_memdev, }, { +.name = "memory-devices", +.args_type = "", +.params = "", +.help = "show memory devices", +.mhandler.cmd = hmp_info_memory_devices, +}, +{ .name = NULL, }, }; -- 1.9.3
[Qemu-devel] [PATCH v1 0/3] monitor: add peripheral device del completion support
After inputting device_del command in monitor, we expect to list all hotpluggable devices automatically by pressing tab key. This patchset provides the function to list all peripheral devices such as memory devices. Zhu Guihua (3): qom: add function to get opaque property in ObjectProperty qom: export object_property_is_child() monitor: add del completion for peripheral device include/qom/object.h | 2 ++ monitor.c| 24 qom/object.c | 11 ++- 3 files changed, 36 insertions(+), 1 deletion(-) -- 1.9.3
[Qemu-devel] [PATCH v1 2/3] qom: export object_property_is_child()
Export object_property_is_child() to let it be invoked in other places. Signed-off-by: Zhu Guihua --- include/qom/object.h | 1 + qom/object.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/qom/object.h b/include/qom/object.h index 5d55889..8f27b7c 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1302,4 +1302,5 @@ Object *container_get(Object *root, const char *path); void *object_property_get_opaque(ObjectProperty *prop, Error **errp); +bool object_property_is_child(ObjectProperty *prop); #endif diff --git a/qom/object.c b/qom/object.c index 00a25e0..8de2599 100644 --- a/qom/object.c +++ b/qom/object.c @@ -351,7 +351,7 @@ void object_initialize(void *data, size_t size, const char *typename) object_initialize_with_type(data, size, type); } -static inline bool object_property_is_child(ObjectProperty *prop) +bool object_property_is_child(ObjectProperty *prop) { return strstart(prop->type, "child<", NULL); } -- 1.9.3
[Qemu-devel] [PATCH v1 1/3] qom: add function to get opaque property in ObjectProperty
Add object_property_get_opaque() to get opaque property in ObjectProperty. Signed-off-by: Zhu Guihua --- include/qom/object.h | 1 + qom/object.c | 9 + 2 files changed, 10 insertions(+) diff --git a/include/qom/object.h b/include/qom/object.h index 8a05a81..5d55889 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1300,5 +1300,6 @@ int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), */ Object *container_get(Object *root, const char *path); +void *object_property_get_opaque(ObjectProperty *prop, Error **errp); #endif diff --git a/qom/object.c b/qom/object.c index da0919a..00a25e0 100644 --- a/qom/object.c +++ b/qom/object.c @@ -356,6 +356,15 @@ static inline bool object_property_is_child(ObjectProperty *prop) return strstart(prop->type, "child<", NULL); } +void *object_property_get_opaque(ObjectProperty *prop, Error **errp) +{ +if (prop == NULL) { +return NULL; +} + +return prop->opaque; +} + static void object_property_del_all(Object *obj) { while (!QTAILQ_EMPTY(&obj->properties)) { -- 1.9.3
[Qemu-devel] [PATCH v1 3/3] monitor: add del completion for peripheral device
Add peripheral_device_del_completion() to let peripheral device del completion be possible. Signed-off-by: Zhu Guihua --- monitor.c | 24 1 file changed, 24 insertions(+) diff --git a/monitor.c b/monitor.c index 667efb7..c0e00e4 100644 --- a/monitor.c +++ b/monitor.c @@ -4351,6 +4351,29 @@ static void device_del_bus_completion(ReadLineState *rs, BusState *bus, } } +static void peripheral_device_del_completion(ReadLineState *rs, + const char *str, size_t len) +{ +Object *peripheral; +DeviceState *dev = NULL; +ObjectProperty *prop; + +peripheral = object_resolve_path("/machine/peripheral/", NULL); + +if (peripheral == NULL) { +return; +} + +QTAILQ_FOREACH(prop, &peripheral->properties, node) { +if (object_property_is_child(prop)) { +dev = DEVICE(object_property_get_opaque(prop, NULL)); +if (dev->id && !strncmp(str, dev->id, len)) { +readline_add_completion(rs, dev->id); +} +} +} +} + void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str) { size_t len; @@ -4424,6 +4447,7 @@ void device_del_completion(ReadLineState *rs, int nb_args, const char *str) len = strlen(str); readline_set_completion_index(rs, len); device_del_bus_completion(rs, sysbus_get_default(), str, len); +peripheral_device_del_completion(rs, str, len); } void object_del_completion(ReadLineState *rs, int nb_args, const char *str) -- 1.9.3
Re: [Qemu-devel] [PATCH v4] Add HMP command "info memory-devices"
On Mon, 2014-09-22 at 09:03 -0400, Luiz Capitulino wrote: > On Mon, 22 Sep 2014 11:29:00 +0200 > Markus Armbruster wrote: > > > Igor Mammedov writes: > > > > > On Mon, 22 Sep 2014 09:59:06 +0200 > > > Markus Armbruster wrote: > > > > > >> zhugh writes: > > >> > > >> > On Fri, 2014-09-19 at 11:34 -0400, Luiz Capitulino wrote: > > >> >> On Fri, 19 Sep 2014 15:30:19 +0200 > > >> >> Igor Mammedov wrote: > > >> >> > > >> >> > On Thu, 18 Sep 2014 16:09:32 +0800 > > >> >> > zhugh wrote: > > >> >> > > > >> >> > > Hi, > > >> >> > > > > >> >> > > Could anyone help to review this patch? > > >> >> > > If there was no problem, could help to merge it? > > >> >> > > > > >> >> > > thanks! > > >> >> > > zhu > > >> >> > > > > >> >> > > On Mon, 2014-09-15 at 19:31 +0800, Zhu Guihua wrote: > > >> >> > > > Provides HMP equivalent of QMP query-memory-devices command. > > >> >> > > > > > >> >> > > > Signed-off-by: Zhu Guihua > > >> [...] > > >> >> > > > diff --git a/hmp.c b/hmp.c > > >> >> > > > index 40a90da..feefeb4 100644 > > >> >> > > > --- a/hmp.c > > >> >> > > > +++ b/hmp.c > > >> >> > > > @@ -1718,3 +1718,41 @@ void hmp_info_memdev(Monitor *mon, const > > >> >> > > > QDict *qdict) > > >> >> > > > > > >> >> > > > qapi_free_MemdevList(memdev_list); > > >> >> > > > } > > >> >> > > > + > > >> >> > > > +void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) > > >> >> > > > +{ > > >> >> > > > +Error *err = NULL; > > >> >> > > > +MemoryDeviceInfoList *info_list = > > >> >> > > > qmp_query_memory_devices(&err); > > >> >> > > > +MemoryDeviceInfoList *info; > > >> >> > > > +MemoryDeviceInfo *value; > > >> >> > > > +PCDIMMDeviceInfo *di; > > >> >> > > > + > > >> >> > > > +for (info = info_list; info; info = info->next) { > > >> >> > > > +value = info->value; > > >> >> > > > + > > >> >> > > > +if (value) { > > >> >> > > > +switch (value->kind) { > > >> >> > > > +case MEMORY_DEVICE_INFO_KIND_DIMM: > > >> >> > > > +di = value->dimm; > > >> >> > > > + > > >> >> > > > +monitor_printf(mon, "Memory device [%s]: %s\n", > > >> >> > > > + > > >> >> > > > MemoryDeviceInfoKind_lookup[value->kind], > > >> >> > > > + di->id); > > >> >> > 'id' might be null, here is what user will see: > > >> >> > > > >> >> > Memory device [dimm]: (null) > > >> >> > > > >> >> > I'd suggest to replace (null) with "" as it is done elsewhere. > > >> >> > > >> >> Is the fix below what you're looking for? If it is I can apply it > > >> >> myself: > > >> > > > >> > I am sorry, I did not test this fix in my code last time. But your fix > > >> > would print nothing when the id was null. > > >> > > >> Printing nothing when there's no ID has a certain logic to it :) > > > > > > When I do 'info qtree' it displays empty IDs with as empty "" > > > I think we should be consistent and apply above correction. > > > > If you want consistency with "info qtree", you should enclose non-null > > ID in double quotes. > > zhugh, at this point is better to respin the patch. Ok, I will send v5 to fix this. Thanks! Zhu
[Qemu-devel] [PATCH v5] Add HMP command "info memory-devices"
Provides HMP equivalent of QMP query-memory-devices command. Signed-off-by: Zhu Guihua --- Changes since v4: - enclose ID in double quotes. Changes since v3: - optimize the time to print memory devices' information. - change output format of di->addr and di->size. Changes since v2: - print address in hex. - change the loop control from while to for. - modify some variables' name. - optimize the time to print memory devices' kind. Changes since v1: - fix bug that accessing info->dimm when MemoryDeviceInfo is not PCDIMMDevice. - use enum to replace "dimm", and lookup typename in MemoryDeviceInfoKind_lookup[] instead of opencodding it. --- hmp-commands.hx | 2 ++ hmp.c | 38 ++ hmp.h | 1 + monitor.c | 7 +++ 4 files changed, 48 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index f859f8d..0b1a4f7 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1778,6 +1778,8 @@ show qdev device model list show roms @item info tpm show the TPM device +@item info memory-devices +show the memory devices @end table ETEXI diff --git a/hmp.c b/hmp.c index 40a90da..49238e9 100644 --- a/hmp.c +++ b/hmp.c @@ -1718,3 +1718,41 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) qapi_free_MemdevList(memdev_list); } + +void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) +{ +Error *err = NULL; +MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err); +MemoryDeviceInfoList *info; +MemoryDeviceInfo *value; +PCDIMMDeviceInfo *di; + +for (info = info_list; info; info = info->next) { +value = info->value; + +if (value) { +switch (value->kind) { +case MEMORY_DEVICE_INFO_KIND_DIMM: +di = value->dimm; + +monitor_printf(mon, "Memory device [%s]: \"%s\"\n", + MemoryDeviceInfoKind_lookup[value->kind], + di->id ? di->id : ""); +monitor_printf(mon, " addr: 0x%" PRIx64 "\n", di->addr); +monitor_printf(mon, " slot: %" PRId64 "\n", di->slot); +monitor_printf(mon, " node: %" PRId64 "\n", di->node); +monitor_printf(mon, " size: %" PRIu64 "\n", di->size); +monitor_printf(mon, " memdev: %s\n", di->memdev); +monitor_printf(mon, " hotplugged: %s\n", + di->hotplugged ? "true" : "false"); +monitor_printf(mon, " hotpluggable: %s\n", + di->hotpluggable ? "true" : "false"); +break; +default: +break; +} +} +} + +qapi_free_MemoryDeviceInfoList(info_list); +} diff --git a/hmp.h b/hmp.h index 4fd3c4a..4bb5dca 100644 --- a/hmp.h +++ b/hmp.h @@ -94,6 +94,7 @@ void hmp_cpu_add(Monitor *mon, const QDict *qdict); void hmp_object_add(Monitor *mon, const QDict *qdict); void hmp_object_del(Monitor *mon, const QDict *qdict); void hmp_info_memdev(Monitor *mon, const QDict *qdict); +void hmp_info_memory_devices(Monitor *mon, const QDict *qdict); void object_add_completion(ReadLineState *rs, int nb_args, const char *str); void object_del_completion(ReadLineState *rs, int nb_args, const char *str); void device_add_completion(ReadLineState *rs, int nb_args, const char *str); diff --git a/monitor.c b/monitor.c index 667efb7..7467521 100644 --- a/monitor.c +++ b/monitor.c @@ -2921,6 +2921,13 @@ static mon_cmd_t info_cmds[] = { .mhandler.cmd = hmp_info_memdev, }, { +.name = "memory-devices", +.args_type = "", +.params = "", +.help = "show memory devices", +.mhandler.cmd = hmp_info_memory_devices, +}, +{ .name = NULL, }, }; -- 1.9.3
Re: [Qemu-devel] [PATCH v1 0/3] monitor: add peripheral device del completion support
ping ... On Thu, 2014-09-18 at 15:53 +0800, Zhu Guihua wrote: > After inputting device_del command in monitor, we expect to list all > hotpluggable devices automatically by pressing tab key. This patchset provides > the function to list all peripheral devices such as memory devices. > > Zhu Guihua (3): > qom: add function to get opaque property in ObjectProperty > qom: export object_property_is_child() > monitor: add del completion for peripheral device > > include/qom/object.h | 2 ++ > monitor.c| 24 > qom/object.c | 11 ++- > 3 files changed, 36 insertions(+), 1 deletion(-) >
[Qemu-devel] [RFC PATCH v1] monitor: add parameter 'memory-devices' to the 'info' command
When you hot remove hotpluggable memory devices, you should know the id of memory devices. But before this, you could not know the id of memory devices unless you remember all infomation about hotpluggable memory devices. This patch provides the function, if you input command 'info memory-devices' in monitor, monitor can list all available memory devices and their information. Signed-off-by: Zhu Guihua --- hmp-commands.hx | 2 ++ hmp.c | 33 + hmp.h | 1 + monitor.c | 7 +++ 4 files changed, 43 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index d0943b1..1aa353f 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1780,6 +1780,8 @@ show qdev device model list show roms @item info tpm show the TPM device +@item info memory-devices +show the memory devices @end table ETEXI diff --git a/hmp.c b/hmp.c index 4d1838e..977d3f4 100644 --- a/hmp.c +++ b/hmp.c @@ -1714,3 +1714,36 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) monitor_printf(mon, "\n"); } + +void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) +{ +Error *err = NULL; +MemoryDeviceInfoList *list = qmp_query_memory_devices(&err); +MemoryDeviceInfoList *elem = list; +MemoryDeviceInfo *info; +PCDIMMDeviceInfo *di; +int i = 0; + +while (elem) { +info = elem->value; +di = info->dimm; + +monitor_printf(mon, "MemoryDevice %d\n", i); +monitor_printf(mon, " data:\n"); +monitor_printf(mon, " id: %s\n", di->id); +monitor_printf(mon, " addr: %" PRId64 "\n", di->addr); +monitor_printf(mon, " slot: %" PRId64 "\n", di->slot); +monitor_printf(mon, " node: %" PRId64 "\n", di->node); +monitor_printf(mon, " size: %" PRId64 "\n", di->size); +monitor_printf(mon, " memdev: %s\n", di->memdev); +monitor_printf(mon, " hotplugged: %s\n", di->hotplugged ? "true" : "false"); +monitor_printf(mon, " hotpluggable: %s\n", di->hotpluggable ? "true" : "false"); +monitor_printf(mon, " type: %s\n", info->kind ? "max" : "dimm"); + +elem = elem->next; +i++; +} + +qapi_free_MemoryDeviceInfoList(elem); +qapi_free_MemoryDeviceInfoList(list); +} diff --git a/hmp.h b/hmp.h index 4fd3c4a..4bb5dca 100644 --- a/hmp.h +++ b/hmp.h @@ -94,6 +94,7 @@ void hmp_cpu_add(Monitor *mon, const QDict *qdict); void hmp_object_add(Monitor *mon, const QDict *qdict); void hmp_object_del(Monitor *mon, const QDict *qdict); void hmp_info_memdev(Monitor *mon, const QDict *qdict); +void hmp_info_memory_devices(Monitor *mon, const QDict *qdict); void object_add_completion(ReadLineState *rs, int nb_args, const char *str); void object_del_completion(ReadLineState *rs, int nb_args, const char *str); void device_add_completion(ReadLineState *rs, int nb_args, const char *str); diff --git a/monitor.c b/monitor.c index 34cee74..fe88e0d 100644 --- a/monitor.c +++ b/monitor.c @@ -2921,6 +2921,13 @@ static mon_cmd_t info_cmds[] = { .mhandler.cmd = hmp_info_memdev, }, { +.name = "memory-devices", +.args_type = "", +.params = "", +.help = "show memory devices", +.mhandler.cmd = hmp_info_memory_devices, +}, +{ .name = NULL, }, }; -- 1.9.3
[Qemu-devel] [PATCH] icc_bus: rename ICC_BRIGDE to ICC_BRIDGE
Rename ICC_BRIGDE for better readability. Signed-off-by: Zhu Guihua --- hw/cpu/icc_bus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c index 9575fd6..6646ea2 100644 --- a/hw/cpu/icc_bus.c +++ b/hw/cpu/icc_bus.c @@ -73,11 +73,11 @@ typedef struct ICCBridgeState { MemoryRegion apic_container; } ICCBridgeState; -#define ICC_BRIGDE(obj) OBJECT_CHECK(ICCBridgeState, (obj), TYPE_ICC_BRIDGE) +#define ICC_BRIDGE(obj) OBJECT_CHECK(ICCBridgeState, (obj), TYPE_ICC_BRIDGE) static void icc_bridge_init(Object *obj) { -ICCBridgeState *s = ICC_BRIGDE(obj); +ICCBridgeState *s = ICC_BRIDGE(obj); SysBusDevice *sb = SYS_BUS_DEVICE(obj); qbus_create_inplace(&s->icc_bus, sizeof(s->icc_bus), TYPE_ICC_BUS, -- 1.9.3
Re: [Qemu-devel] [PATCH] icc_bus: rename ICC_BRIGDE to ICC_BRIDGE
On Mon, 2014-11-03 at 12:01 +0300, Michael Tokarev wrote: > 03.11.2014 08:51, Zhu Guihua wrote: > > Rename ICC_BRIGDE for better readability. > > That's a good one... :) Applied to -trivial, thank you! > For Igor's opinion, it is better to change the subject. So should I send v2 to fix this? Regards, Zhu > /mjt
Re: [Qemu-devel] [PATCH Part2 10/13] acpi, ich9: Add memory hot unplug support for ich9.
On Mon, 2014-11-17 at 13:03 +0800, Tang Chen wrote: > Call memory unplug cb in ich9_pm_device_unplug_cb(). > > Signed-off-by: Tang Chen > --- > hw/acpi/ich9.c | 10 -- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c > index 841f57d..691299f 100644 > --- a/hw/acpi/ich9.c > +++ b/hw/acpi/ich9.c > @@ -317,8 +317,14 @@ void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, > DeviceState *dev, > void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, >Error **errp) > { > -error_setg(errp, "acpi: device unplug for not supported device" > - " type: %s", object_get_typename(OBJECT(dev))); > +if (pm->acpi_memory_hotplug.is_enabled && > +object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { > +acpi_memory_unplug_request_cb(&pm->acpi_regs, pm->irq, > + &pm->acpi_memory_hotplug, dev, errp); This should invoke acpi_memory_unplug_cb(). Regards, Zhu > +} else { > +error_setg(errp, "acpi: device unplug for not supported device" > + " type: %s", object_get_typename(OBJECT(dev))); > +} > } > > void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
[Qemu-devel] [RFC PATCH] add memory hotunplug support
From: Hu Tao This patch is to solve a problem that when you add a hot-pluggable memory, you can't remove the memory. Its approach is to set GPE status bit by qemu, then generate SCI to notify guest os. Guest os checks device status, and free memory resource if possible, then generate OST. Finally, qemu handles OST events to free dimm device. 1. based on branch mst/pci url = http://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git 2. known problems 1) When you try to delete a pc-dimm twice, guest will generate some errors. 2) If you create a pc-dimm whose id is d9, then you excute 'device_del d10', the pc-dimm will be deleted successfully. If you change the id property of device_del to others, the device_del operation will also be excuted correctly, and the pc-dimm d9 will be deleted. Signed-off-by: Hu Tao Signed-off-by: Zhu Guihua --- hw/acpi/memory_hotplug.c | 74 +++- hw/acpi/piix4.c | 2 ++ hw/core/qdev.c | 9 + hw/i386/pc.c | 31 + hw/i386/ssdt-mem.dsl | 8 + hw/i386/ssdt-misc.dsl| 13 ++- include/hw/acpi/memory_hotplug.h | 3 ++ include/qom/object.h | 1 + qdev-monitor.c | 25 +- qom/object.c | 2 +- 10 files changed, 164 insertions(+), 4 deletions(-) diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index ed39241..b43b2b4 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -75,12 +75,14 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr, case 0x14: /* pack and return is_* fields */ val |= mdev->is_enabled ? 1 : 0; val |= mdev->is_inserting ? 2 : 0; +val |= mdev->is_removing ? 4 : 0; trace_mhp_acpi_read_flags(mem_st->selector, val); break; default: val = ~0; break; } + return val; } @@ -126,17 +128,57 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data, info = acpi_memory_device_status(mem_st->selector, mdev); qapi_event_send_acpi_device_ost(info, &error_abort); qapi_free_ACPIOSTInfo(info); +switch (mdev->ost_event) { +case 0x03: /* EJECT */ +switch (mdev->ost_status) { +case 0x0: /* SUCCESS */ +object_unparent(OBJECT(mdev->dimm)); +mdev->is_removing = false; +mdev->dimm = NULL; +break; +case 0x1: /* FAILURE */ +case 0x2: /* UNRECOGNIZED NOTIFY */ +case 0x80: /* EJECT NOT SUPPORTED */ +case 0x81: /* DEVICE IN USE */ +case 0x82: /* DEVICE BUSY */ +case 0x83: /* EJECT_DEPENDENCY_BUSY */ +mdev->is_removing = false; +mdev->is_enabled = true; +break; +case 0x84: /* EJECTION IN PROGRESS */ +break; +default: +break; +} +break; +case 0x103: /* OSPM EJECT */ +switch (mdev->ost_status) { +case 0x0: /* SUCCESS */ +object_unparent(OBJECT(mdev->dimm)); +mdev->is_removing = false; +mdev->dimm = NULL; +break; +case 0x84: /* EJECTION IN PROGRESS */ +mdev->is_enabled = false; +mdev->is_removing = true; +break; +default: +break; +} +} break; case 0x14: mdev = &mem_st->devs[mem_st->selector]; if (data & 2) { /* clear insert event */ mdev->is_inserting = false; trace_mhp_acpi_clear_insert_evt(mem_st->selector); +} else if (data & 4) { /* MRMV */ +mdev->is_enabled = false; } break; } - } + static const MemoryRegionOps acpi_memory_hotplug_ops = { .read = acpi_memory_hotplug_read, .write = acpi_memory_hotplug_write, @@ -195,6 +237,36 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, return; } +void acpi_memory_unplug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, + DeviceState *dev, Error **errp) +{ +MemStatus *mdev; +Error *local_err = NULL; +int slot = object_property_get_int(OBJECT(dev), "slot", &local_err); + +if (local_err) { +error_propagate(errp, local_err); +return; +} + +if (slot >= mem_st->dev_count) { +char *dev_path = object_get_canonical_path(OBJECT(dev)); +error_setg(errp, "acpi_memory_plug_cb: " + "device [%s] returned invalid memory slot[%d]", +
Re: [Qemu-devel] [PATCH v12 2/5] apic: use per CPU AS to map APIC MMIO for TCG
On 10/03/2015 03:21 AM, Eduardo Habkost wrote: On Fri, Oct 02, 2015 at 03:24:24PM -0300, Eduardo Habkost wrote: On Tue, Sep 22, 2015 at 02:29:01PM +0200, Igor Mammedov wrote: On Wed, 16 Sep 2015 17:19:12 +0800 Zhu Guihua wrote: TCG supports per CPU address space, and the emulation quality is a bit better with it. So use per CPU address space to map APIC MMIO area. This allows the APIC base address of each cpu to be moved independent of others. Signed-off-by: Zhu Guihua Reviewed-by: Igor Mammedov The series seems to be OK when using KVM, but something is wrong with TCG. After applying this patch, my Fedora 20 image hangs on boot at: [ OK ] Started udev Coldplug all Devices. Starting dracut initqueue hook... [ OK ] Reached target System Initialization. [ OK ] Reached target Basic System. [8.988420] ACPI: PCI Interrupt Link [LNKD] enabled at IRQ 11 Before this patch, boot continues with: [ OK ] Reached target Basic System. [8.523293] ACPI: PCI Interrupt Link [LNKD] enabled at IRQ 11 [9.230955] vda: vda1 [ OK ] Started dracut initqueue hook. Mounting /sysroot... I am running QEMU as: $ ./x86_64-softmmu/qemu-system-x86_64 -drive if=virtio,file=/home/ehabkost/system/vmachines/Fedora-x86_64-20-20131211.1-sda.qcow2,format=qcow2 -machine pc,accel=tcg -smp 8,sockets=2,threads=2,cores=2,maxcpus=16 -serial stdio -nographic -monitor none Debugging revealed that this broke MSI delivery of virtio notifications. Writes to PCIDevice::bus_master_as (at msi_send_message()) don't get delivered to the APIC memory region anymore. This patch doesn't seem to be required for the removal of ICC bus, so I am applying the rest of the series anyway. If you see any problem with that, please let me know. Sorry for late reply. I'll look at this. Thanks, Zhu
[Qemu-devel] [RESEND PATCH v3] i386: keep cpu_model field in MachineState uptodate
Update cpu_model in MachineState for i386, so that the field can be used for cpu hotplug, instead of using a static variable. This patch is rebased on the latest master. Signed-off-by: Zhu Guihua Reviewed-by: Eduardo Habkost --- v3: -use PCMachineState in pc_cpus_init() instead MachineState v2: -transfer MachineState from all pc_cpus_init() callers --- hw/i386/pc.c | 17 - hw/i386/pc_piix.c| 2 +- hw/i386/pc_q35.c | 2 +- include/hw/i386/pc.h | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 682867a..208f553 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1077,11 +1077,10 @@ out: return cpu; } -static const char *current_cpu_model; - void pc_hot_add_cpu(const int64_t id, Error **errp) { X86CPU *cpu; +MachineState *machine = MACHINE(qdev_get_machine()); int64_t apic_id = x86_cpu_apic_id_from_index(id); Error *local_err = NULL; @@ -1109,7 +1108,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) return; } -cpu = pc_new_cpu(current_cpu_model, apic_id, &local_err); +cpu = pc_new_cpu(machine->cpu_model, apic_id, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -1117,22 +1116,22 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) object_unref(OBJECT(cpu)); } -void pc_cpus_init(const char *cpu_model) +void pc_cpus_init(PCMachineState *pcms) { int i; X86CPU *cpu = NULL; +MachineState *machine = MACHINE(pcms); Error *error = NULL; unsigned long apic_id_limit; /* init CPUs */ -if (cpu_model == NULL) { +if (machine->cpu_model == NULL) { #ifdef TARGET_X86_64 -cpu_model = "qemu64"; +machine->cpu_model = "qemu64"; #else -cpu_model = "qemu32"; +machine->cpu_model = "qemu32"; #endif } -current_cpu_model = cpu_model; apic_id_limit = pc_apic_id_limit(max_cpus); if (apic_id_limit > ACPI_CPU_HOTPLUG_ID_LIMIT) { @@ -1142,7 +1141,7 @@ void pc_cpus_init(const char *cpu_model) } for (i = 0; i < smp_cpus; i++) { -cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i), +cpu = pc_new_cpu(machine->cpu_model, x86_cpu_apic_id_from_index(i), &error); if (error) { error_report_err(error); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index ae7bbeb..0eacde1 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -139,7 +139,7 @@ static void pc_init1(MachineState *machine, exit(1); } -pc_cpus_init(machine->cpu_model); +pc_cpus_init(pcms); if (kvm_enabled() && kvmclock_enabled) { kvmclock_create(); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 19e6670..3744abd 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -128,7 +128,7 @@ static void pc_q35_init(MachineState *machine) exit(1); } -pc_cpus_init(machine->cpu_model); +pc_cpus_init(pcms); pc_acpi_init("q35-acpi-dsdt.aml"); kvmclock_create(); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 0503485..c5961d7 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -168,7 +168,7 @@ bool pc_machine_is_smm_enabled(PCMachineState *pcms); void pc_register_ferr_irq(qemu_irq irq); void pc_acpi_smi_interrupt(void *opaque, int irq, int level); -void pc_cpus_init(const char *cpu_model); +void pc_cpus_init(PCMachineState *pcms); void pc_hot_add_cpu(const int64_t id, Error **errp); void pc_acpi_init(const char *default_dsdt); -- 1.9.3
Re: [Qemu-devel] [PATCH v12 0/5] remove icc bus/bridge
Hi Eduardo, Can you help merge this patch series to your x86 tree? Thanks, Zhu On 09/16/2015 05:19 PM, Zhu Guihua wrote: ICC Bus was used for providing a hotpluggable bus for APIC and CPU, but now we use HotplugHandler to make hotplug. So ICC Bus is unnecessary. This code has passed the new pc-cpu-test. And I have tested with kvm along with kernel_irqchip=on/off, it works fine. This patch series is based on the latest master. v12: -move APIC MMIO mapping into x86_cpu_apic_realize() -change commit message in PATCH 4 v11: -improve commit messages -split per CPU AS change into a separate patch v10: -improve commit messages in patch 1 and 2 -make the check of cpu->cpu_as_root simplier v9: -use a callback to correct reset sequence for x86 -update apic mmio mapping Chen Fan (2): apic: move APIC's MMIO region mapping into APIC cpu/apic: drop icc bus/bridge Zhu Guihua (3): apic: use per CPU AS to map APIC MMIO for TCG x86: use new method to correct reset sequence icc_bus: drop the unused files default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - hw/i386/pc.c | 46 --- hw/i386/pc_piix.c | 9 +-- hw/i386/pc_q35.c | 9 +-- hw/intc/apic_common.c | 11 +--- include/hw/cpu/icc_bus.h | 82 -- include/hw/i386/apic_internal.h| 7 ++- include/hw/i386/pc.h | 2 +- target-i386/cpu.c | 33 --- 12 files changed, 58 insertions(+), 262 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h
Re: [Qemu-devel] cpu modelling and hotplug
Hi all, May I know whether the discussion is still ongoing? I checked Andreas's git tree, there was no changes about the topology. Plz let me know the schedule about this. Thanks, Zhu On 04/07/2015 08:43 PM, Christian Borntraeger wrote: We had a call and I was asked to write a summary about our conclusion. The more I wrote, there more I became uncertain if we really came to a conclusion and became more certain that we want to define the QMP/HMP/CLI interfaces first (or quite early in the process) As discussed I will provide an initial document as a discussion starter So here is my current understanding with each piece of information on one line, so that everybody can correct me or make additions: current wrap-up of architecture support --- x86 - Topology possible - can be hierarchical - interfaces to query topology - SMT: fanout in host, guest uses host threads to back guest vCPUS - supports cpu hotplug via cpu_add power - Topology possible - interfaces to query topology? - SMT: Power8: no threads in host and full core passed in due to HW design may change in the future s/390 - Topology possible - can be hierarchical - interfaces to query topology - always virtualized via PR/SM LPAR - host topology from LPAR can be heterogenous (e.g. 3 cpus in 1st socket, 4 in 2nd) - SMT: fanout in host, guest uses host threads to back guest vCPUS Current downsides of CPU definitions/hotplug --- - smp, sockets=,cores=,threads= builds only homogeneous topology - cpu_add does not tell were to add - artificial icc bus construct on x86 for several reasons (link, sysbus not hotpluggable..) discussions --- - we want to be able to (most important question, IHMO) - hotplug CPUs on power/x86/s390 and maybe others - define topology information - bind the guest topology to the host topology in some way - to host nodes - maybe also for gang scheduling of threads (might face reluctance from the linux scheduler folks) - not really deeply outlined in this call - QOM links must be allocated at boot time, but can be set later on - nothing that we want to expose to users - Machine provides QOM links that the device_add hotplug mechanism can use to add new CPUs into preallocated slots. "CPUs" can be groups of cores and/or threads. - hotplug and initial config should use same semantics - cpu and memory topology might be somewhat independent --> - define nodes - map CPUs to nodes - map memory to nodes - hotplug per - socket - core - thread ? Now comes the part where I am not sure if we came to a conclusion or not: - hotplug/definition per core (but not per thread) seems to handle all cases - core might have multiple threads ( and thus multiple cpustates) - as device statement (or object?) - mapping of cpus to nodes or defining the topology not really outlined in this call To be defined: - QEMU command line for initial setup - QEMU hmp/qmp interfaces for dynamic setup Christian .
Re: [Qemu-devel] [RFC PATCH v4 01/11] exec: Remove cpu from cpus list during cpu_exec_exit()
Hi Bharata, On 09/09/2015 03:56 PM, Bharata B Rao wrote: On Wed, Sep 09, 2015 at 03:41:30PM +0800, Zhu Guihua wrote: On 09/09/2015 01:52 PM, Bharata B Rao wrote: On Fri, Sep 04, 2015 at 03:31:24PM +1000, David Gibson wrote: On Thu, Aug 06, 2015 at 10:57:07AM +0530, Bharata B Rao wrote: CPUState *cpu gets added to the cpus list during cpu_exec_init(). It should be removed from cpu_exec_exit(). cpu_exec_init() is called from generic CPU::instance_finalize and some archs like PowerPC call it from CPU unrealizefn. So ensure that we dequeue the cpu only once. Instead of introducing a new field CPUState.queued, I could have used CPUState.cpu_index to check if the cpu is already dequeued from the list. Since that doesn't work for CONFIG_USER_ONLY, I had to add a new field. Signed-off-by: Bharata B Rao This seems reasonable to me, but I'm wondering how x86 cpu hotplug / unplug is working without it. x86 hotplug/unplug code currently resides in Zhu's git tree (git://github.com/zhugh/qemu). They are removing the CPU from the list explicitly in x86 CPU's instance_finalize routine. Sorry, my git tree is git://github.com/zhuguihua/qemu Now there was no progress about topology, so we don't know what will happen in x86. I am not sure whether we will take this method finally. Andreas had a presentation on this topic in KVM forum recently. Andreas - do you have any updates on the topology and other aspects of CPU hotplug so that we can align the CPU hotplug work in different archs accordingly and hope to get it merged in 2.5 time frame ? Do you update the patchset? My work in x86 has stopped for a while, Maybe I can get some ideas from another arch's worker. Thanks, Zhu
Re: [Qemu-devel] [RFC PATCH v4 01/11] exec: Remove cpu from cpus list during cpu_exec_exit()
On 11/12/2015 05:30 PM, Bharata B Rao wrote: On Thu, Nov 12, 2015 at 05:11:02PM +0800, Zhu Guihua wrote: Hi Bharata, On 09/09/2015 03:56 PM, Bharata B Rao wrote: On Wed, Sep 09, 2015 at 03:41:30PM +0800, Zhu Guihua wrote: On 09/09/2015 01:52 PM, Bharata B Rao wrote: On Fri, Sep 04, 2015 at 03:31:24PM +1000, David Gibson wrote: On Thu, Aug 06, 2015 at 10:57:07AM +0530, Bharata B Rao wrote: CPUState *cpu gets added to the cpus list during cpu_exec_init(). It should be removed from cpu_exec_exit(). cpu_exec_init() is called from generic CPU::instance_finalize and some archs like PowerPC call it from CPU unrealizefn. So ensure that we dequeue the cpu only once. Instead of introducing a new field CPUState.queued, I could have used CPUState.cpu_index to check if the cpu is already dequeued from the list. Since that doesn't work for CONFIG_USER_ONLY, I had to add a new field. Signed-off-by: Bharata B Rao This seems reasonable to me, but I'm wondering how x86 cpu hotplug / unplug is working without it. x86 hotplug/unplug code currently resides in Zhu's git tree (git://github.com/zhugh/qemu). They are removing the CPU from the list explicitly in x86 CPU's instance_finalize routine. Sorry, my git tree is git://github.com/zhuguihua/qemu Now there was no progress about topology, so we don't know what will happen in x86. I am not sure whether we will take this method finally. Andreas had a presentation on this topic in KVM forum recently. Andreas - do you have any updates on the topology and other aspects of CPU hotplug so that we can align the CPU hotplug work in different archs accordingly and hope to get it merged in 2.5 time frame ? Do you update the patchset? My work in x86 has stopped for a while, Maybe I can get some ideas from another arch's worker. My last version is here: https://lists.gnu.org/archive/html/qemu-devel/2015-08/msg00650.html I initally started with core level CPU hotplug, moved to socket level hotplug based on Andreas' patchset and then moved back again to core level hotplug. I was a bit confused about how the generic semantics would evovle and hence the work got delayed. I wil be posting the next version of my patchset based on core level semantics soon. I am hoping that I should be able to get CPU hotplug/unplug included in QEMU-2.6 timeframe. Thanks for your reply. Look forward to your next version. Regards, Zhu
Re: [Qemu-devel] [RFC PATCH v4 01/11] exec: Remove cpu from cpus list during cpu_exec_exit()
On 09/09/2015 01:52 PM, Bharata B Rao wrote: On Fri, Sep 04, 2015 at 03:31:24PM +1000, David Gibson wrote: On Thu, Aug 06, 2015 at 10:57:07AM +0530, Bharata B Rao wrote: CPUState *cpu gets added to the cpus list during cpu_exec_init(). It should be removed from cpu_exec_exit(). cpu_exec_init() is called from generic CPU::instance_finalize and some archs like PowerPC call it from CPU unrealizefn. So ensure that we dequeue the cpu only once. Instead of introducing a new field CPUState.queued, I could have used CPUState.cpu_index to check if the cpu is already dequeued from the list. Since that doesn't work for CONFIG_USER_ONLY, I had to add a new field. Signed-off-by: Bharata B Rao This seems reasonable to me, but I'm wondering how x86 cpu hotplug / unplug is working without it. x86 hotplug/unplug code currently resides in Zhu's git tree (git://github.com/zhugh/qemu). They are removing the CPU from the list explicitly in x86 CPU's instance_finalize routine. Sorry, my git tree is git://github.com/zhuguihua/qemu Now there was no progress about topology, so we don't know what will happen in x86. I am not sure whether we will take this method finally. Thanks, Zhu Since we add CPU to the list in cpu_exec_init(), I thought it makes sense to remove it in cpu_exec_exit(). May be it makes sense to separately purse this patch and the next one so that other archs are also taken into account correctly. Regards, Bharata.
Re: [Qemu-devel] [PATCH] cpu: introduce CpuTopoInfo structure for argument simplification
On 09/10/2015 12:11 AM, Eduardo Habkost wrote: On Mon, Sep 07, 2015 at 04:22:10PM +0200, Andreas Färber wrote: Am 07.09.2015 um 13:29 schrieb Paolo Bonzini: On 21/08/2015 11:34, Zhu Guihua wrote: @@ -107,14 +111,12 @@ static inline apic_id_t apicid_from_topo_ids(unsigned nr_cores, static inline void x86_topo_ids_from_idx(unsigned nr_cores, unsigned nr_threads, unsigned cpu_index, - unsigned *pkg_id, - unsigned *core_id, - unsigned *smt_id) + X86CPUTopoInfo *topo) { Isn't this function used in hw/i386/pc.c as well? In case it gets respun now, in Seattle I had asked Eduardo to update the subject with s/CpuTopoInfo/X86CPUTopoInfo/. I have fixed the subject line when applying to x86, and now added the following fix to the patch to avoid a respin: diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 9f2924e..c515fca 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1938,10 +1938,10 @@ static void pc_machine_initfn(Object *obj) static unsigned pc_cpu_index_to_socket_id(unsigned cpu_index) { -unsigned pkg_id, core_id, smt_id; +X86CPUTopoInfo topo; x86_topo_ids_from_idx(smp_cores, smp_threads, cpu_index, - &pkg_id, &core_id, &smt_id); -return pkg_id; + &topo); +return topo.pkg_id; } static void pc_machine_class_init(ObjectClass *oc, void *data) I am sorry for my carelessness, thanks for your work. Regards, Zhu
Re: [Qemu-devel] [PATCH v11 0/5] remove icc bus/bridge
ping ... On 09/02/2015 05:36 PM, Zhu Guihua wrote: ICC Bus was used for providing a hotpluggable bus for APIC and CPU, but now we use HotplugHandler to make hotplug. So ICC Bus is unnecessary. This code has passed the new pc-cpu-test. And I have tested with kvm along with kernel_irqchip=on/off, it works fine. This patch series is based on the latest master and '[PATCH v3] i386: keep cpu_model field in MachineState uptodate' https://lists.nongnu.org/archive/html/qemu-devel/2015-08/msg03375.html which has been reviewed but not been merged. v11: -improve commit messages -split per CPU AS change into a separate patch v10: -improve commit messages in patch 1 and 2 -make the check of cpu->cpu_as_root simplier v9: -use a callback to correct reset sequence for x86 -update apic mmio mapping Chen Fan (2): apic: move APIC's MMIO region mapping into APIC cpu/apic: drop icc bus/bridge Zhu Guihua (3): apic: use per CPU AS to map APIC MMIO for TCG x86: use new method to correct reset sequence icc_bus: drop the unused files default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - hw/i386/pc.c | 46 --- hw/i386/pc_piix.c | 9 +-- hw/i386/pc_q35.c | 9 +-- hw/intc/apic_common.c | 11 +--- include/hw/cpu/icc_bus.h | 82 -- include/hw/i386/apic_internal.h| 7 ++- include/hw/i386/pc.h | 2 +- target-i386/cpu.c | 33 --- 12 files changed, 58 insertions(+), 262 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h
Re: [Qemu-devel] [PATCH v11 4/5] cpu/apic: drop icc bus/bridge
On 09/14/2015 09:18 PM, Igor Mammedov wrote: On Wed, 2 Sep 2015 17:36:21 +0800 Zhu Guihua wrote: From: Chen Fan After CPU hotplug has been converted to BUS-less hot-plug infrastructure, the only function ICC bus performs is to propagate reset to LAPICs. However LAPIC could be reset by registering its reset handler after all device are initialized. Do so and drop ~200LOC of not needed anymore ICCBus related code. this patch drops about 30LOCs only ... PS: Doesn't apply to current master, please rebase. This patch rebased on my another patch '[PATCH v3] i386: keep cpu_model field in MachineState uptodate' https://lists.nongnu.org/archive/html/qemu-devel/2015-08/msg03375.html The patch has been reviewed by Eduardo, but not been merged. Should I only rebase on current master? Thanks, Zhu Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- hw/i386/pc.c| 19 --- hw/i386/pc_piix.c | 9 + hw/i386/pc_q35.c| 9 + hw/intc/apic_common.c | 5 ++--- include/hw/i386/apic_internal.h | 7 --- include/hw/i386/pc.h| 2 +- target-i386/cpu.c | 9 + 7 files changed, 14 insertions(+), 46 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 4b4a7f3..4c1d68a 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -59,7 +59,6 @@ #include "qemu/error-report.h" #include "hw/acpi/acpi.h" #include "hw/acpi/cpu_hotplug.h" -#include "hw/cpu/icc_bus.h" #include "hw/boards.h" #include "hw/pci/pci_host.h" #include "acpi-build.h" @@ -1052,23 +1051,16 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level) } static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id, - DeviceState *icc_bridge, Error **errp) + Error **errp) { X86CPU *cpu = NULL; Error *local_err = NULL; -if (icc_bridge == NULL) { -error_setg(&local_err, "Invalid icc-bridge value"); -goto out; -} - cpu = cpu_x86_create(cpu_model, &local_err); if (local_err != NULL) { goto out; } -qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc")); - object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err); object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); @@ -1083,7 +1075,6 @@ out: void pc_hot_add_cpu(const int64_t id, Error **errp) { -DeviceState *icc_bridge; MachineState *machine = MACHINE(qdev_get_machine()); X86CPU *cpu; int64_t apic_id = x86_cpu_apic_id_from_index(id); @@ -1113,9 +1104,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) return; } -icc_bridge = DEVICE(object_resolve_path_type("icc-bridge", - TYPE_ICC_BRIDGE, NULL)); -cpu = pc_new_cpu(machine->cpu_model, apic_id, icc_bridge, &local_err); +cpu = pc_new_cpu(machine->cpu_model, apic_id, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -1123,7 +1112,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) object_unref(OBJECT(cpu)); } -void pc_cpus_init(PCMachineState *pcms, DeviceState *icc_bridge) +void pc_cpus_init(PCMachineState *pcms) { int i; X86CPU *cpu = NULL; @@ -1149,7 +1138,7 @@ void pc_cpus_init(PCMachineState *pcms, DeviceState *icc_bridge) for (i = 0; i < smp_cpus; i++) { cpu = pc_new_cpu(machine->cpu_model, x86_cpu_apic_id_from_index(i), - icc_bridge, &error); + &error); if (error) { error_report_err(error); exit(1); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index fd6130d..3a97826 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -39,7 +39,6 @@ #include "hw/kvm/clock.h" #include "sysemu/sysemu.h" #include "hw/sysbus.h" -#include "hw/cpu/icc_bus.h" #include "sysemu/arch_init.h" #include "sysemu/block-backend.h" #include "hw/i2c/smbus.h" @@ -96,7 +95,6 @@ static void pc_init1(MachineState *machine) MemoryRegion *ram_memory; MemoryRegion *pci_memory; MemoryRegion *rom_memory; -DeviceState *icc_bridge; PcGuestInfo *guest_info; ram_addr_t lowmem; @@ -141,11 +139,7 @@ static void pc_init1(MachineState *machine) exit(1); } -icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); -object_property_add_child(qdev_get_machine(), "icc-bridge", - OBJECT(icc_bridge), NULL); - -pc_cpus_init(pcms, icc_bridge); +pc_cpus_init(pcms); if (kvm_enabled() &&
[Qemu-devel] [PATCH v12 3/5] x86: use new method to correct reset sequence
During reset some devices (such as hpet, rtc) might send IRQ to APIC which changes APIC's state from default one it's supposed to have at machine startup time. Fix this by resetting APIC after devices have been reset to cancel any changes that qemu_devices_reset() might have done to its state. Signed-off-by: Zhu Guihua --- hw/i386/pc.c | 20 1 file changed, 20 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 631f89f..b414055 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1924,6 +1924,25 @@ static void pc_machine_initfn(Object *obj) NULL, &error_abort); } +static void pc_machine_reset(void) +{ +CPUState *cs; +X86CPU *cpu; + +qemu_devices_reset(); + +/* Reset APIC after devices have been reset to cancel + * any changes that qemu_devices_reset() might have done. + */ +CPU_FOREACH(cs) { +cpu = X86_CPU(cs); + +if (cpu->apic_state) { +device_reset(cpu->apic_state); +} +} +} + static unsigned pc_cpu_index_to_socket_id(unsigned cpu_index) { unsigned pkg_id, core_id, smt_id; @@ -1944,6 +1963,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) mc->default_boot_order = "cad"; mc->hot_add_cpu = pc_hot_add_cpu; mc->max_cpus = 255; +mc->reset = pc_machine_reset; hc->plug = pc_machine_device_plug_cb; hc->unplug_request = pc_machine_device_unplug_request_cb; hc->unplug = pc_machine_device_unplug_cb; -- 1.9.3
[Qemu-devel] [PATCH v12 0/5] remove icc bus/bridge
ICC Bus was used for providing a hotpluggable bus for APIC and CPU, but now we use HotplugHandler to make hotplug. So ICC Bus is unnecessary. This code has passed the new pc-cpu-test. And I have tested with kvm along with kernel_irqchip=on/off, it works fine. This patch series is based on the latest master. v12: -move APIC MMIO mapping into x86_cpu_apic_realize() -change commit message in PATCH 4 v11: -improve commit messages -split per CPU AS change into a separate patch v10: -improve commit messages in patch 1 and 2 -make the check of cpu->cpu_as_root simplier v9: -use a callback to correct reset sequence for x86 -update apic mmio mapping Chen Fan (2): apic: move APIC's MMIO region mapping into APIC cpu/apic: drop icc bus/bridge Zhu Guihua (3): apic: use per CPU AS to map APIC MMIO for TCG x86: use new method to correct reset sequence icc_bus: drop the unused files default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - hw/i386/pc.c | 46 --- hw/i386/pc_piix.c | 9 +-- hw/i386/pc_q35.c | 9 +-- hw/intc/apic_common.c | 11 +--- include/hw/cpu/icc_bus.h | 82 -- include/hw/i386/apic_internal.h| 7 ++- include/hw/i386/pc.h | 2 +- target-i386/cpu.c | 33 --- 12 files changed, 58 insertions(+), 262 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h -- 1.9.3
[Qemu-devel] [PATCH v12 5/5] icc_bus: drop the unused files
ICC bus impl has been droped, so all icc related files are not useful any more; delete them. Signed-off-by: Zhu Guihua --- default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - include/hw/cpu/icc_bus.h | 82 -- 5 files changed, 203 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 9393cf0..43c96d1 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -44,7 +44,6 @@ CONFIG_LPC_ICH9=y CONFIG_PCI_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y -CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_XIO3130=y diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index 28e2099..dfb8095 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -44,7 +44,6 @@ CONFIG_LPC_ICH9=y CONFIG_PCI_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y -CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_XIO3130=y diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs index 6381238..0954a18 100644 --- a/hw/cpu/Makefile.objs +++ b/hw/cpu/Makefile.objs @@ -2,5 +2,4 @@ obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o obj-$(CONFIG_REALVIEW) += realview_mpcore.o obj-$(CONFIG_A9MPCORE) += a9mpcore.o obj-$(CONFIG_A15MPCORE) += a15mpcore.o -obj-$(CONFIG_ICC_BUS) += icc_bus.o diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c deleted file mode 100644 index 6646ea2..000 --- a/hw/cpu/icc_bus.c +++ /dev/null @@ -1,118 +0,0 @@ -/* icc_bus.c - * emulate x86 ICC (Interrupt Controller Communications) bus - * - * Copyright (c) 2013 Red Hat, Inc - * - * Authors: - * Igor Mammedov - * - * 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 <http://www.gnu.org/licenses/> - */ -#include "hw/cpu/icc_bus.h" -#include "hw/sysbus.h" - -/* icc-bridge implementation */ - -static const TypeInfo icc_bus_info = { -.name = TYPE_ICC_BUS, -.parent = TYPE_BUS, -.instance_size = sizeof(ICCBus), -}; - - -/* icc-device implementation */ - -static void icc_device_realize(DeviceState *dev, Error **errp) -{ -ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(dev); - -/* convert to QOM */ -if (idc->realize) { -idc->realize(dev, errp); -} - -} - -static void icc_device_class_init(ObjectClass *oc, void *data) -{ -DeviceClass *dc = DEVICE_CLASS(oc); - -dc->realize = icc_device_realize; -dc->bus_type = TYPE_ICC_BUS; -} - -static const TypeInfo icc_device_info = { -.name = TYPE_ICC_DEVICE, -.parent = TYPE_DEVICE, -.abstract = true, -.instance_size = sizeof(ICCDevice), -.class_size = sizeof(ICCDeviceClass), -.class_init = icc_device_class_init, -}; - - -/* icc-bridge implementation */ - -typedef struct ICCBridgeState { -/*< private >*/ -SysBusDevice parent_obj; -/*< public >*/ - -ICCBus icc_bus; -MemoryRegion apic_container; -} ICCBridgeState; - -#define ICC_BRIDGE(obj) OBJECT_CHECK(ICCBridgeState, (obj), TYPE_ICC_BRIDGE) - -static void icc_bridge_init(Object *obj) -{ -ICCBridgeState *s = ICC_BRIDGE(obj); -SysBusDevice *sb = SYS_BUS_DEVICE(obj); - -qbus_create_inplace(&s->icc_bus, sizeof(s->icc_bus), TYPE_ICC_BUS, -DEVICE(s), "icc"); - -/* Do not change order of registering regions, - * APIC must be first registered region, board maps it by 0 index - */ -memory_region_init(&s->apic_container, obj, "icc-apic-container", - APIC_SPACE_SIZE); -sysbus_init_mmio(sb, &s->apic_container); -s->icc_bus.apic_address_space = &s->apic_container; -} - -static void icc_bridge_class_init(ObjectClass *oc, void *data) -{ -DeviceClass *dc = DEVICE_CLASS(oc); - -set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); -} - -static const TypeInfo icc_bridge_info = { -.name = TYPE_ICC_BRIDGE, -.parent = TYPE_SYS_BUS_DEVICE, -.instance_init = icc_bridge_init, -.instance_size = sizeof(ICCBridgeState), -.class_init = icc_bridge_class_init, -}; - - -static void icc_bus_register_types(void) -{ -
[Qemu-devel] [PATCH v12 4/5] cpu/apic: drop icc bus/bridge
From: Chen Fan After CPU hotplug has been converted to BUS-less hot-plug infrastructure, the only function ICC bus performs is to propagate reset to LAPICs. However LAPIC could be reset by registering its reset handler after all device are initialized. Do so and drop ~30LOC of not needed anymore ICCBus related code. Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- hw/i386/pc.c| 19 --- hw/i386/pc_piix.c | 9 + hw/i386/pc_q35.c| 9 + hw/intc/apic_common.c | 5 ++--- include/hw/i386/apic_internal.h | 7 --- include/hw/i386/pc.h| 2 +- target-i386/cpu.c | 9 + 7 files changed, 14 insertions(+), 46 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index b414055..1a690d0 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -59,7 +59,6 @@ #include "qemu/error-report.h" #include "hw/acpi/acpi.h" #include "hw/acpi/cpu_hotplug.h" -#include "hw/cpu/icc_bus.h" #include "hw/boards.h" #include "hw/pci/pci_host.h" #include "acpi-build.h" @@ -1052,23 +1051,16 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level) } static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id, - DeviceState *icc_bridge, Error **errp) + Error **errp) { X86CPU *cpu = NULL; Error *local_err = NULL; -if (icc_bridge == NULL) { -error_setg(&local_err, "Invalid icc-bridge value"); -goto out; -} - cpu = cpu_x86_create(cpu_model, &local_err); if (local_err != NULL) { goto out; } -qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc")); - object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err); object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); @@ -1085,7 +1077,6 @@ static const char *current_cpu_model; void pc_hot_add_cpu(const int64_t id, Error **errp) { -DeviceState *icc_bridge; X86CPU *cpu; int64_t apic_id = x86_cpu_apic_id_from_index(id); Error *local_err = NULL; @@ -1114,9 +1105,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) return; } -icc_bridge = DEVICE(object_resolve_path_type("icc-bridge", - TYPE_ICC_BRIDGE, NULL)); -cpu = pc_new_cpu(current_cpu_model, apic_id, icc_bridge, &local_err); +cpu = pc_new_cpu(current_cpu_model, apic_id, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -1124,7 +1113,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) object_unref(OBJECT(cpu)); } -void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) +void pc_cpus_init(const char *cpu_model) { int i; X86CPU *cpu = NULL; @@ -1150,7 +1139,7 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) for (i = 0; i < smp_cpus; i++) { cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i), - icc_bridge, &error); + &error); if (error) { error_report_err(error); exit(1); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 3f925b2..4335e9e 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -39,7 +39,6 @@ #include "hw/kvm/clock.h" #include "sysemu/sysemu.h" #include "hw/sysbus.h" -#include "hw/cpu/icc_bus.h" #include "sysemu/arch_init.h" #include "sysemu/block-backend.h" #include "hw/i2c/smbus.h" @@ -98,7 +97,6 @@ static void pc_init1(MachineState *machine, MemoryRegion *ram_memory; MemoryRegion *pci_memory; MemoryRegion *rom_memory; -DeviceState *icc_bridge; PcGuestInfo *guest_info; ram_addr_t lowmem; @@ -141,11 +139,7 @@ static void pc_init1(MachineState *machine, exit(1); } -icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); -object_property_add_child(qdev_get_machine(), "icc-bridge", - OBJECT(icc_bridge), NULL); - -pc_cpus_init(machine->cpu_model, icc_bridge); +pc_cpus_init(machine->cpu_model); if (kvm_enabled() && kvmclock_enabled) { kvmclock_create(); @@ -226,7 +220,6 @@ static void pc_init1(MachineState *machine, if (pci_enabled) { ioapic_init_gsi(gsi_state, "i440fx"); } -qdev_init_nofail(icc_bridge); pc_register_ferr_irq(gsi[13]); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 11601ab..616ec68 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -43,7 +43,6 @@ #include "hw/ide/pci.h" #include "hw/ide/ahci.h" #include "hw/usb.h" -#include "hw/cpu/icc_bus.h"
[Qemu-devel] [PATCH v12 1/5] apic: move APIC's MMIO region mapping into APIC
From: Chen Fan When ICC bus/bridge is removed, APIC MMIO will be left unmapped since it was mapped into system's address space indirectly by ICC bridge. Fix it by moving mapping into APIC code, so it would be possible to remove ICC bus/bridge code later. Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- hw/i386/pc.c | 7 --- hw/intc/apic_common.c | 6 -- target-i386/cpu.c | 15 +++ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 56aecce..631f89f 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1158,13 +1158,6 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) object_unref(OBJECT(cpu)); } -/* map APIC MMIO area if CPU has APIC */ -if (cpu && cpu->apic_state) { -/* XXX: what if the base changes? */ -sysbus_mmio_map_overlap(SYS_BUS_DEVICE(icc_bridge), 0, -APIC_DEFAULT_ADDRESS, 0x1000); -} - /* tell smbios about cpuid version and features */ smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); } diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index 0032b97..c0b32eb 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -296,7 +296,6 @@ static void apic_common_realize(DeviceState *dev, Error **errp) APICCommonClass *info; static DeviceState *vapic; static int apic_no; -static bool mmio_registered; if (apic_no >= MAX_APICS) { error_setg(errp, "%s initialization failed.", @@ -307,11 +306,6 @@ static void apic_common_realize(DeviceState *dev, Error **errp) info = APIC_COMMON_GET_CLASS(s); info->realize(dev, errp); -if (!mmio_registered) { -ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev)); -memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory); -mmio_registered = true; -} /* Note: We need at least 1M to map the VAPIC option ROM */ if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK && diff --git a/target-i386/cpu.c b/target-i386/cpu.c index cfb8aa7..050ce11 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2745,15 +2745,30 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp) /* TODO: convert to link<> */ apic = APIC_COMMON(cpu->apic_state); apic->cpu = cpu; +apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE; } static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) { +APICCommonState *apic; +static bool apic_mmio_map_once; + if (cpu->apic_state == NULL) { return; } object_property_set_bool(OBJECT(cpu->apic_state), true, "realized", errp); + +/* Map APIC MMIO area */ +apic = APIC_COMMON(cpu->apic_state); +if (!apic_mmio_map_once) { +memory_region_add_subregion_overlap(get_system_memory(), +apic->apicbase & +MSR_IA32_APICBASE_BASE, +&apic->io_memory, +0x1000); +apic_mmio_map_once = true; + } } static void x86_cpu_machine_done(Notifier *n, void *unused) -- 1.9.3
[Qemu-devel] [PATCH v12 2/5] apic: use per CPU AS to map APIC MMIO for TCG
TCG supports per CPU address space, and the emulation quality is a bit better with it. So use per CPU address space to map APIC MMIO area. This allows the APIC base address of each cpu to be moved independent of others. Signed-off-by: Zhu Guihua --- target-i386/cpu.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 050ce11..692a284 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2759,9 +2759,18 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) object_property_set_bool(OBJECT(cpu->apic_state), true, "realized", errp); -/* Map APIC MMIO area */ +/* Map APIC MMIO area, use per-CPU address space if available (TCG + * supports it, KVM doesn't). This allows the APIC base address of + * each CPU to be moved independently. + */ apic = APIC_COMMON(cpu->apic_state); -if (!apic_mmio_map_once) { +if (tcg_enabled()) { +memory_region_add_subregion_overlap(cpu->cpu_as_root, +apic->apicbase & +MSR_IA32_APICBASE_BASE, +&apic->io_memory, +0x1000); +} else if (!apic_mmio_map_once) { memory_region_add_subregion_overlap(get_system_memory(), apic->apicbase & MSR_IA32_APICBASE_BASE, -- 1.9.3
Re: [Qemu-devel] [RFC PATCH v4 00/11] sPAPR CPU hotplug
On 08/06/2015 01:27 PM, Bharata B Rao wrote: Hi, This is the next version of CPU hotplug support patchset for PowerPC sPAPR guests. This is a split-out from the previous version (v3) that was carrying CPU and memory hotplug together. This patchset applies on spapr-next branch of David Gibson's tree. In the previous version, I was doing CPU addition at socket granularity. One hotplug request would add one complete CPU socket with all the cores and threads as per the boot time topology specification. Based on the feedback for v3, I am switching back to earlier method wherein I don't have the notion of socket device. In this version I don't create any additional device abstraction over CPU device, but use the existing CPU device and add full cores at once. One hotplug request will add a complete core with all the underlying threads. So the new generic infrastructure is generic socket or generic core? Cc: Andreas What about hot-adding a core device for x86 too? Hot-plug per core seems to handle all cases. thanks, Zhu I have enabled device_add based hotplug for POWER8 family for processors and currently the semantics looks like this: (qemu) device_add POWER8-powerpc64-cpu,id=cpu8 v3: https://lists.nongnu.org/archive/html/qemu-devel/2015-04/msg02910.html Bharata B Rao (10): exec: Remove cpu from cpus list during cpu_exec_exit() exec: Do vmstate unregistration from cpu_exec_exit() cpus: Add a sync version of cpu_remove() xics_kvm: Add cpu_destroy method to XICS spapr: Create pseries-2.5 machine spapr: Enable CPU hotplug for pseries-2.5 and add CPU DRC DT entries spapr: CPU hotplug support spapr: Support topologies with unfilled cores spapr: CPU hot unplug support target-ppc: Enable CPU hotplug for POWER8 CPU family Gu Zheng (1): cpus: Reclaim vCPU objects cpus.c | 55 exec.c | 30 + hw/intc/xics.c | 12 ++ hw/intc/xics_kvm.c | 9 ++ hw/ppc/spapr.c | 300 +++- hw/ppc/spapr_events.c | 3 + hw/ppc/spapr_rtas.c | 11 ++ include/hw/ppc/spapr.h | 1 + include/hw/ppc/xics.h | 2 + include/qom/cpu.h | 19 +++ include/sysemu/kvm.h| 1 + kvm-all.c | 57 - kvm-stub.c | 5 + target-ppc/translate_init.c | 10 ++ 14 files changed, 511 insertions(+), 4 deletions(-)
[Qemu-devel] [RESEND PATCH v9 2/4] x86: use new method to correct reset sequence
Something must be occur during reset of the X86 platform in a specific order. For example, the apic reset should be after some devices (such as hpet, rtc) reset, so that the apic register could be set to default values. This patch uses the new QEMUMachine reset method to solve the above problem, ensuring the various reset happen in the correct order. Signed-off-by: Zhu Guihua --- hw/i386/pc.c | 17 + 1 file changed, 17 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 8b7dbe5..0e83dc9 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1929,6 +1929,22 @@ static void pc_machine_initfn(Object *obj) NULL, &error_abort); } +static void pc_machine_reset(void) +{ +CPUState *cs; +X86CPU *cpu; + +qemu_devices_reset(); + +CPU_FOREACH(cs) { +cpu = X86_CPU(cs); + +if (cpu->apic_state) { +device_reset(cpu->apic_state); +} +} +} + static unsigned pc_cpu_index_to_socket_id(unsigned cpu_index) { unsigned pkg_id, core_id, smt_id; @@ -1949,6 +1965,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) mc->default_boot_order = "cad"; mc->hot_add_cpu = pc_hot_add_cpu; mc->max_cpus = 255; +mc->reset = pc_machine_reset; hc->plug = pc_machine_device_plug_cb; hc->unplug_request = pc_machine_device_unplug_request_cb; hc->unplug = pc_machine_device_unplug_cb; -- 1.9.3
[Qemu-devel] [RESEND PATCH v9 3/4] cpu/apic: drop icc bus/bridge
From: Chen Fan After CPU hotplug has been converted to BUS-less hot-plug infrastructure, the only function ICC bus performs is to propagate reset to LAPICs. However LAPIC could be reset by registering its reset handler after all device are initialized. Do so and drop ~200LOC of not needed anymore ICCBus related code. Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- hw/i386/pc.c| 19 --- hw/i386/pc_piix.c | 9 + hw/i386/pc_q35.c| 9 + hw/intc/apic_common.c | 5 ++--- include/hw/i386/apic_internal.h | 7 --- include/hw/i386/pc.h| 2 +- target-i386/cpu.c | 9 + 7 files changed, 14 insertions(+), 46 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 0e83dc9..7291037 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -59,7 +59,6 @@ #include "qemu/error-report.h" #include "hw/acpi/acpi.h" #include "hw/acpi/cpu_hotplug.h" -#include "hw/cpu/icc_bus.h" #include "hw/boards.h" #include "hw/pci/pci_host.h" #include "acpi-build.h" @@ -1052,23 +1051,16 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level) } static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id, - DeviceState *icc_bridge, Error **errp) + Error **errp) { X86CPU *cpu = NULL; Error *local_err = NULL; -if (icc_bridge == NULL) { -error_setg(&local_err, "Invalid icc-bridge value"); -goto out; -} - cpu = cpu_x86_create(cpu_model, &local_err); if (local_err != NULL) { goto out; } -qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc")); - object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err); object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); @@ -1085,7 +1077,6 @@ static const char *current_cpu_model; void pc_hot_add_cpu(const int64_t id, Error **errp) { -DeviceState *icc_bridge; X86CPU *cpu; int64_t apic_id = x86_cpu_apic_id_from_index(id); Error *local_err = NULL; @@ -1114,9 +1105,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) return; } -icc_bridge = DEVICE(object_resolve_path_type("icc-bridge", - TYPE_ICC_BRIDGE, NULL)); -cpu = pc_new_cpu(current_cpu_model, apic_id, icc_bridge, &local_err); +cpu = pc_new_cpu(current_cpu_model, apic_id, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -1124,7 +1113,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) object_unref(OBJECT(cpu)); } -void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) +void pc_cpus_init(const char *cpu_model) { int i; X86CPU *cpu = NULL; @@ -1150,7 +1139,7 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) for (i = 0; i < smp_cpus; i++) { cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i), - icc_bridge, &error); + &error); if (error) { error_report_err(error); exit(1); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 9558467..b6d68aa 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -39,7 +39,6 @@ #include "hw/kvm/clock.h" #include "sysemu/sysemu.h" #include "hw/sysbus.h" -#include "hw/cpu/icc_bus.h" #include "sysemu/arch_init.h" #include "sysemu/block-backend.h" #include "hw/i2c/smbus.h" @@ -96,7 +95,6 @@ static void pc_init1(MachineState *machine) MemoryRegion *ram_memory; MemoryRegion *pci_memory; MemoryRegion *rom_memory; -DeviceState *icc_bridge; PcGuestInfo *guest_info; ram_addr_t lowmem; @@ -141,11 +139,7 @@ static void pc_init1(MachineState *machine) exit(1); } -icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); -object_property_add_child(qdev_get_machine(), "icc-bridge", - OBJECT(icc_bridge), NULL); - -pc_cpus_init(machine->cpu_model, icc_bridge); +pc_cpus_init(machine->cpu_model); if (kvm_enabled() && kvmclock_enabled) { kvmclock_create(); @@ -223,7 +217,6 @@ static void pc_init1(MachineState *machine) if (pci_enabled) { ioapic_init_gsi(gsi_state, "i440fx"); } -qdev_init_nofail(icc_bridge); pc_register_ferr_irq(gsi[13]); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index c07d65b..ef3c490 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -43,7 +43,6 @@ #include "hw/ide/pci.h" #include "hw/ide/ahci.h" #include "hw/usb.h" -#include "hw/cpu/icc_bus.h"
[Qemu-devel] [RESEND PATCH v9 0/4] remove icc bus/bridge
ICC Bus was used for providing a hotpluggable bus for APIC and CPU, but now we use HotplugHandler to make hotplug. So ICC Bus is unnecessary. This code has passed the new pc-cpu-test. And I have tested with kvm along with kernel_irqchip=on/off, it works fine. This patch series is based on the latest master. v9: -use a callback to correct reset sequence for x86 -update apic mmio mapping v8: -add a wrapper to specify reset order v7: -update to register reset handler for main_system_bus when created -register reset handler for apic after all devices are initialized Chen Fan (2): apic: map APIC's MMIO region at each CPU's address space cpu/apic: drop icc bus/bridge Zhu Guihua (2): x86: use new method to correct reset sequence icc_bus: drop the unused files default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - hw/i386/pc.c | 43 +++--- hw/i386/pc_piix.c | 9 +-- hw/i386/pc_q35.c | 9 +-- hw/intc/apic_common.c | 11 +--- include/hw/cpu/icc_bus.h | 82 -- include/hw/i386/apic_internal.h| 7 ++- include/hw/i386/pc.h | 2 +- target-i386/cpu.c | 30 +++--- 12 files changed, 52 insertions(+), 262 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h -- 1.9.3
[Qemu-devel] [RESEND PATCH v9 4/4] icc_bus: drop the unused files
ICC bus impl has been droped, so all icc related files are not useful any more; delete them. Signed-off-by: Zhu Guihua --- default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - include/hw/cpu/icc_bus.h | 82 -- 5 files changed, 203 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 5eaafa1..70391ed 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -43,7 +43,6 @@ CONFIG_LPC_ICH9=y CONFIG_PCI_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y -CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_XIO3130=y diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index 28e2099..dfb8095 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -44,7 +44,6 @@ CONFIG_LPC_ICH9=y CONFIG_PCI_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y -CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_XIO3130=y diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs index 6381238..0954a18 100644 --- a/hw/cpu/Makefile.objs +++ b/hw/cpu/Makefile.objs @@ -2,5 +2,4 @@ obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o obj-$(CONFIG_REALVIEW) += realview_mpcore.o obj-$(CONFIG_A9MPCORE) += a9mpcore.o obj-$(CONFIG_A15MPCORE) += a15mpcore.o -obj-$(CONFIG_ICC_BUS) += icc_bus.o diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c deleted file mode 100644 index 6646ea2..000 --- a/hw/cpu/icc_bus.c +++ /dev/null @@ -1,118 +0,0 @@ -/* icc_bus.c - * emulate x86 ICC (Interrupt Controller Communications) bus - * - * Copyright (c) 2013 Red Hat, Inc - * - * Authors: - * Igor Mammedov - * - * 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 <http://www.gnu.org/licenses/> - */ -#include "hw/cpu/icc_bus.h" -#include "hw/sysbus.h" - -/* icc-bridge implementation */ - -static const TypeInfo icc_bus_info = { -.name = TYPE_ICC_BUS, -.parent = TYPE_BUS, -.instance_size = sizeof(ICCBus), -}; - - -/* icc-device implementation */ - -static void icc_device_realize(DeviceState *dev, Error **errp) -{ -ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(dev); - -/* convert to QOM */ -if (idc->realize) { -idc->realize(dev, errp); -} - -} - -static void icc_device_class_init(ObjectClass *oc, void *data) -{ -DeviceClass *dc = DEVICE_CLASS(oc); - -dc->realize = icc_device_realize; -dc->bus_type = TYPE_ICC_BUS; -} - -static const TypeInfo icc_device_info = { -.name = TYPE_ICC_DEVICE, -.parent = TYPE_DEVICE, -.abstract = true, -.instance_size = sizeof(ICCDevice), -.class_size = sizeof(ICCDeviceClass), -.class_init = icc_device_class_init, -}; - - -/* icc-bridge implementation */ - -typedef struct ICCBridgeState { -/*< private >*/ -SysBusDevice parent_obj; -/*< public >*/ - -ICCBus icc_bus; -MemoryRegion apic_container; -} ICCBridgeState; - -#define ICC_BRIDGE(obj) OBJECT_CHECK(ICCBridgeState, (obj), TYPE_ICC_BRIDGE) - -static void icc_bridge_init(Object *obj) -{ -ICCBridgeState *s = ICC_BRIDGE(obj); -SysBusDevice *sb = SYS_BUS_DEVICE(obj); - -qbus_create_inplace(&s->icc_bus, sizeof(s->icc_bus), TYPE_ICC_BUS, -DEVICE(s), "icc"); - -/* Do not change order of registering regions, - * APIC must be first registered region, board maps it by 0 index - */ -memory_region_init(&s->apic_container, obj, "icc-apic-container", - APIC_SPACE_SIZE); -sysbus_init_mmio(sb, &s->apic_container); -s->icc_bus.apic_address_space = &s->apic_container; -} - -static void icc_bridge_class_init(ObjectClass *oc, void *data) -{ -DeviceClass *dc = DEVICE_CLASS(oc); - -set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); -} - -static const TypeInfo icc_bridge_info = { -.name = TYPE_ICC_BRIDGE, -.parent = TYPE_SYS_BUS_DEVICE, -.instance_init = icc_bridge_init, -.instance_size = sizeof(ICCBridgeState), -.class_init = icc_bridge_class_init, -}; - - -static void icc_bus_register_types(void) -{ -
[Qemu-devel] [RESEND PATCH v9 1/4] apic: map APIC's MMIO region at each CPU's address space
From: Chen Fan Replace mapping APIC at global system address space with mapping it at per-CPU address spaces. Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- hw/i386/pc.c | 7 --- hw/intc/apic_common.c | 6 -- target-i386/cpu.c | 21 + 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 9f2924e..8b7dbe5 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1158,13 +1158,6 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) object_unref(OBJECT(cpu)); } -/* map APIC MMIO area if CPU has APIC */ -if (cpu && cpu->apic_state) { -/* XXX: what if the base changes? */ -sysbus_mmio_map_overlap(SYS_BUS_DEVICE(icc_bridge), 0, -APIC_DEFAULT_ADDRESS, 0x1000); -} - /* tell smbios about cpuid version and features */ smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); } diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index 0032b97..c0b32eb 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -296,7 +296,6 @@ static void apic_common_realize(DeviceState *dev, Error **errp) APICCommonClass *info; static DeviceState *vapic; static int apic_no; -static bool mmio_registered; if (apic_no >= MAX_APICS) { error_setg(errp, "%s initialization failed.", @@ -307,11 +306,6 @@ static void apic_common_realize(DeviceState *dev, Error **errp) info = APIC_COMMON_GET_CLASS(s); info->realize(dev, errp); -if (!mmio_registered) { -ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev)); -memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory); -mmio_registered = true; -} /* Note: We need at least 1M to map the VAPIC option ROM */ if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK && diff --git a/target-i386/cpu.c b/target-i386/cpu.c index cfb8aa7..8eed88c 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2745,6 +2745,7 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp) /* TODO: convert to link<> */ apic = APIC_COMMON(cpu->apic_state); apic->cpu = cpu; +apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE; } static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) @@ -2789,8 +2790,10 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) X86CPU *cpu = X86_CPU(dev); X86CPUClass *xcc = X86_CPU_GET_CLASS(dev); CPUX86State *env = &cpu->env; +APICCommonState *apic; Error *local_err = NULL; static bool ht_warned; +static bool apic_mmio_map_once; if (cpu->apic_id < 0) { error_setg(errp, "apic-id property was not initialized properly"); @@ -2877,6 +2880,24 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) if (local_err != NULL) { goto out; } + +/* map APIC MMIO area */ +apic = APIC_COMMON(cpu->apic_state); +if (tcg_enabled()) { +memory_region_add_subregion_overlap(cpu->cpu_as_root, +apic->apicbase & +MSR_IA32_APICBASE_BASE, +&apic->io_memory, +0x1000); +} else if (!apic_mmio_map_once) { +memory_region_add_subregion_overlap(get_system_memory(), +apic->apicbase & +MSR_IA32_APICBASE_BASE, +&apic->io_memory, +0x1000); +apic_mmio_map_once = true; +} + cpu_reset(cs); xcc->parent_realize(dev, &local_err); -- 1.9.3
[Qemu-devel] [PATCH] i386: keep cpu_model field in MachineState uptodate
Update cpu_model in MachineState for i386, so that the field can be used for cpu hotplug, instead of using a static variable. Signed-off-by: Zhu Guihua --- hw/i386/pc.c | 17 - hw/i386/pc_piix.c| 2 +- hw/i386/pc_q35.c | 2 +- include/hw/i386/pc.h | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 9f2924e..977442f 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1081,11 +1081,10 @@ out: return cpu; } -static const char *current_cpu_model; - void pc_hot_add_cpu(const int64_t id, Error **errp) { DeviceState *icc_bridge; +MachineState *machine = MACHINE(qdev_get_machine()); X86CPU *cpu; int64_t apic_id = x86_cpu_apic_id_from_index(id); Error *local_err = NULL; @@ -1116,7 +1115,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) icc_bridge = DEVICE(object_resolve_path_type("icc-bridge", TYPE_ICC_BRIDGE, NULL)); -cpu = pc_new_cpu(current_cpu_model, apic_id, icc_bridge, &local_err); +cpu = pc_new_cpu(machine->cpu_model, apic_id, icc_bridge, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -1124,22 +1123,22 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) object_unref(OBJECT(cpu)); } -void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) +void pc_cpus_init(DeviceState *icc_bridge) { int i; X86CPU *cpu = NULL; +MachineState *machine = MACHINE(qdev_get_machine()); Error *error = NULL; unsigned long apic_id_limit; /* init CPUs */ -if (cpu_model == NULL) { +if (machine->cpu_model == NULL) { #ifdef TARGET_X86_64 -cpu_model = "qemu64"; +machine->cpu_model = "qemu64"; #else -cpu_model = "qemu32"; +machine->cpu_model = "qemu32"; #endif } -current_cpu_model = cpu_model; apic_id_limit = pc_apic_id_limit(max_cpus); if (apic_id_limit > ACPI_CPU_HOTPLUG_ID_LIMIT) { @@ -1149,7 +1148,7 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) } for (i = 0; i < smp_cpus; i++) { -cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i), +cpu = pc_new_cpu(machine->cpu_model, x86_cpu_apic_id_from_index(i), icc_bridge, &error); if (error) { error_report_err(error); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 9558467..860d034 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -145,7 +145,7 @@ static void pc_init1(MachineState *machine) object_property_add_child(qdev_get_machine(), "icc-bridge", OBJECT(icc_bridge), NULL); -pc_cpus_init(machine->cpu_model, icc_bridge); +pc_cpus_init(icc_bridge); if (kvm_enabled() && kvmclock_enabled) { kvmclock_create(); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index c07d65b..29c3fde 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -136,7 +136,7 @@ static void pc_q35_init(MachineState *machine) object_property_add_child(qdev_get_machine(), "icc-bridge", OBJECT(icc_bridge), NULL); -pc_cpus_init(machine->cpu_model, icc_bridge); +pc_cpus_init(icc_bridge); pc_acpi_init("q35-acpi-dsdt.aml"); kvmclock_create(); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index d0cad87..6bf9ef3 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -161,7 +161,7 @@ bool pc_machine_is_smm_enabled(PCMachineState *pcms); void pc_register_ferr_irq(qemu_irq irq); void pc_acpi_smi_interrupt(void *opaque, int irq, int level); -void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge); +void pc_cpus_init(DeviceState *icc_bridge); void pc_hot_add_cpu(const int64_t id, Error **errp); void pc_acpi_init(const char *default_dsdt); -- 1.9.3
[Qemu-devel] [PATCH] cpu: introduce CpuTopoInfo structure for argument simplification
From: Chen Fan In order to simplify arguments of function, introduce a new struct named X86CPUTopoInfo. Originally, this patch was in the patchset "cpu: add device_add foo-x86_64-cpu support". Now put it into a separate patch so that it can be merged ASAP. Reviewed-by: Eduardo Habkost Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- include/hw/i386/topology.h | 33 + 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h index 9c6f3a9..148cc1b 100644 --- a/include/hw/i386/topology.h +++ b/include/hw/i386/topology.h @@ -47,6 +47,12 @@ */ typedef uint32_t apic_id_t; +typedef struct X86CPUTopoInfo { +unsigned pkg_id; +unsigned core_id; +unsigned smt_id; +} X86CPUTopoInfo; + /* Return the bit width needed for 'count' IDs */ static unsigned apicid_bitwidth_for_count(unsigned count) @@ -92,13 +98,11 @@ static inline unsigned apicid_pkg_offset(unsigned nr_cores, unsigned nr_threads) */ static inline apic_id_t apicid_from_topo_ids(unsigned nr_cores, unsigned nr_threads, - unsigned pkg_id, - unsigned core_id, - unsigned smt_id) + const X86CPUTopoInfo *topo) { -return (pkg_id << apicid_pkg_offset(nr_cores, nr_threads)) | - (core_id << apicid_core_offset(nr_cores, nr_threads)) | - smt_id; +return (topo->pkg_id << apicid_pkg_offset(nr_cores, nr_threads)) | + (topo->core_id << apicid_core_offset(nr_cores, nr_threads)) | + topo->smt_id; } /* Calculate thread/core/package IDs for a specific topology, @@ -107,14 +111,12 @@ static inline apic_id_t apicid_from_topo_ids(unsigned nr_cores, static inline void x86_topo_ids_from_idx(unsigned nr_cores, unsigned nr_threads, unsigned cpu_index, - unsigned *pkg_id, - unsigned *core_id, - unsigned *smt_id) + X86CPUTopoInfo *topo) { unsigned core_index = cpu_index / nr_threads; -*smt_id = cpu_index % nr_threads; -*core_id = core_index % nr_cores; -*pkg_id = core_index / nr_cores; +topo->smt_id = cpu_index % nr_threads; +topo->core_id = core_index % nr_cores; +topo->pkg_id = core_index / nr_cores; } /* Make APIC ID for the CPU 'cpu_index' @@ -125,10 +127,9 @@ static inline apic_id_t x86_apicid_from_cpu_idx(unsigned nr_cores, unsigned nr_threads, unsigned cpu_index) { -unsigned pkg_id, core_id, smt_id; -x86_topo_ids_from_idx(nr_cores, nr_threads, cpu_index, - &pkg_id, &core_id, &smt_id); -return apicid_from_topo_ids(nr_cores, nr_threads, pkg_id, core_id, smt_id); +X86CPUTopoInfo topo; +x86_topo_ids_from_idx(nr_cores, nr_threads, cpu_index, &topo); +return apicid_from_topo_ids(nr_cores, nr_threads, &topo); } #endif /* HW_I386_TOPOLOGY_H */ -- 1.9.3
[Qemu-devel] [PATCH v2] i386: keep cpu_model field in MachineState uptodate
Update cpu_model in MachineState for i386, so that the field can be used for cpu hotplug, instead of using a static variable. Signed-off-by: Zhu Guihua --- v2: -transfer MachineState from all pc_cpus_init() callers --- hw/i386/pc.c | 16 +++- hw/i386/pc_piix.c| 2 +- hw/i386/pc_q35.c | 2 +- include/hw/i386/pc.h | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 9f2924e..46ea74a 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1081,11 +1081,10 @@ out: return cpu; } -static const char *current_cpu_model; - void pc_hot_add_cpu(const int64_t id, Error **errp) { DeviceState *icc_bridge; +MachineState *machine = MACHINE(qdev_get_machine()); X86CPU *cpu; int64_t apic_id = x86_cpu_apic_id_from_index(id); Error *local_err = NULL; @@ -1116,7 +1115,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) icc_bridge = DEVICE(object_resolve_path_type("icc-bridge", TYPE_ICC_BRIDGE, NULL)); -cpu = pc_new_cpu(current_cpu_model, apic_id, icc_bridge, &local_err); +cpu = pc_new_cpu(machine->cpu_model, apic_id, icc_bridge, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -1124,7 +1123,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) object_unref(OBJECT(cpu)); } -void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) +void pc_cpus_init(MachineState *machine, DeviceState *icc_bridge) { int i; X86CPU *cpu = NULL; @@ -1132,14 +1131,13 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) unsigned long apic_id_limit; /* init CPUs */ -if (cpu_model == NULL) { +if (machine->cpu_model == NULL) { #ifdef TARGET_X86_64 -cpu_model = "qemu64"; +machine->cpu_model = "qemu64"; #else -cpu_model = "qemu32"; +machine->cpu_model = "qemu32"; #endif } -current_cpu_model = cpu_model; apic_id_limit = pc_apic_id_limit(max_cpus); if (apic_id_limit > ACPI_CPU_HOTPLUG_ID_LIMIT) { @@ -1149,7 +1147,7 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) } for (i = 0; i < smp_cpus; i++) { -cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i), +cpu = pc_new_cpu(machine->cpu_model, x86_cpu_apic_id_from_index(i), icc_bridge, &error); if (error) { error_report_err(error); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 9558467..7e16665 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -145,7 +145,7 @@ static void pc_init1(MachineState *machine) object_property_add_child(qdev_get_machine(), "icc-bridge", OBJECT(icc_bridge), NULL); -pc_cpus_init(machine->cpu_model, icc_bridge); +pc_cpus_init(machine, icc_bridge); if (kvm_enabled() && kvmclock_enabled) { kvmclock_create(); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index c07d65b..e7249d2 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -136,7 +136,7 @@ static void pc_q35_init(MachineState *machine) object_property_add_child(qdev_get_machine(), "icc-bridge", OBJECT(icc_bridge), NULL); -pc_cpus_init(machine->cpu_model, icc_bridge); +pc_cpus_init(machine, icc_bridge); pc_acpi_init("q35-acpi-dsdt.aml"); kvmclock_create(); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index d0cad87..ae0184d 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -161,7 +161,7 @@ bool pc_machine_is_smm_enabled(PCMachineState *pcms); void pc_register_ferr_irq(qemu_irq irq); void pc_acpi_smi_interrupt(void *opaque, int irq, int level); -void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge); +void pc_cpus_init(MachineState *machine, DeviceState *icc_bridge); void pc_hot_add_cpu(const int64_t id, Error **errp); void pc_acpi_init(const char *default_dsdt); -- 1.9.3
Re: [Qemu-devel] [PATCH v2] i386: keep cpu_model field in MachineState uptodate
On 08/26/2015 11:11 PM, Eduardo Habkost wrote: On Mon, Aug 24, 2015 at 05:42:09PM +0800, Zhu Guihua wrote: Update cpu_model in MachineState for i386, so that the field can be used for cpu hotplug, instead of using a static variable. Signed-off-by: Zhu Guihua [...] -void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) +void pc_cpus_init(MachineState *machine, DeviceState *icc_bridge) This is a PC initialization function, so a PCMachineState argument makes more sense. See pc_cmos_init(), load_linux(), pc_guest_info_init(), pc_memory_init(), etc. Oh, I know how to do this. Thanks for your suggestion. Thanks, Zhu The rest looks good.
Re: [Qemu-devel] [RESEND PATCH v9 1/4] apic: map APIC's MMIO region at each CPU's address space
On 08/26/2015 11:49 PM, Eduardo Habkost wrote: On Wed, Aug 26, 2015 at 11:27:08AM -0400, Paolo Bonzini wrote: [...] +if (tcg_enabled()) { +memory_region_add_subregion_overlap(cpu->cpu_as_root, +apic->apicbase & +MSR_IA32_APICBASE_BASE, +&apic->io_memory, +0x1000); Why exactly is this necessary? If this is necessary, why don't we need to do this for non-TCG accelerators? At least KVM and qtest do not support per-CPU address spaces. Right, but given this restriction why can't we also do whatever we need to work without the per-CPU address spaces with TCG? Because the emulation quality is indeed a bit better with the per-CPU address spaces; you could move each APIC's base address independent of the others. However, this is not a feature that is actually used by anything in practice, so I doubt anyone cares about TCG implementing it correctly. Do we need additional changes in TCG to implement it correctly, or is this going to work out of the box as soon as we apply this series? If it's the latter, the patch makes sense to me (but please add a comment to the code explaining why). If it's the former, I don't see the point of making the code more complex before that feature is actually implemented by TCG. Also, we could make the logic simpler if we just check if cpu->cpu_as_root is set, e.g.: /* Use per-CPU address space if available (TCG supports it, KVM * doesn't). This allows the APIC base address of each CPU * to be moved independently. */ memory_region_add_subregion_overlap(cpu->cpu_as_root ?: get_system_memory(), apic->apicbase & MSR_IA32_APICBASE_BASE, &apic->io_memory, 0x1000); Yeah, the logic is better. I will take this, thanks. And, comments will be added in next version. Thanks, Zhu
[Qemu-devel] [PATCH v3] i386: keep cpu_model field in MachineState uptodate
Update cpu_model in MachineState for i386, so that the field can be used for cpu hotplug, instead of using a static variable. Signed-off-by: Zhu Guihua --- v3: -use PCMachineState in pc_cpus_init() instead MachineState v2: -transfer MachineState from all pc_cpus_init() callers --- hw/i386/pc.c | 17 - hw/i386/pc_piix.c| 2 +- hw/i386/pc_q35.c | 2 +- include/hw/i386/pc.h | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 9f2924e..b1c96a8 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1081,11 +1081,10 @@ out: return cpu; } -static const char *current_cpu_model; - void pc_hot_add_cpu(const int64_t id, Error **errp) { DeviceState *icc_bridge; +MachineState *machine = MACHINE(qdev_get_machine()); X86CPU *cpu; int64_t apic_id = x86_cpu_apic_id_from_index(id); Error *local_err = NULL; @@ -1116,7 +1115,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) icc_bridge = DEVICE(object_resolve_path_type("icc-bridge", TYPE_ICC_BRIDGE, NULL)); -cpu = pc_new_cpu(current_cpu_model, apic_id, icc_bridge, &local_err); +cpu = pc_new_cpu(machine->cpu_model, apic_id, icc_bridge, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -1124,22 +1123,22 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) object_unref(OBJECT(cpu)); } -void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) +void pc_cpus_init(PCMachineState *pcms, DeviceState *icc_bridge) { int i; X86CPU *cpu = NULL; +MachineState *machine = MACHINE(pcms); Error *error = NULL; unsigned long apic_id_limit; /* init CPUs */ -if (cpu_model == NULL) { +if (machine->cpu_model == NULL) { #ifdef TARGET_X86_64 -cpu_model = "qemu64"; +machine->cpu_model = "qemu64"; #else -cpu_model = "qemu32"; +machine->cpu_model = "qemu32"; #endif } -current_cpu_model = cpu_model; apic_id_limit = pc_apic_id_limit(max_cpus); if (apic_id_limit > ACPI_CPU_HOTPLUG_ID_LIMIT) { @@ -1149,7 +1148,7 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) } for (i = 0; i < smp_cpus; i++) { -cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i), +cpu = pc_new_cpu(machine->cpu_model, x86_cpu_apic_id_from_index(i), icc_bridge, &error); if (error) { error_report_err(error); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 9558467..fd6130d 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -145,7 +145,7 @@ static void pc_init1(MachineState *machine) object_property_add_child(qdev_get_machine(), "icc-bridge", OBJECT(icc_bridge), NULL); -pc_cpus_init(machine->cpu_model, icc_bridge); +pc_cpus_init(pcms, icc_bridge); if (kvm_enabled() && kvmclock_enabled) { kvmclock_create(); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index c07d65b..4f76535 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -136,7 +136,7 @@ static void pc_q35_init(MachineState *machine) object_property_add_child(qdev_get_machine(), "icc-bridge", OBJECT(icc_bridge), NULL); -pc_cpus_init(machine->cpu_model, icc_bridge); +pc_cpus_init(pcms, icc_bridge); pc_acpi_init("q35-acpi-dsdt.aml"); kvmclock_create(); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index d0cad87..3732ab5 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -161,7 +161,7 @@ bool pc_machine_is_smm_enabled(PCMachineState *pcms); void pc_register_ferr_irq(qemu_irq irq); void pc_acpi_smi_interrupt(void *opaque, int irq, int level); -void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge); +void pc_cpus_init(PCMachineState *pcms, DeviceState *icc_bridge); void pc_hot_add_cpu(const int64_t id, Error **errp); void pc_acpi_init(const char *default_dsdt); -- 1.9.3
[Qemu-devel] [PATCH v10 0/4] remove icc bus/bridge
ICC Bus was used for providing a hotpluggable bus for APIC and CPU, but now we use HotplugHandler to make hotplug. So ICC Bus is unnecessary. This code has passed the new pc-cpu-test. And I have tested with kvm along with kernel_irqchip=on/off, it works fine. This patch series is based on the latest master and '[PATCH v3] i386: keep cpu_model field in MachineState uptodate'. https://lists.nongnu.org/archive/html/qemu-devel/2015-08/msg03375.html which has been reviewed but not been merged. v10: -improve commit messages in patch 1 and 2 -make the check of cpu->cpu_as_root simplier v9: -use a callback to correct reset sequence for x86 -update apic mmio mapping v8: -add a wrapper to specify reset order v7: -update to register reset handler for main_system_bus when created -register reset handler for apic after all devices are initialized Chen Fan (2): apic: map APIC's MMIO region at each CPU's address space cpu/apic: drop icc bus/bridge Zhu Guihua (2): x86: use new method to correct reset sequence icc_bus: drop the unused files default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - hw/i386/pc.c | 48 --- hw/i386/pc_piix.c | 9 +-- hw/i386/pc_q35.c | 9 +-- hw/intc/apic_common.c | 11 +--- include/hw/cpu/icc_bus.h | 82 -- include/hw/i386/apic_internal.h| 7 ++- include/hw/i386/pc.h | 2 +- target-i386/cpu.c | 25 +--- 12 files changed, 52 insertions(+), 262 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h -- 1.9.3
[Qemu-devel] [PATCH v10 2/4] x86: use new method to correct reset sequence
Something must be occur during reset of the X86 platform in a specific order. For example, some devices (such as hpet, rtc) reset will send irq to apic, this will update the apic register. In order to ensure the apic register could be set to default values, apic reset must be after those devices reset. This patch uses the new QEMUMachine reset method to solve the above problem, ensuring the various reset happen in the correct order. Signed-off-by: Zhu Guihua --- hw/i386/pc.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index e15971c..875ada8 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1928,6 +1928,27 @@ static void pc_machine_initfn(Object *obj) NULL, &error_abort); } +static void pc_machine_reset(void) +{ +CPUState *cs; +X86CPU *cpu; + +qemu_devices_reset(); + +/* When some devices (such as hpet, rtc) do their reset, they will + * send irq to APIC. This will modify the value of the APIC register. + * In order to ensure the APIC register can be set to default value, + * APIC reset must be after those devices reset. + */ +CPU_FOREACH(cs) { +cpu = X86_CPU(cs); + +if (cpu->apic_state) { +device_reset(cpu->apic_state); +} +} +} + static unsigned pc_cpu_index_to_socket_id(unsigned cpu_index) { unsigned pkg_id, core_id, smt_id; @@ -1948,6 +1969,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) mc->default_boot_order = "cad"; mc->hot_add_cpu = pc_hot_add_cpu; mc->max_cpus = 255; +mc->reset = pc_machine_reset; hc->plug = pc_machine_device_plug_cb; hc->unplug_request = pc_machine_device_unplug_request_cb; hc->unplug = pc_machine_device_unplug_cb; -- 1.9.3
[Qemu-devel] [PATCH v10 3/4] cpu/apic: drop icc bus/bridge
From: Chen Fan After CPU hotplug has been converted to BUS-less hot-plug infrastructure, the only function ICC bus performs is to propagate reset to LAPICs. However LAPIC could be reset by registering its reset handler after all device are initialized. Do so and drop ~200LOC of not needed anymore ICCBus related code. Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- hw/i386/pc.c| 19 --- hw/i386/pc_piix.c | 9 + hw/i386/pc_q35.c| 9 + hw/intc/apic_common.c | 5 ++--- include/hw/i386/apic_internal.h | 7 --- include/hw/i386/pc.h| 2 +- target-i386/cpu.c | 9 + 7 files changed, 14 insertions(+), 46 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 875ada8..3f89e6c 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -59,7 +59,6 @@ #include "qemu/error-report.h" #include "hw/acpi/acpi.h" #include "hw/acpi/cpu_hotplug.h" -#include "hw/cpu/icc_bus.h" #include "hw/boards.h" #include "hw/pci/pci_host.h" #include "acpi-build.h" @@ -1052,23 +1051,16 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level) } static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id, - DeviceState *icc_bridge, Error **errp) + Error **errp) { X86CPU *cpu = NULL; Error *local_err = NULL; -if (icc_bridge == NULL) { -error_setg(&local_err, "Invalid icc-bridge value"); -goto out; -} - cpu = cpu_x86_create(cpu_model, &local_err); if (local_err != NULL) { goto out; } -qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc")); - object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err); object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); @@ -1083,7 +1075,6 @@ out: void pc_hot_add_cpu(const int64_t id, Error **errp) { -DeviceState *icc_bridge; MachineState *machine = MACHINE(qdev_get_machine()); X86CPU *cpu; int64_t apic_id = x86_cpu_apic_id_from_index(id); @@ -1113,9 +1104,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) return; } -icc_bridge = DEVICE(object_resolve_path_type("icc-bridge", - TYPE_ICC_BRIDGE, NULL)); -cpu = pc_new_cpu(machine->cpu_model, apic_id, icc_bridge, &local_err); +cpu = pc_new_cpu(machine->cpu_model, apic_id, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -1123,7 +1112,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) object_unref(OBJECT(cpu)); } -void pc_cpus_init(PCMachineState *pcms, DeviceState *icc_bridge) +void pc_cpus_init(PCMachineState *pcms) { int i; X86CPU *cpu = NULL; @@ -1149,7 +1138,7 @@ void pc_cpus_init(PCMachineState *pcms, DeviceState *icc_bridge) for (i = 0; i < smp_cpus; i++) { cpu = pc_new_cpu(machine->cpu_model, x86_cpu_apic_id_from_index(i), - icc_bridge, &error); + &error); if (error) { error_report_err(error); exit(1); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index fd6130d..3a97826 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -39,7 +39,6 @@ #include "hw/kvm/clock.h" #include "sysemu/sysemu.h" #include "hw/sysbus.h" -#include "hw/cpu/icc_bus.h" #include "sysemu/arch_init.h" #include "sysemu/block-backend.h" #include "hw/i2c/smbus.h" @@ -96,7 +95,6 @@ static void pc_init1(MachineState *machine) MemoryRegion *ram_memory; MemoryRegion *pci_memory; MemoryRegion *rom_memory; -DeviceState *icc_bridge; PcGuestInfo *guest_info; ram_addr_t lowmem; @@ -141,11 +139,7 @@ static void pc_init1(MachineState *machine) exit(1); } -icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); -object_property_add_child(qdev_get_machine(), "icc-bridge", - OBJECT(icc_bridge), NULL); - -pc_cpus_init(pcms, icc_bridge); +pc_cpus_init(pcms); if (kvm_enabled() && kvmclock_enabled) { kvmclock_create(); @@ -223,7 +217,6 @@ static void pc_init1(MachineState *machine) if (pci_enabled) { ioapic_init_gsi(gsi_state, "i440fx"); } -qdev_init_nofail(icc_bridge); pc_register_ferr_irq(gsi[13]); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 4f76535..414cbbb 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -43,7 +43,6 @@ #include "hw/ide/pci.h" #include "hw/ide/ahci.h" #include "hw/usb.h" -#include "hw/cpu/icc_bus.h" #include "qemu/err
[Qemu-devel] [PATCH v10 1/4] apic: map APIC's MMIO region at each CPU's address space
From: Chen Fan After ICC bus/bridge have been removed, APIC MMIO area could not be mapped into sysbus MMIO any more. So replace mapping APIC at global system address space with mapping it at per-CPU address spaces. Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- hw/i386/pc.c | 7 --- hw/intc/apic_common.c | 6 -- target-i386/cpu.c | 16 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index b1c96a8..e15971c 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1157,13 +1157,6 @@ void pc_cpus_init(PCMachineState *pcms, DeviceState *icc_bridge) object_unref(OBJECT(cpu)); } -/* map APIC MMIO area if CPU has APIC */ -if (cpu && cpu->apic_state) { -/* XXX: what if the base changes? */ -sysbus_mmio_map_overlap(SYS_BUS_DEVICE(icc_bridge), 0, -APIC_DEFAULT_ADDRESS, 0x1000); -} - /* tell smbios about cpuid version and features */ smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); } diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index 0032b97..c0b32eb 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -296,7 +296,6 @@ static void apic_common_realize(DeviceState *dev, Error **errp) APICCommonClass *info; static DeviceState *vapic; static int apic_no; -static bool mmio_registered; if (apic_no >= MAX_APICS) { error_setg(errp, "%s initialization failed.", @@ -307,11 +306,6 @@ static void apic_common_realize(DeviceState *dev, Error **errp) info = APIC_COMMON_GET_CLASS(s); info->realize(dev, errp); -if (!mmio_registered) { -ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev)); -memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory); -mmio_registered = true; -} /* Note: We need at least 1M to map the VAPIC option ROM */ if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK && diff --git a/target-i386/cpu.c b/target-i386/cpu.c index cfb8aa7..171cdc0 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2745,6 +2745,7 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp) /* TODO: convert to link<> */ apic = APIC_COMMON(cpu->apic_state); apic->cpu = cpu; +apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE; } static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) @@ -2789,6 +2790,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) X86CPU *cpu = X86_CPU(dev); X86CPUClass *xcc = X86_CPU_GET_CLASS(dev); CPUX86State *env = &cpu->env; +APICCommonState *apic; Error *local_err = NULL; static bool ht_warned; @@ -2877,6 +2879,20 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) if (local_err != NULL) { goto out; } + +apic = APIC_COMMON(cpu->apic_state); +/* Map APIC MMIO area, use per-CPU address space if available (TCG + * supports it, KVM doesn't). This allows the APIC base address of + * each CPU to be moved independently. + */ +memory_region_add_subregion_overlap(cpu->cpu_as_root ? +cpu->cpu_as_root : +get_system_memory(), +apic->apicbase & +MSR_IA32_APICBASE_BASE, +&apic->io_memory, +0x1000); + cpu_reset(cs); xcc->parent_realize(dev, &local_err); -- 1.9.3
[Qemu-devel] [PATCH v10 4/4] icc_bus: drop the unused files
ICC bus impl has been droped, so all icc related files are not useful any more; delete them. Signed-off-by: Zhu Guihua --- default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - include/hw/cpu/icc_bus.h | 82 -- 5 files changed, 203 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 5eaafa1..70391ed 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -43,7 +43,6 @@ CONFIG_LPC_ICH9=y CONFIG_PCI_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y -CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_XIO3130=y diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index 28e2099..dfb8095 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -44,7 +44,6 @@ CONFIG_LPC_ICH9=y CONFIG_PCI_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y -CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_XIO3130=y diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs index 6381238..0954a18 100644 --- a/hw/cpu/Makefile.objs +++ b/hw/cpu/Makefile.objs @@ -2,5 +2,4 @@ obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o obj-$(CONFIG_REALVIEW) += realview_mpcore.o obj-$(CONFIG_A9MPCORE) += a9mpcore.o obj-$(CONFIG_A15MPCORE) += a15mpcore.o -obj-$(CONFIG_ICC_BUS) += icc_bus.o diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c deleted file mode 100644 index 6646ea2..000 --- a/hw/cpu/icc_bus.c +++ /dev/null @@ -1,118 +0,0 @@ -/* icc_bus.c - * emulate x86 ICC (Interrupt Controller Communications) bus - * - * Copyright (c) 2013 Red Hat, Inc - * - * Authors: - * Igor Mammedov - * - * 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 <http://www.gnu.org/licenses/> - */ -#include "hw/cpu/icc_bus.h" -#include "hw/sysbus.h" - -/* icc-bridge implementation */ - -static const TypeInfo icc_bus_info = { -.name = TYPE_ICC_BUS, -.parent = TYPE_BUS, -.instance_size = sizeof(ICCBus), -}; - - -/* icc-device implementation */ - -static void icc_device_realize(DeviceState *dev, Error **errp) -{ -ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(dev); - -/* convert to QOM */ -if (idc->realize) { -idc->realize(dev, errp); -} - -} - -static void icc_device_class_init(ObjectClass *oc, void *data) -{ -DeviceClass *dc = DEVICE_CLASS(oc); - -dc->realize = icc_device_realize; -dc->bus_type = TYPE_ICC_BUS; -} - -static const TypeInfo icc_device_info = { -.name = TYPE_ICC_DEVICE, -.parent = TYPE_DEVICE, -.abstract = true, -.instance_size = sizeof(ICCDevice), -.class_size = sizeof(ICCDeviceClass), -.class_init = icc_device_class_init, -}; - - -/* icc-bridge implementation */ - -typedef struct ICCBridgeState { -/*< private >*/ -SysBusDevice parent_obj; -/*< public >*/ - -ICCBus icc_bus; -MemoryRegion apic_container; -} ICCBridgeState; - -#define ICC_BRIDGE(obj) OBJECT_CHECK(ICCBridgeState, (obj), TYPE_ICC_BRIDGE) - -static void icc_bridge_init(Object *obj) -{ -ICCBridgeState *s = ICC_BRIDGE(obj); -SysBusDevice *sb = SYS_BUS_DEVICE(obj); - -qbus_create_inplace(&s->icc_bus, sizeof(s->icc_bus), TYPE_ICC_BUS, -DEVICE(s), "icc"); - -/* Do not change order of registering regions, - * APIC must be first registered region, board maps it by 0 index - */ -memory_region_init(&s->apic_container, obj, "icc-apic-container", - APIC_SPACE_SIZE); -sysbus_init_mmio(sb, &s->apic_container); -s->icc_bus.apic_address_space = &s->apic_container; -} - -static void icc_bridge_class_init(ObjectClass *oc, void *data) -{ -DeviceClass *dc = DEVICE_CLASS(oc); - -set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); -} - -static const TypeInfo icc_bridge_info = { -.name = TYPE_ICC_BRIDGE, -.parent = TYPE_SYS_BUS_DEVICE, -.instance_init = icc_bridge_init, -.instance_size = sizeof(ICCBridgeState), -.class_init = icc_bridge_class_init, -}; - - -static void icc_bus_register_types(void) -{ -
Re: [Qemu-devel] [PATCH v10 1/4] apic: map APIC's MMIO region at each CPU's address space
On 08/31/2015 09:21 PM, Igor Mammedov wrote: On Mon, 31 Aug 2015 17:47:44 +0800 Zhu Guihua wrote: From: Chen Fan After ICC bus/bridge have been removed, APIC MMIO area could not be mapped into sysbus MMIO any more. So replace mapping APIC at global system address space with mapping it at per-CPU address spaces. When ICC bus/bridge is removed, APIC MMIO will be left unmapped since it was mapped into system's address space indirectly by ICC bridge. Fix it by moving mapping into APIC code, so it would be possible to remove ICC bus/bridge code later. Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- hw/i386/pc.c | 7 --- hw/intc/apic_common.c | 6 -- target-i386/cpu.c | 16 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index b1c96a8..e15971c 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1157,13 +1157,6 @@ void pc_cpus_init(PCMachineState *pcms, DeviceState *icc_bridge) object_unref(OBJECT(cpu)); } -/* map APIC MMIO area if CPU has APIC */ -if (cpu && cpu->apic_state) { -/* XXX: what if the base changes? */ -sysbus_mmio_map_overlap(SYS_BUS_DEVICE(icc_bridge), 0, -APIC_DEFAULT_ADDRESS, 0x1000); -} - /* tell smbios about cpuid version and features */ smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); } diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index 0032b97..c0b32eb 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -296,7 +296,6 @@ static void apic_common_realize(DeviceState *dev, Error **errp) APICCommonClass *info; static DeviceState *vapic; static int apic_no; -static bool mmio_registered; if (apic_no >= MAX_APICS) { error_setg(errp, "%s initialization failed.", @@ -307,11 +306,6 @@ static void apic_common_realize(DeviceState *dev, Error **errp) info = APIC_COMMON_GET_CLASS(s); info->realize(dev, errp); -if (!mmio_registered) { -ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev)); -memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory); -mmio_registered = true; -} /* Note: We need at least 1M to map the VAPIC option ROM */ if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK && diff --git a/target-i386/cpu.c b/target-i386/cpu.c index cfb8aa7..171cdc0 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2745,6 +2745,7 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp) /* TODO: convert to link<> */ apic = APIC_COMMON(cpu->apic_state); apic->cpu = cpu; +apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE; } static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) @@ -2789,6 +2790,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) X86CPU *cpu = X86_CPU(dev); X86CPUClass *xcc = X86_CPU_GET_CLASS(dev); CPUX86State *env = &cpu->env; +APICCommonState *apic; Error *local_err = NULL; static bool ht_warned; @@ -2877,6 +2879,20 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) if (local_err != NULL) { goto out; } + +apic = APIC_COMMON(cpu->apic_state); +/* Map APIC MMIO area, use per-CPU address space if available (TCG + * supports it, KVM doesn't). This allows the APIC base address of + * each CPU to be moved independently. + */ +memory_region_add_subregion_overlap(cpu->cpu_as_root ? +cpu->cpu_as_root : +get_system_memory(), +apic->apicbase & +MSR_IA32_APICBASE_BASE, +&apic->io_memory, +0x1000); You have lost apic_mmio_map_once from previous version, as result in KVM case io_memory will be mapped many times over itself, pls fix it. I'm sorry to forget apic_mmio_map_once, so the logic must be as previous version. I will fix it. Thanks, Zhu Pls, also split per CPU AS change into a separate patch as Eduardo asked you for, with following order: 1. move region mapping into APIC in this patch 2. add per CPU AS in an additional path cpu_reset(cs); xcc->parent_realize(dev, &local_err); .
[Qemu-devel] [PATCH v11 0/5] remove icc bus/bridge
ICC Bus was used for providing a hotpluggable bus for APIC and CPU, but now we use HotplugHandler to make hotplug. So ICC Bus is unnecessary. This code has passed the new pc-cpu-test. And I have tested with kvm along with kernel_irqchip=on/off, it works fine. This patch series is based on the latest master and '[PATCH v3] i386: keep cpu_model field in MachineState uptodate' https://lists.nongnu.org/archive/html/qemu-devel/2015-08/msg03375.html which has been reviewed but not been merged. v11: -improve commit messages -split per CPU AS change into a separate patch v10: -improve commit messages in patch 1 and 2 -make the check of cpu->cpu_as_root simplier v9: -use a callback to correct reset sequence for x86 -update apic mmio mapping Chen Fan (2): apic: move APIC's MMIO region mapping into APIC cpu/apic: drop icc bus/bridge Zhu Guihua (3): apic: use per CPU AS to map APIC MMIO for TCG x86: use new method to correct reset sequence icc_bus: drop the unused files default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - hw/i386/pc.c | 46 --- hw/i386/pc_piix.c | 9 +-- hw/i386/pc_q35.c | 9 +-- hw/intc/apic_common.c | 11 +--- include/hw/cpu/icc_bus.h | 82 -- include/hw/i386/apic_internal.h| 7 ++- include/hw/i386/pc.h | 2 +- target-i386/cpu.c | 33 --- 12 files changed, 58 insertions(+), 262 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h -- 1.9.3
[Qemu-devel] [PATCH v11 1/5] apic: move APIC's MMIO region mapping into APIC
From: Chen Fan When ICC bus/bridge is removed, APIC MMIO will be left unmapped since it was mapped into system's address space indirectly by ICC bridge. Fix it by moving mapping into APIC code, so it would be possible to remove ICC bus/bridge code later. Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- hw/i386/pc.c | 7 --- hw/intc/apic_common.c | 6 -- target-i386/cpu.c | 15 +++ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index b1c96a8..e15971c 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1157,13 +1157,6 @@ void pc_cpus_init(PCMachineState *pcms, DeviceState *icc_bridge) object_unref(OBJECT(cpu)); } -/* map APIC MMIO area if CPU has APIC */ -if (cpu && cpu->apic_state) { -/* XXX: what if the base changes? */ -sysbus_mmio_map_overlap(SYS_BUS_DEVICE(icc_bridge), 0, -APIC_DEFAULT_ADDRESS, 0x1000); -} - /* tell smbios about cpuid version and features */ smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); } diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index 0032b97..c0b32eb 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -296,7 +296,6 @@ static void apic_common_realize(DeviceState *dev, Error **errp) APICCommonClass *info; static DeviceState *vapic; static int apic_no; -static bool mmio_registered; if (apic_no >= MAX_APICS) { error_setg(errp, "%s initialization failed.", @@ -307,11 +306,6 @@ static void apic_common_realize(DeviceState *dev, Error **errp) info = APIC_COMMON_GET_CLASS(s); info->realize(dev, errp); -if (!mmio_registered) { -ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev)); -memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory); -mmio_registered = true; -} /* Note: We need at least 1M to map the VAPIC option ROM */ if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK && diff --git a/target-i386/cpu.c b/target-i386/cpu.c index cfb8aa7..66b6b0d 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2745,6 +2745,7 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp) /* TODO: convert to link<> */ apic = APIC_COMMON(cpu->apic_state); apic->cpu = cpu; +apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE; } static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) @@ -2789,8 +2790,10 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) X86CPU *cpu = X86_CPU(dev); X86CPUClass *xcc = X86_CPU_GET_CLASS(dev); CPUX86State *env = &cpu->env; +APICCommonState *apic; Error *local_err = NULL; static bool ht_warned; +static bool apic_mmio_map_once; if (cpu->apic_id < 0) { error_setg(errp, "apic-id property was not initialized properly"); @@ -2877,6 +2880,18 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) if (local_err != NULL) { goto out; } + +/* Map APIC MMIO area */ +apic = APIC_COMMON(cpu->apic_state); +if (!apic_mmio_map_once) { +memory_region_add_subregion_overlap(get_system_memory(), +apic->apicbase & +MSR_IA32_APICBASE_BASE, +&apic->io_memory, +0x1000); +apic_mmio_map_once = true; +} + cpu_reset(cs); xcc->parent_realize(dev, &local_err); -- 1.9.3
[Qemu-devel] [PATCH v11 2/5] apic: use per CPU AS to map APIC MMIO for TCG
TCG supports per CPU address space, and the emulation quality is a bit better with it. So use per CPU address space to map APIC MMIO area. This allows the APIC base address of each cpu to be moved indepenedent of others. Signed-off-by: Zhu Guihua --- target-i386/cpu.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 66b6b0d..0a95162 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2881,9 +2881,18 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) goto out; } -/* Map APIC MMIO area */ +/* Map APIC MMIO area, use per-CPU address space if available (TCG + * supports it, KVM doesn't). This allows the APIC base address of + * each CPU to be moved independently. + */ apic = APIC_COMMON(cpu->apic_state); -if (!apic_mmio_map_once) { +if (tcg_enabled()) { +memory_region_add_subregion_overlap(cpu->cpu_as_root, +apic->apicbase & +MSR_IA32_APICBASE_BASE, +&apic->io_memory, +0x1000); +} else if (!apic_mmio_map_once) { memory_region_add_subregion_overlap(get_system_memory(), apic->apicbase & MSR_IA32_APICBASE_BASE, -- 1.9.3
[Qemu-devel] [PATCH v11 3/5] x86: use new method to correct reset sequence
During reset some devices (such as hpet, rtc) might send IRQ to APIC which changes APIC's state from default one it's supposed to have at machine startup time. Fix this by resetting APIC after devices have been reset to cancel any changes that qemu_devices_reset() might have done to its state. Signed-off-by: Zhu Guihua --- hw/i386/pc.c | 20 1 file changed, 20 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index e15971c..4b4a7f3 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1928,6 +1928,25 @@ static void pc_machine_initfn(Object *obj) NULL, &error_abort); } +static void pc_machine_reset(void) +{ +CPUState *cs; +X86CPU *cpu; + +qemu_devices_reset(); + +/* Reset APIC after devices have been reset to cancel + * any changes that qemu_devices_reset() might have done. + */ +CPU_FOREACH(cs) { +cpu = X86_CPU(cs); + +if (cpu->apic_state) { +device_reset(cpu->apic_state); +} +} +} + static unsigned pc_cpu_index_to_socket_id(unsigned cpu_index) { unsigned pkg_id, core_id, smt_id; @@ -1948,6 +1967,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) mc->default_boot_order = "cad"; mc->hot_add_cpu = pc_hot_add_cpu; mc->max_cpus = 255; +mc->reset = pc_machine_reset; hc->plug = pc_machine_device_plug_cb; hc->unplug_request = pc_machine_device_unplug_request_cb; hc->unplug = pc_machine_device_unplug_cb; -- 1.9.3
[Qemu-devel] [PATCH v11 4/5] cpu/apic: drop icc bus/bridge
From: Chen Fan After CPU hotplug has been converted to BUS-less hot-plug infrastructure, the only function ICC bus performs is to propagate reset to LAPICs. However LAPIC could be reset by registering its reset handler after all device are initialized. Do so and drop ~200LOC of not needed anymore ICCBus related code. Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- hw/i386/pc.c| 19 --- hw/i386/pc_piix.c | 9 + hw/i386/pc_q35.c| 9 + hw/intc/apic_common.c | 5 ++--- include/hw/i386/apic_internal.h | 7 --- include/hw/i386/pc.h| 2 +- target-i386/cpu.c | 9 + 7 files changed, 14 insertions(+), 46 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 4b4a7f3..4c1d68a 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -59,7 +59,6 @@ #include "qemu/error-report.h" #include "hw/acpi/acpi.h" #include "hw/acpi/cpu_hotplug.h" -#include "hw/cpu/icc_bus.h" #include "hw/boards.h" #include "hw/pci/pci_host.h" #include "acpi-build.h" @@ -1052,23 +1051,16 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level) } static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id, - DeviceState *icc_bridge, Error **errp) + Error **errp) { X86CPU *cpu = NULL; Error *local_err = NULL; -if (icc_bridge == NULL) { -error_setg(&local_err, "Invalid icc-bridge value"); -goto out; -} - cpu = cpu_x86_create(cpu_model, &local_err); if (local_err != NULL) { goto out; } -qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc")); - object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err); object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); @@ -1083,7 +1075,6 @@ out: void pc_hot_add_cpu(const int64_t id, Error **errp) { -DeviceState *icc_bridge; MachineState *machine = MACHINE(qdev_get_machine()); X86CPU *cpu; int64_t apic_id = x86_cpu_apic_id_from_index(id); @@ -1113,9 +1104,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) return; } -icc_bridge = DEVICE(object_resolve_path_type("icc-bridge", - TYPE_ICC_BRIDGE, NULL)); -cpu = pc_new_cpu(machine->cpu_model, apic_id, icc_bridge, &local_err); +cpu = pc_new_cpu(machine->cpu_model, apic_id, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -1123,7 +1112,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) object_unref(OBJECT(cpu)); } -void pc_cpus_init(PCMachineState *pcms, DeviceState *icc_bridge) +void pc_cpus_init(PCMachineState *pcms) { int i; X86CPU *cpu = NULL; @@ -1149,7 +1138,7 @@ void pc_cpus_init(PCMachineState *pcms, DeviceState *icc_bridge) for (i = 0; i < smp_cpus; i++) { cpu = pc_new_cpu(machine->cpu_model, x86_cpu_apic_id_from_index(i), - icc_bridge, &error); + &error); if (error) { error_report_err(error); exit(1); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index fd6130d..3a97826 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -39,7 +39,6 @@ #include "hw/kvm/clock.h" #include "sysemu/sysemu.h" #include "hw/sysbus.h" -#include "hw/cpu/icc_bus.h" #include "sysemu/arch_init.h" #include "sysemu/block-backend.h" #include "hw/i2c/smbus.h" @@ -96,7 +95,6 @@ static void pc_init1(MachineState *machine) MemoryRegion *ram_memory; MemoryRegion *pci_memory; MemoryRegion *rom_memory; -DeviceState *icc_bridge; PcGuestInfo *guest_info; ram_addr_t lowmem; @@ -141,11 +139,7 @@ static void pc_init1(MachineState *machine) exit(1); } -icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); -object_property_add_child(qdev_get_machine(), "icc-bridge", - OBJECT(icc_bridge), NULL); - -pc_cpus_init(pcms, icc_bridge); +pc_cpus_init(pcms); if (kvm_enabled() && kvmclock_enabled) { kvmclock_create(); @@ -223,7 +217,6 @@ static void pc_init1(MachineState *machine) if (pci_enabled) { ioapic_init_gsi(gsi_state, "i440fx"); } -qdev_init_nofail(icc_bridge); pc_register_ferr_irq(gsi[13]); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 4f76535..414cbbb 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -43,7 +43,6 @@ #include "hw/ide/pci.h" #include "hw/ide/ahci.h" #include "hw/usb.h" -#include "hw/cpu/icc_bus.h" #include "qemu/err
[Qemu-devel] [PATCH v11 5/5] icc_bus: drop the unused files
ICC bus impl has been droped, so all icc related files are not useful any more; delete them. Signed-off-by: Zhu Guihua --- default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - include/hw/cpu/icc_bus.h | 82 -- 5 files changed, 203 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 5eaafa1..70391ed 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -43,7 +43,6 @@ CONFIG_LPC_ICH9=y CONFIG_PCI_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y -CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_XIO3130=y diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index 28e2099..dfb8095 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -44,7 +44,6 @@ CONFIG_LPC_ICH9=y CONFIG_PCI_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y -CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_XIO3130=y diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs index 6381238..0954a18 100644 --- a/hw/cpu/Makefile.objs +++ b/hw/cpu/Makefile.objs @@ -2,5 +2,4 @@ obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o obj-$(CONFIG_REALVIEW) += realview_mpcore.o obj-$(CONFIG_A9MPCORE) += a9mpcore.o obj-$(CONFIG_A15MPCORE) += a15mpcore.o -obj-$(CONFIG_ICC_BUS) += icc_bus.o diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c deleted file mode 100644 index 6646ea2..000 --- a/hw/cpu/icc_bus.c +++ /dev/null @@ -1,118 +0,0 @@ -/* icc_bus.c - * emulate x86 ICC (Interrupt Controller Communications) bus - * - * Copyright (c) 2013 Red Hat, Inc - * - * Authors: - * Igor Mammedov - * - * 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 <http://www.gnu.org/licenses/> - */ -#include "hw/cpu/icc_bus.h" -#include "hw/sysbus.h" - -/* icc-bridge implementation */ - -static const TypeInfo icc_bus_info = { -.name = TYPE_ICC_BUS, -.parent = TYPE_BUS, -.instance_size = sizeof(ICCBus), -}; - - -/* icc-device implementation */ - -static void icc_device_realize(DeviceState *dev, Error **errp) -{ -ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(dev); - -/* convert to QOM */ -if (idc->realize) { -idc->realize(dev, errp); -} - -} - -static void icc_device_class_init(ObjectClass *oc, void *data) -{ -DeviceClass *dc = DEVICE_CLASS(oc); - -dc->realize = icc_device_realize; -dc->bus_type = TYPE_ICC_BUS; -} - -static const TypeInfo icc_device_info = { -.name = TYPE_ICC_DEVICE, -.parent = TYPE_DEVICE, -.abstract = true, -.instance_size = sizeof(ICCDevice), -.class_size = sizeof(ICCDeviceClass), -.class_init = icc_device_class_init, -}; - - -/* icc-bridge implementation */ - -typedef struct ICCBridgeState { -/*< private >*/ -SysBusDevice parent_obj; -/*< public >*/ - -ICCBus icc_bus; -MemoryRegion apic_container; -} ICCBridgeState; - -#define ICC_BRIDGE(obj) OBJECT_CHECK(ICCBridgeState, (obj), TYPE_ICC_BRIDGE) - -static void icc_bridge_init(Object *obj) -{ -ICCBridgeState *s = ICC_BRIDGE(obj); -SysBusDevice *sb = SYS_BUS_DEVICE(obj); - -qbus_create_inplace(&s->icc_bus, sizeof(s->icc_bus), TYPE_ICC_BUS, -DEVICE(s), "icc"); - -/* Do not change order of registering regions, - * APIC must be first registered region, board maps it by 0 index - */ -memory_region_init(&s->apic_container, obj, "icc-apic-container", - APIC_SPACE_SIZE); -sysbus_init_mmio(sb, &s->apic_container); -s->icc_bus.apic_address_space = &s->apic_container; -} - -static void icc_bridge_class_init(ObjectClass *oc, void *data) -{ -DeviceClass *dc = DEVICE_CLASS(oc); - -set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); -} - -static const TypeInfo icc_bridge_info = { -.name = TYPE_ICC_BRIDGE, -.parent = TYPE_SYS_BUS_DEVICE, -.instance_init = icc_bridge_init, -.instance_size = sizeof(ICCBridgeState), -.class_init = icc_bridge_class_init, -}; - - -static void icc_bus_register_types(void) -{ -
Re: [Qemu-devel] [PATCH v3] i386: keep cpu_model field in MachineState uptodate
This patch has been reviewed. Could anyone help merge it? Thanks, Zhu On 08/28/2015 02:28 AM, Eduardo Habkost wrote: On Thu, Aug 27, 2015 at 05:27:05PM +0800, Zhu Guihua wrote: Update cpu_model in MachineState for i386, so that the field can be used for cpu hotplug, instead of using a static variable. Signed-off-by: Zhu Guihua Reviewed-by: Eduardo Habkost
Re: [Qemu-devel] [PATCH v3 0/7] cpu: add i386 cpu hot remove support
On 07/09/2015 10:25 PM, Eduardo Otubo wrote: On Fri, Jun 26, 2015 at 11=37=43AM +0800, Zhu Guihua wrote: Hi, On 06/24/2015 09:28 PM, Eduardo Otubo wrote: Hello Zhu, Are you still working on this feature? Could you provide a rebased version of this series? Sorry for late reply. Yes, we are still working on this feature. I have updated my github, you can get the rebased version from it. https://github.com/zhuguihua/qemu.git cpu-hotplug Hi, thanks a lot for rebasing it. I didn't have time to test it, though. I appologise. Regarding your branch, your plan is to stick with device_del and object_del interface? Yeah, we will only stick with device_del interface. There is no need to use object_del interface for cpu hot remove. Thanks, Zhu
Re: [Qemu-devel] [PATCH v9 0/4] remove icc bus/bridge
ping... On 07/03/2015 05:38 PM, Zhu Guihua wrote: ICC Bus was used for providing a hotpluggable bus for APIC and CPU, but now we use HotplugHandler to make hotplug. So ICC Bus is unnecessary. This code has passed the new pc-cpu-test. And I have tested with kvm along with kernel_irqchip=on/off, it works fine. This patch series is based on the latest master. v9: -use a callback to correct reset sequence for x86 -update apic mmio mapping v8: -add a wrapper to specify reset order v7: -update to register reset handler for main_system_bus when created -register reset handler for apic after all devices are initialized Chen Fan (2): apic: map APIC's MMIO region at each CPU's address space cpu/apic: drop icc bus/bridge Zhu Guihua (2): x86: use new method to correct reset sequence icc_bus: drop the unused files default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - hw/i386/pc.c | 43 +++--- hw/i386/pc_piix.c | 9 +-- hw/i386/pc_q35.c | 9 +-- hw/intc/apic_common.c | 11 +--- include/hw/cpu/icc_bus.h | 82 -- include/hw/i386/apic_internal.h| 7 ++- include/hw/i386/pc.h | 2 +- target-i386/cpu.c | 30 +++--- 12 files changed, 52 insertions(+), 262 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h
Re: [Qemu-devel] [PATCH v9 0/4] remove icc bus/bridge
On 07/16/2015 05:52 PM, Igor Mammedov wrote: On Thu, 16 Jul 2015 10:45:41 +0800 Zhu Guihua wrote: ping... I'll look at it once 2.4 is released. Got it, thanks. By the way, do you know what state of qemu socket topology ? Regards, Zhu On 07/03/2015 05:38 PM, Zhu Guihua wrote: ICC Bus was used for providing a hotpluggable bus for APIC and CPU, but now we use HotplugHandler to make hotplug. So ICC Bus is unnecessary. This code has passed the new pc-cpu-test. And I have tested with kvm along with kernel_irqchip=on/off, it works fine. This patch series is based on the latest master. v9: -use a callback to correct reset sequence for x86 -update apic mmio mapping v8: -add a wrapper to specify reset order v7: -update to register reset handler for main_system_bus when created -register reset handler for apic after all devices are initialized Chen Fan (2): apic: map APIC's MMIO region at each CPU's address space cpu/apic: drop icc bus/bridge Zhu Guihua (2): x86: use new method to correct reset sequence icc_bus: drop the unused files default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - hw/i386/pc.c | 43 +++--- hw/i386/pc_piix.c | 9 +-- hw/i386/pc_q35.c | 9 +-- hw/intc/apic_common.c | 11 +--- include/hw/cpu/icc_bus.h | 82 -- include/hw/i386/apic_internal.h| 7 ++- include/hw/i386/pc.h | 2 +- target-i386/cpu.c | 30 +++--- 12 files changed, 52 insertions(+), 262 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h .
Re: [Qemu-devel] [PATCH v8 0/4] remove icc bus/bridge
ping... On 06/08/2015 06:35 PM, Zhu Guihua wrote: ICC Bus was used for providing a hotpluggable bus for APIC and CPU, but now we use HotplugHandler to make hotplug. So ICC Bus is unnecessary. This code has passed the new pc-cpu-test. And I have tested with kvm along with kernel_irqchip=on/off, it works fine. This patch series is based on Eduardo's x86 tree. https://github.com/ehabkost/qemu.git v8: -add a wrapper to specify reset order v7: -update to register reset handler for main_system_bus when created -register reset handler for apic after all devices are initialized v6: -reword commit message -drop NULL check for APIC device -use C cast instead of QOM cast v5: -convert DEVICE() casts to C casts -use a local variable instead of doing the cast inline twice -drop to set cpu's parent bus -rename patch 3's subject -fix a bug about setting cpu's apic base v4: -add wrapper to get root memory region from address space -set cpu apic base's default value in x86_cpu_apic_create() -drop NULL check for cpu apic_state -put drop of the unused files about icc_bus into a seprate patch -put DEVICE() casts into a seprate patch v3: -replace init apic by object_new() -add reset apic at the time of CPU reset Chen Fan (2): apic: map APIC's MMIO region at each CPU's address space cpu/apic: drop icc bus/bridge Zhu Guihua (2): hw: add a wrapper for registering reset handler icc_bus: drop the unused files default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - exec.c | 5 ++ hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - hw/i386/pc.c | 31 +++--- hw/i386/pc_piix.c | 9 +-- hw/i386/pc_q35.c | 9 +-- hw/intc/apic_common.c | 19 +++--- include/exec/memory.h | 5 ++ include/hw/cpu/icc_bus.h | 82 -- include/hw/hw.h| 4 ++ include/hw/i386/apic_internal.h| 7 ++- include/hw/i386/pc.h | 2 +- target-i386/cpu.c | 25 +--- target-i386/cpu.h | 4 ++ vl.c | 18 +- 17 files changed, 78 insertions(+), 263 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h
[Qemu-devel] [RESEND PATCH v8 2/4] hw: add a wrapper for registering reset handler
Add a wrapper to specify reset order when registering reset handler, instead of non-obvious initiazation code ordering. Signed-off-by: Zhu Guihua --- include/hw/hw.h | 4 vl.c| 18 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/include/hw/hw.h b/include/hw/hw.h index c78adae..d9375e7 100644 --- a/include/hw/hw.h +++ b/include/hw/hw.h @@ -37,7 +37,11 @@ #endif typedef void QEMUResetHandler(void *opaque); +typedef uint64_t QEMUResetOrder; +#define default_reset_order 0x0 +void qemu_register_reset_common(QEMUResetHandler *func, void *opaque, +QEMUResetOrder reset_order); void qemu_register_reset(QEMUResetHandler *func, void *opaque); void qemu_unregister_reset(QEMUResetHandler *func, void *opaque); diff --git a/vl.c b/vl.c index 69ad90c..b205a9b 100644 --- a/vl.c +++ b/vl.c @@ -1589,6 +1589,7 @@ typedef struct QEMUResetEntry { QTAILQ_ENTRY(QEMUResetEntry) entry; QEMUResetHandler *func; void *opaque; +QEMUResetOrder reset_order; } QEMUResetEntry; static QTAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers = @@ -1672,15 +1673,30 @@ static int qemu_debug_requested(void) return r; } -void qemu_register_reset(QEMUResetHandler *func, void *opaque) +void qemu_register_reset_common(QEMUResetHandler *func, void *opaque, +QEMUResetOrder reset_order) { +QEMUResetEntry *item; QEMUResetEntry *re = g_malloc0(sizeof(QEMUResetEntry)); re->func = func; re->opaque = opaque; +re->reset_order = reset_order; + +QTAILQ_FOREACH(item, &reset_handlers, entry) { +if (re->reset_order >= item->reset_order) +continue; +QTAILQ_INSERT_BEFORE(item, re, entry); +return; +} QTAILQ_INSERT_TAIL(&reset_handlers, re, entry); } +void qemu_register_reset(QEMUResetHandler *func, void *opaque) +{ +qemu_register_reset_common(func, opaque, default_reset_order); +} + void qemu_unregister_reset(QEMUResetHandler *func, void *opaque) { QEMUResetEntry *re; -- 1.9.3
[Qemu-devel] [RESEND PATCH v8 1/4] apic: map APIC's MMIO region at each CPU's address space
From: Chen Fan Replace mapping APIC at global system address space with mapping it at per-CPU address spaces. Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- exec.c| 5 + hw/i386/pc.c | 7 --- hw/intc/apic_common.c | 14 -- include/exec/memory.h | 5 + target-i386/cpu.c | 2 ++ 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/exec.c b/exec.c index f7883d2..1cd2e74 100644 --- a/exec.c +++ b/exec.c @@ -2710,6 +2710,11 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, cpu_notify_map_clients(); } +MemoryRegion *address_space_root_memory_region(AddressSpace *as) +{ +return as->root; +} + void *cpu_physical_memory_map(hwaddr addr, hwaddr *plen, int is_write) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 7072930..9f16128 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1076,13 +1076,6 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) object_unref(OBJECT(cpu)); } -/* map APIC MMIO area if CPU has APIC */ -if (cpu && cpu->apic_state) { -/* XXX: what if the base changes? */ -sysbus_mmio_map_overlap(SYS_BUS_DEVICE(icc_bridge), 0, -APIC_DEFAULT_ADDRESS, 0x1000); -} - /* tell smbios about cpuid version and features */ smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); } diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index 0032b97..cf105f5 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -296,7 +296,8 @@ static void apic_common_realize(DeviceState *dev, Error **errp) APICCommonClass *info; static DeviceState *vapic; static int apic_no; -static bool mmio_registered; +CPUState *cpu = CPU(s->cpu); +MemoryRegion *root; if (apic_no >= MAX_APICS) { error_setg(errp, "%s initialization failed.", @@ -307,11 +308,12 @@ static void apic_common_realize(DeviceState *dev, Error **errp) info = APIC_COMMON_GET_CLASS(s); info->realize(dev, errp); -if (!mmio_registered) { -ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev)); -memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory); -mmio_registered = true; -} + +root = address_space_root_memory_region(cpu->as); +memory_region_add_subregion_overlap(root, +s->apicbase & MSR_IA32_APICBASE_BASE, +&s->io_memory, +0x1000); /* Note: We need at least 1M to map the VAPIC option ROM */ if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK && diff --git a/include/exec/memory.h b/include/exec/memory.h index 8ae004e..811f027 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1308,6 +1308,11 @@ void *address_space_map(AddressSpace *as, hwaddr addr, void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, int is_write, hwaddr access_len); +/* address_space_root_memory_region: get root memory region + * + * @as: #AddressSpace to be accessed + */ +MemoryRegion *address_space_root_memory_region(AddressSpace *as); #endif diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 36b07f9..1fb88f6 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2741,6 +2741,8 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp) /* TODO: convert to link<> */ apic = APIC_COMMON(cpu->apic_state); apic->cpu = cpu; +cpu_set_apic_base(cpu->apic_state, + APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE); } static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) -- 1.9.3
[Qemu-devel] [RESEND PATCH v8 0/4] remove icc bus/bridge
ICC Bus was used for providing a hotpluggable bus for APIC and CPU, but now we use HotplugHandler to make hotplug. So ICC Bus is unnecessary. This code has passed the new pc-cpu-test. And I have tested with kvm along with kernel_irqchip=on/off, it works fine. This patch series is based on the latest master. v8: -add a wrapper to specify reset order v7: -update to register reset handler for main_system_bus when created -register reset handler for apic after all devices are initialized v6: -reword commit message -drop NULL check for APIC device -use C cast instead of QOM cast v5: -convert DEVICE() casts to C casts -use a local variable instead of doing the cast inline twice -drop to set cpu's parent bus -rename patch 3's subject -fix a bug about setting cpu's apic base v4: -add wrapper to get root memory region from address space -set cpu apic base's default value in x86_cpu_apic_create() -drop NULL check for cpu apic_state -put drop of the unused files about icc_bus into a seprate patch -put DEVICE() casts into a seprate patch v3: -replace init apic by object_new() -add reset apic at the time of CPU reset Chen Fan (2): apic: map APIC's MMIO region at each CPU's address space cpu/apic: drop icc bus/bridge Zhu Guihua (2): hw: add a wrapper for registering reset handler icc_bus: drop the unused files default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - exec.c | 5 ++ hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - hw/i386/pc.c | 31 +++--- hw/i386/pc_piix.c | 9 +-- hw/i386/pc_q35.c | 9 +-- hw/intc/apic_common.c | 19 +++--- include/exec/memory.h | 5 ++ include/hw/cpu/icc_bus.h | 82 -- include/hw/hw.h| 4 ++ include/hw/i386/apic_internal.h| 7 ++- include/hw/i386/pc.h | 2 +- target-i386/cpu.c | 25 +--- target-i386/cpu.h | 1 + vl.c | 18 +- 17 files changed, 75 insertions(+), 263 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h -- 1.9.3
[Qemu-devel] [RESEND PATCH v8 3/4] cpu/apic: drop icc bus/bridge
From: Chen Fan After CPU hotplug has been converted to BUS-less hot-plug infrastructure, the only function ICC bus performs is to propagate reset to LAPICs. However LAPIC could be reset by registering its reset handler after all device are initialized. Do so and drop ~200LOC of not needed anymore ICCBus related code. Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- hw/i386/pc.c| 24 +--- hw/i386/pc_piix.c | 9 + hw/i386/pc_q35.c| 9 + hw/intc/apic_common.c | 5 ++--- include/hw/i386/apic_internal.h | 7 --- include/hw/i386/pc.h| 2 +- target-i386/cpu.c | 23 +++ target-i386/cpu.h | 1 + 8 files changed, 34 insertions(+), 46 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 9f16128..c547d74 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -59,7 +59,6 @@ #include "qemu/error-report.h" #include "hw/acpi/acpi.h" #include "hw/acpi/cpu_hotplug.h" -#include "hw/cpu/icc_bus.h" #include "hw/boards.h" #include "hw/pci/pci_host.h" #include "acpi-build.h" @@ -969,27 +968,25 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level) } } +#define x86_cpu_apic_reset_order 0x1 + static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id, - DeviceState *icc_bridge, Error **errp) + Error **errp) { X86CPU *cpu = NULL; Error *local_err = NULL; -if (icc_bridge == NULL) { -error_setg(&local_err, "Invalid icc-bridge value"); -goto out; -} - cpu = cpu_x86_create(cpu_model, &local_err); if (local_err != NULL) { goto out; } -qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc")); - object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err); object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); +qemu_register_reset_common(x86_cpu_apic_reset, cpu, + x86_cpu_apic_reset_order); + out: if (local_err) { error_propagate(errp, local_err); @@ -1003,7 +1000,6 @@ static const char *current_cpu_model; void pc_hot_add_cpu(const int64_t id, Error **errp) { -DeviceState *icc_bridge; X86CPU *cpu; int64_t apic_id = x86_cpu_apic_id_from_index(id); Error *local_err = NULL; @@ -1032,9 +1028,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) return; } -icc_bridge = DEVICE(object_resolve_path_type("icc-bridge", - TYPE_ICC_BRIDGE, NULL)); -cpu = pc_new_cpu(current_cpu_model, apic_id, icc_bridge, &local_err); +cpu = pc_new_cpu(current_cpu_model, apic_id, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -1042,7 +1036,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) object_unref(OBJECT(cpu)); } -void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) +void pc_cpus_init(const char *cpu_model) { int i; X86CPU *cpu = NULL; @@ -1068,7 +1062,7 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) for (i = 0; i < smp_cpus; i++) { cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i), - icc_bridge, &error); + &error); if (error) { error_report_err(error); exit(1); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index e142f75..7e9a185 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -39,7 +39,6 @@ #include "hw/kvm/clock.h" #include "sysemu/sysemu.h" #include "hw/sysbus.h" -#include "hw/cpu/icc_bus.h" #include "sysemu/arch_init.h" #include "sysemu/block-backend.h" #include "hw/i2c/smbus.h" @@ -98,7 +97,6 @@ static void pc_init1(MachineState *machine) MemoryRegion *ram_memory; MemoryRegion *pci_memory; MemoryRegion *rom_memory; -DeviceState *icc_bridge; PcGuestInfo *guest_info; ram_addr_t lowmem; @@ -142,11 +140,7 @@ static void pc_init1(MachineState *machine) exit(1); } -icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); -object_property_add_child(qdev_get_machine(), "icc-bridge", - OBJECT(icc_bridge), NULL); - -pc_cpus_init(machine->cpu_model, icc_bridge); +pc_cpus_init(machine->cpu_model); if (kvm_enabled() && kvmclock_enabled) { kvmclock_create(); @@ -229,7 +223,6 @@ static void pc_init1(MachineState *machine) if (pci_enabled) { ioapic_init_gsi(gsi_state, "i440fx"); } -qdev_init_nofail(icc_bridge); pc_register_ferr_irq(gsi[13
[Qemu-devel] [RESEND PATCH v8 4/4] icc_bus: drop the unused files
ICC bus impl has been droped, so all icc related files are not useful any more; delete them. Signed-off-by: Zhu Guihua --- default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - include/hw/cpu/icc_bus.h | 82 -- 5 files changed, 203 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 91d602c..0759f22 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -42,7 +42,6 @@ CONFIG_LPC_ICH9=y CONFIG_PCI_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y -CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_XIO3130=y diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index 62575eb..08aac8c 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -43,7 +43,6 @@ CONFIG_LPC_ICH9=y CONFIG_PCI_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y -CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_XIO3130=y diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs index 6381238..0954a18 100644 --- a/hw/cpu/Makefile.objs +++ b/hw/cpu/Makefile.objs @@ -2,5 +2,4 @@ obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o obj-$(CONFIG_REALVIEW) += realview_mpcore.o obj-$(CONFIG_A9MPCORE) += a9mpcore.o obj-$(CONFIG_A15MPCORE) += a15mpcore.o -obj-$(CONFIG_ICC_BUS) += icc_bus.o diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c deleted file mode 100644 index 6646ea2..000 --- a/hw/cpu/icc_bus.c +++ /dev/null @@ -1,118 +0,0 @@ -/* icc_bus.c - * emulate x86 ICC (Interrupt Controller Communications) bus - * - * Copyright (c) 2013 Red Hat, Inc - * - * Authors: - * Igor Mammedov - * - * 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 <http://www.gnu.org/licenses/> - */ -#include "hw/cpu/icc_bus.h" -#include "hw/sysbus.h" - -/* icc-bridge implementation */ - -static const TypeInfo icc_bus_info = { -.name = TYPE_ICC_BUS, -.parent = TYPE_BUS, -.instance_size = sizeof(ICCBus), -}; - - -/* icc-device implementation */ - -static void icc_device_realize(DeviceState *dev, Error **errp) -{ -ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(dev); - -/* convert to QOM */ -if (idc->realize) { -idc->realize(dev, errp); -} - -} - -static void icc_device_class_init(ObjectClass *oc, void *data) -{ -DeviceClass *dc = DEVICE_CLASS(oc); - -dc->realize = icc_device_realize; -dc->bus_type = TYPE_ICC_BUS; -} - -static const TypeInfo icc_device_info = { -.name = TYPE_ICC_DEVICE, -.parent = TYPE_DEVICE, -.abstract = true, -.instance_size = sizeof(ICCDevice), -.class_size = sizeof(ICCDeviceClass), -.class_init = icc_device_class_init, -}; - - -/* icc-bridge implementation */ - -typedef struct ICCBridgeState { -/*< private >*/ -SysBusDevice parent_obj; -/*< public >*/ - -ICCBus icc_bus; -MemoryRegion apic_container; -} ICCBridgeState; - -#define ICC_BRIDGE(obj) OBJECT_CHECK(ICCBridgeState, (obj), TYPE_ICC_BRIDGE) - -static void icc_bridge_init(Object *obj) -{ -ICCBridgeState *s = ICC_BRIDGE(obj); -SysBusDevice *sb = SYS_BUS_DEVICE(obj); - -qbus_create_inplace(&s->icc_bus, sizeof(s->icc_bus), TYPE_ICC_BUS, -DEVICE(s), "icc"); - -/* Do not change order of registering regions, - * APIC must be first registered region, board maps it by 0 index - */ -memory_region_init(&s->apic_container, obj, "icc-apic-container", - APIC_SPACE_SIZE); -sysbus_init_mmio(sb, &s->apic_container); -s->icc_bus.apic_address_space = &s->apic_container; -} - -static void icc_bridge_class_init(ObjectClass *oc, void *data) -{ -DeviceClass *dc = DEVICE_CLASS(oc); - -set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); -} - -static const TypeInfo icc_bridge_info = { -.name = TYPE_ICC_BRIDGE, -.parent = TYPE_SYS_BUS_DEVICE, -.instance_init = icc_bridge_init, -.instance_size = sizeof(ICCBridgeState), -.class_init = icc_bridge_class_init, -}; - - -static void icc_bus_register_types(void) -{ -
Re: [Qemu-devel] [PATCH v3 0/7] cpu: add i386 cpu hot remove support
Hi, On 06/24/2015 09:28 PM, Eduardo Otubo wrote: Hello Zhu, Are you still working on this feature? Could you provide a rebased version of this series? Sorry for late reply. Yes, we are still working on this feature. I have updated my github, you can get the rebased version from it. https://github.com/zhuguihua/qemu.git cpu-hotplug Thanks, Zhu Regards, On Fri, Feb 13, 2015 at 06=40=15PM +0800, Zhu Guihua wrote: This series is based on chen fan's previous i386 cpu hot remove patchset: https://lists.nongnu.org/archive/html/qemu-devel/2013-12/msg04266.html Via implementing ACPI standard methods _EJ0 in ACPI table, after Guest OS remove one vCPU online, the fireware will store removed bitmap to QEMU, then QEMU could know to notify the assigned vCPU of exiting. Meanwhile, intruduce the QOM command 'device_del' to remove vCPU from QEMU itself. The whole work is based on the new hot plug/unplug framework, ,the unplug request callback does the pre-check and send the request, unplug callback does the removal handling. This series depends on tangchen's common hot plug/unplug enhance patchset. [PATCH v2 0/5] Common unplug and unplug request cb for memory and CPU hot-unplug https://lists.nongnu.org/archive/html/qemu-devel/2015-01/msg03929.html The is the second half of the previous series: [RFC V2 00/10] cpu: add device_add foo-x86_64-cpu and i386 cpu hot remove support https://lists.nongnu.org/archive/html/qemu-devel/2014-08/msg04779.html If you want to test the series, you need to apply the 'device_add foo-x86_64-cpu' patchset first: [PATCH v4 00/10] cpu: add device_add foo-x86_64-cpu support https://lists.nongnu.org/archive/html/qemu-devel/2015-02/msg02584.html --- Changelog since v2: -drop ICC bus impl -fix delete cpu exceed 32 issue -fix bug about deleting the last cpu Changelog since v1: -rebase on the latest version. -delete patch i386/cpu: add instance finalize callback, and put it into patchset [PATCH v3 0/6] cpu: add device_add foo-x86_64-cpu support. Changelog since RFC: -splited the i386 cpu hot remove into single thread. -replaced apic_no with apic_id, so does the related stuff to make it work with arbitrary CPU hotadd. -add the icc_device_unrealize callback to handle apic unrealize. -rework on the new hot plug/unplug platform. --- Chen Fan (2): x86: add x86_cpu_unrealizefn() for cpu apic remove cpu hotplug: implement function cpu_status_write() for vcpu ejection Gu Zheng (3): acpi/cpu: add cpu hot unplug request callback function acpi, pc: add cpu hot unplug callback support cpus: reclaim allocated vCPU objects Zhu Guihua (2): acpi, pc: add cpu hot unplug request callback support acpi/cpu: add cpu hot unplug callback function cpus.c| 44 hw/acpi/cpu_hotplug.c | 87 --- hw/acpi/ich9.c| 17 ++-- hw/acpi/piix4.c | 12 +- hw/core/qdev.c| 2 +- hw/i386/acpi-dsdt-cpu-hotplug.dsl | 16 ++- hw/i386/kvm/apic.c| 5 +++ hw/i386/pc.c | 68 -- hw/intc/apic.c| 9 hw/intc/apic_common.c | 21 ++ include/hw/acpi/cpu_hotplug.h | 8 include/hw/i386/apic_internal.h | 1 + include/hw/qdev-core.h| 1 + include/qom/cpu.h | 9 include/sysemu/kvm.h | 1 + kvm-all.c | 57 - target-i386/cpu.c | 46 + 17 files changed, 377 insertions(+), 27 deletions(-) -- 1.9.3
Re: [Qemu-devel] [RESEND PATCH v8 2/4] hw: add a wrapper for registering reset handler
On 06/26/2015 01:28 AM, Andreas Färber wrote: Am 25.06.2015 um 19:00 schrieb Paolo Bonzini: On 25/06/2015 04:17, Zhu Guihua wrote: Add a wrapper to specify reset order when registering reset handler, instead of non-obvious initiazation code ordering. Signed-off-by: Zhu Guihua I'm sorry, this is not really acceptable. The initialization code ordering is good because it should be okay to run reset handlers in the same order as code is run. If there are dependencies between reset handlers, a random integer is not a maintainable way to maintain them. Instead, you should have a single reset handler that calls the reset handlers in the right order; for example a qdev bus such as icc_bus always resets children before parents. Are you sure that you want to remove the icc_bus?... What are you gaining exactly by doing so? >From my view we would be gaining by making the APIC an integral part (child<>) of the CPU in a follow-up step (there's a TODO to make things link<>s). But either way the CPU's existing reset handler should be able to handle CPU/APIC interdependencies just fine, somehow. Which is what Eduardo said on v6 and v7. (Another alternative he raised was a machine init notifier, but I see no code for that after its mention on v7?) According to Eduardo's suggestions on v7, the simpler way is to add a ordering parameter to qemu_register_reset(), so that we can ensure the order of apic reset handler(apic reset must be after the other devices' reset on x86). This way will not influence the initialization code ordering expect apic reset. Can we take this way? or someone have a better one? Thanks, Zhu Cheers, Andreas
Re: [Qemu-devel] [RESEND PATCH v8 2/4] hw: add a wrapper for registering reset handler
On 06/30/2015 05:21 PM, Igor Mammedov wrote: On Tue, 30 Jun 2015 14:31:50 +0800 Zhu Guihua wrote: On 06/26/2015 01:28 AM, Andreas Färber wrote: Am 25.06.2015 um 19:00 schrieb Paolo Bonzini: On 25/06/2015 04:17, Zhu Guihua wrote: Add a wrapper to specify reset order when registering reset handler, instead of non-obvious initiazation code ordering. Signed-off-by: Zhu Guihua I'm sorry, this is not really acceptable. The initialization code ordering is good because it should be okay to run reset handlers in the same order as code is run. If there are dependencies between reset handlers, a random integer is not a maintainable way to maintain them. Instead, you should have a single reset handler that calls the reset handlers in the right order; for example a qdev bus such as icc_bus always resets children before parents. Are you sure that you want to remove the icc_bus?... What are you gaining exactly by doing so? >From my view we would be gaining by making the APIC an integral part (child<>) of the CPU in a follow-up step (there's a TODO to make things link<>s). But either way the CPU's existing reset handler should be able to handle CPU/APIC interdependencies just fine, somehow. Which is what Eduardo said on v6 and v7. (Another alternative he raised was a machine init notifier, but I see no code for that after its mention on v7?) According to Eduardo's suggestions on v7, the simpler way is to add a ordering parameter to qemu_register_reset(), so that we can ensure the order of apic reset handler(apic reset must be after the other devices' reset on x86). This way will not influence the initialization code ordering expect apic reset. Can we take this way? or someone have a better one? could you explain once more why apic->reset() doesn't work when it's called from cpu->reset(), please? Originally, there are some devices (such as hpet, rtc) reset before apic reset. When these devices reset, they would send irq to apic. As apic reset is behind these devices reset, the apic register could be set to default values. If apic->reset() is called from cpu->reset(), cpu reset is before some devices reset, it lead to apic reset is before them too, so the apic register could not be set to default values. But before guest boots up, the irq request should be rejected. So when linux enables local apic, it would find there are irr requests, then it will cause the following warn_on. [1.073487] [ cut here ] [1.074019] WARNING: at arch/x86/kernel/apic/apic.c:1401 setup_local_APIC+0x268/0x320() [1.075011] Modules linked in: [1.076474] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.10.0.sort+ #100 [1.077012] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.1-0-g4adadbd-20150316_085822-nilsson.home.kraxel.org 04/01/2014 [1.078011] d1b49dbb 88007c787da8 81649983 [1.082011] 88007c787de0 810b3241 0001 [1.085012] 00f0 88007c787df0 [1.088012] Call Trace: [1.089019] [] dump_stack+0x19/0x1b [1.090017] [] warn_slowpath_common+0x61/0x80 [1.091015] [] warn_slowpath_null+0x1a/0x20 [1.092016] [] setup_local_APIC+0x268/0x320 [1.093019] [] native_smp_prepare_cpus+0x294/0x35b [1.094018] [] kernel_init_freeable+0xbb/0x217 [1.095017] [] ? rest_init+0x80/0x80 [1.096015] [] kernel_init+0xe/0x180 [1.097016] [] ret_from_fork+0x7c/0xb0 [1.098016] [] ? rest_init+0x80/0x80 [1.099017] ---[ end trace d99eba50bffa17c5 ]--- Thanks, Zhu Cheers, Andreas .
[Qemu-devel] [PATCH v9 1/4] apic: map APIC's MMIO region at each CPU's address space
From: Chen Fan Replace mapping APIC at global system address space with mapping it at per-CPU address spaces. Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- hw/i386/pc.c | 7 --- hw/intc/apic_common.c | 6 -- target-i386/cpu.c | 21 + 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 7072930..9f16128 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1076,13 +1076,6 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) object_unref(OBJECT(cpu)); } -/* map APIC MMIO area if CPU has APIC */ -if (cpu && cpu->apic_state) { -/* XXX: what if the base changes? */ -sysbus_mmio_map_overlap(SYS_BUS_DEVICE(icc_bridge), 0, -APIC_DEFAULT_ADDRESS, 0x1000); -} - /* tell smbios about cpuid version and features */ smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); } diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index 0032b97..c0b32eb 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -296,7 +296,6 @@ static void apic_common_realize(DeviceState *dev, Error **errp) APICCommonClass *info; static DeviceState *vapic; static int apic_no; -static bool mmio_registered; if (apic_no >= MAX_APICS) { error_setg(errp, "%s initialization failed.", @@ -307,11 +306,6 @@ static void apic_common_realize(DeviceState *dev, Error **errp) info = APIC_COMMON_GET_CLASS(s); info->realize(dev, errp); -if (!mmio_registered) { -ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev)); -memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory); -mmio_registered = true; -} /* Note: We need at least 1M to map the VAPIC option ROM */ if (!vapic && s->vapic_control & VAPIC_ENABLE_MASK && diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 36b07f9..11affce 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2741,6 +2741,7 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp) /* TODO: convert to link<> */ apic = APIC_COMMON(cpu->apic_state); apic->cpu = cpu; +apic->apicbase = APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE; } static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) @@ -2785,8 +2786,10 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) X86CPU *cpu = X86_CPU(dev); X86CPUClass *xcc = X86_CPU_GET_CLASS(dev); CPUX86State *env = &cpu->env; +APICCommonState *apic; Error *local_err = NULL; static bool ht_warned; +static bool apic_mmio_map_once; if (cpu->apic_id < 0) { error_setg(errp, "apic-id property was not initialized properly"); @@ -2873,6 +2876,24 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) if (local_err != NULL) { goto out; } + +/* map APIC MMIO area */ +apic = APIC_COMMON(cpu->apic_state); +if (tcg_enabled()) { +memory_region_add_subregion_overlap(cpu->cpu_as_root, +apic->apicbase & +MSR_IA32_APICBASE_BASE, +&apic->io_memory, +0x1000); +} else if (!apic_mmio_map_once) { +memory_region_add_subregion_overlap(get_system_memory(), +apic->apicbase & +MSR_IA32_APICBASE_BASE, +&apic->io_memory, +0x1000); +apic_mmio_map_once = true; +} + cpu_reset(cs); xcc->parent_realize(dev, &local_err); -- 1.9.3
[Qemu-devel] [PATCH v9 2/4] x86: use new method to correct reset sequence
Something must be occur during reset of the X86 platform in a specific order. For example, the apic reset should be after some devices (such as hpet, rtc) reset, so that the apic register could be set to default values. This patch uses the new QEMUMachine reset method to solve the above problem, ensuring the various reset happen in the correct order. Signed-off-by: Zhu Guihua --- hw/i386/pc.c | 17 + 1 file changed, 17 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 9f16128..314930a 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1860,6 +1860,22 @@ static void pc_machine_initfn(Object *obj) NULL, NULL); } +static void pc_machine_reset(void) +{ +CPUState *cs; +X86CPU *cpu; + +qemu_devices_reset(); + +CPU_FOREACH(cs) { +cpu = X86_CPU(cs); + +if (cpu->apic_state) { +device_reset(cpu->apic_state); +} +} +} + static unsigned pc_cpu_index_to_socket_id(unsigned cpu_index) { unsigned pkg_id, core_id, smt_id; @@ -1877,6 +1893,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) pcmc->get_hotplug_handler = mc->get_hotplug_handler; mc->get_hotplug_handler = pc_get_hotpug_handler; mc->cpu_index_to_socket_id = pc_cpu_index_to_socket_id; +mc->reset = pc_machine_reset; hc->plug = pc_machine_device_plug_cb; hc->unplug_request = pc_machine_device_unplug_request_cb; hc->unplug = pc_machine_device_unplug_cb; -- 1.9.3
[Qemu-devel] [PATCH v9 0/4] remove icc bus/bridge
ICC Bus was used for providing a hotpluggable bus for APIC and CPU, but now we use HotplugHandler to make hotplug. So ICC Bus is unnecessary. This code has passed the new pc-cpu-test. And I have tested with kvm along with kernel_irqchip=on/off, it works fine. This patch series is based on the latest master. v9: -use a callback to correct reset sequence for x86 -update apic mmio mapping v8: -add a wrapper to specify reset order v7: -update to register reset handler for main_system_bus when created -register reset handler for apic after all devices are initialized Chen Fan (2): apic: map APIC's MMIO region at each CPU's address space cpu/apic: drop icc bus/bridge Zhu Guihua (2): x86: use new method to correct reset sequence icc_bus: drop the unused files default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - hw/i386/pc.c | 43 +++--- hw/i386/pc_piix.c | 9 +-- hw/i386/pc_q35.c | 9 +-- hw/intc/apic_common.c | 11 +--- include/hw/cpu/icc_bus.h | 82 -- include/hw/i386/apic_internal.h| 7 ++- include/hw/i386/pc.h | 2 +- target-i386/cpu.c | 30 +++--- 12 files changed, 52 insertions(+), 262 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h -- 1.9.3
[Qemu-devel] [PATCH v9 3/4] cpu/apic: drop icc bus/bridge
From: Chen Fan After CPU hotplug has been converted to BUS-less hot-plug infrastructure, the only function ICC bus performs is to propagate reset to LAPICs. However LAPIC could be reset by registering its reset handler after all device are initialized. Do so and drop ~200LOC of not needed anymore ICCBus related code. Signed-off-by: Chen Fan Signed-off-by: Zhu Guihua --- hw/i386/pc.c| 19 --- hw/i386/pc_piix.c | 9 + hw/i386/pc_q35.c| 9 + hw/intc/apic_common.c | 5 ++--- include/hw/i386/apic_internal.h | 7 --- include/hw/i386/pc.h| 2 +- target-i386/cpu.c | 9 + 7 files changed, 14 insertions(+), 46 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 314930a..aca4dd0 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -59,7 +59,6 @@ #include "qemu/error-report.h" #include "hw/acpi/acpi.h" #include "hw/acpi/cpu_hotplug.h" -#include "hw/cpu/icc_bus.h" #include "hw/boards.h" #include "hw/pci/pci_host.h" #include "acpi-build.h" @@ -970,23 +969,16 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level) } static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id, - DeviceState *icc_bridge, Error **errp) + Error **errp) { X86CPU *cpu = NULL; Error *local_err = NULL; -if (icc_bridge == NULL) { -error_setg(&local_err, "Invalid icc-bridge value"); -goto out; -} - cpu = cpu_x86_create(cpu_model, &local_err); if (local_err != NULL) { goto out; } -qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc")); - object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err); object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); @@ -1003,7 +995,6 @@ static const char *current_cpu_model; void pc_hot_add_cpu(const int64_t id, Error **errp) { -DeviceState *icc_bridge; X86CPU *cpu; int64_t apic_id = x86_cpu_apic_id_from_index(id); Error *local_err = NULL; @@ -1032,9 +1023,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) return; } -icc_bridge = DEVICE(object_resolve_path_type("icc-bridge", - TYPE_ICC_BRIDGE, NULL)); -cpu = pc_new_cpu(current_cpu_model, apic_id, icc_bridge, &local_err); +cpu = pc_new_cpu(current_cpu_model, apic_id, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -1042,7 +1031,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) object_unref(OBJECT(cpu)); } -void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) +void pc_cpus_init(const char *cpu_model) { int i; X86CPU *cpu = NULL; @@ -1068,7 +1057,7 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) for (i = 0; i < smp_cpus; i++) { cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i), - icc_bridge, &error); + &error); if (error) { error_report_err(error); exit(1); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index e142f75..7e9a185 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -39,7 +39,6 @@ #include "hw/kvm/clock.h" #include "sysemu/sysemu.h" #include "hw/sysbus.h" -#include "hw/cpu/icc_bus.h" #include "sysemu/arch_init.h" #include "sysemu/block-backend.h" #include "hw/i2c/smbus.h" @@ -98,7 +97,6 @@ static void pc_init1(MachineState *machine) MemoryRegion *ram_memory; MemoryRegion *pci_memory; MemoryRegion *rom_memory; -DeviceState *icc_bridge; PcGuestInfo *guest_info; ram_addr_t lowmem; @@ -142,11 +140,7 @@ static void pc_init1(MachineState *machine) exit(1); } -icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); -object_property_add_child(qdev_get_machine(), "icc-bridge", - OBJECT(icc_bridge), NULL); - -pc_cpus_init(machine->cpu_model, icc_bridge); +pc_cpus_init(machine->cpu_model); if (kvm_enabled() && kvmclock_enabled) { kvmclock_create(); @@ -229,7 +223,6 @@ static void pc_init1(MachineState *machine) if (pci_enabled) { ioapic_init_gsi(gsi_state, "i440fx"); } -qdev_init_nofail(icc_bridge); pc_register_ferr_irq(gsi[13]); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 082cd93..9af1d06 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -43,7 +43,6 @@ #include "hw/ide/pci.h" #include "hw/ide/ahci.h" #include "hw/usb.h" -#include "hw/cpu/icc_bus.h"
[Qemu-devel] [PATCH v9 4/4] icc_bus: drop the unused files
ICC bus impl has been droped, so all icc related files are not useful any more; delete them. Signed-off-by: Zhu Guihua --- default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - hw/cpu/Makefile.objs | 1 - hw/cpu/icc_bus.c | 118 - include/hw/cpu/icc_bus.h | 82 -- 5 files changed, 203 deletions(-) delete mode 100644 hw/cpu/icc_bus.c delete mode 100644 include/hw/cpu/icc_bus.h diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 91d602c..0759f22 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -42,7 +42,6 @@ CONFIG_LPC_ICH9=y CONFIG_PCI_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y -CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_XIO3130=y diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index 62575eb..08aac8c 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -43,7 +43,6 @@ CONFIG_LPC_ICH9=y CONFIG_PCI_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y -CONFIG_ICC_BUS=y CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_XIO3130=y diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs index 6381238..0954a18 100644 --- a/hw/cpu/Makefile.objs +++ b/hw/cpu/Makefile.objs @@ -2,5 +2,4 @@ obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o obj-$(CONFIG_REALVIEW) += realview_mpcore.o obj-$(CONFIG_A9MPCORE) += a9mpcore.o obj-$(CONFIG_A15MPCORE) += a15mpcore.o -obj-$(CONFIG_ICC_BUS) += icc_bus.o diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c deleted file mode 100644 index 6646ea2..000 --- a/hw/cpu/icc_bus.c +++ /dev/null @@ -1,118 +0,0 @@ -/* icc_bus.c - * emulate x86 ICC (Interrupt Controller Communications) bus - * - * Copyright (c) 2013 Red Hat, Inc - * - * Authors: - * Igor Mammedov - * - * 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 <http://www.gnu.org/licenses/> - */ -#include "hw/cpu/icc_bus.h" -#include "hw/sysbus.h" - -/* icc-bridge implementation */ - -static const TypeInfo icc_bus_info = { -.name = TYPE_ICC_BUS, -.parent = TYPE_BUS, -.instance_size = sizeof(ICCBus), -}; - - -/* icc-device implementation */ - -static void icc_device_realize(DeviceState *dev, Error **errp) -{ -ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(dev); - -/* convert to QOM */ -if (idc->realize) { -idc->realize(dev, errp); -} - -} - -static void icc_device_class_init(ObjectClass *oc, void *data) -{ -DeviceClass *dc = DEVICE_CLASS(oc); - -dc->realize = icc_device_realize; -dc->bus_type = TYPE_ICC_BUS; -} - -static const TypeInfo icc_device_info = { -.name = TYPE_ICC_DEVICE, -.parent = TYPE_DEVICE, -.abstract = true, -.instance_size = sizeof(ICCDevice), -.class_size = sizeof(ICCDeviceClass), -.class_init = icc_device_class_init, -}; - - -/* icc-bridge implementation */ - -typedef struct ICCBridgeState { -/*< private >*/ -SysBusDevice parent_obj; -/*< public >*/ - -ICCBus icc_bus; -MemoryRegion apic_container; -} ICCBridgeState; - -#define ICC_BRIDGE(obj) OBJECT_CHECK(ICCBridgeState, (obj), TYPE_ICC_BRIDGE) - -static void icc_bridge_init(Object *obj) -{ -ICCBridgeState *s = ICC_BRIDGE(obj); -SysBusDevice *sb = SYS_BUS_DEVICE(obj); - -qbus_create_inplace(&s->icc_bus, sizeof(s->icc_bus), TYPE_ICC_BUS, -DEVICE(s), "icc"); - -/* Do not change order of registering regions, - * APIC must be first registered region, board maps it by 0 index - */ -memory_region_init(&s->apic_container, obj, "icc-apic-container", - APIC_SPACE_SIZE); -sysbus_init_mmio(sb, &s->apic_container); -s->icc_bus.apic_address_space = &s->apic_container; -} - -static void icc_bridge_class_init(ObjectClass *oc, void *data) -{ -DeviceClass *dc = DEVICE_CLASS(oc); - -set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); -} - -static const TypeInfo icc_bridge_info = { -.name = TYPE_ICC_BRIDGE, -.parent = TYPE_SYS_BUS_DEVICE, -.instance_init = icc_bridge_init, -.instance_size = sizeof(ICCBridgeState), -.class_init = icc_bridge_class_init, -}; - - -static void icc_bus_register_types(void) -{ -
Re: [Qemu-devel] [PATCH v2 00/11] cpu: add i386 cpu hot remove support
On Fri, 2015-01-23 at 11:24 +0100, Alexandre DERUMIER wrote: > Hello, > > I'm currently testing the new cpu unplug features, > Works fine here with debian guests and kernel 3.14. > Thanks for your test. > But I have notice some small potential bugs, but I'm not sure I'm doing it > right. > > 1)first, to unplug cpu, we need an id for cpu > Yes, if you want to unplug cpu, you must have an id for cpu. > The problem is that the current qemu command line > -smp 1,sockets=2,cores=1,maxcpus=2 > > for example, will create 1 cpu on apic-id 0 without any id, so we can't > unplug it. > > > So, I have tried with > > -smp 1,sockets=2,cores=1,maxcpus=2 -device kvm64-x86_64-cpu,apic-id=0,id=cpu0 > > But this give me an error: > "-device kvm64-x86_64-cpu,apic-id=0,id=cpu0: CPU with APIC ID 0 exists" > APIC ID 0 was used by the cpu of '-smp 1'. So you should use apic-id=1 > (also try to set -smp 0, but it's not working). > > > > 2) second problem, if I start with > -smp 1,sockets=2,cores=1,maxcpus=2 > > then hmp: > device_add kvm64-x86_64-cpu,apic-id=1,id=cpu1 > > then hmp : device_del cpu1 > > Got an error:" > This is the last cpu, should not be removed!" > > Oh, it's our problem, thanks for your pointing out. I will fix it in next version. Regards, Zhu > > This is coming from > [PATCH 06/12] pc: add cpu hot unplug request callback support > +if (smp_cpus == 1) { > +error_setg(&local_err, > + "This is the last cpu, should not be removed!"); > +goto out; > +} > > > > So, the only way unplug is working for me, is to start with -smp 2 minimum > -smp 2,sockets=2,cores=1,maxcpus=4 > > Then I can hotplug|unplug cpuid >= 2 > > > > Regards, > > Alexandre Derumier [...]
Re: [Qemu-devel] [PATCH v2 00/11] cpu: add i386 cpu hot remove support
On Mon, 2015-01-26 at 04:25 +0100, Alexandre DERUMIER wrote: > >>2)when numa is used, the hotplugged cpu is always on numa node 0 > >>(cpu_add or device_add cpu) > > About this, it seem to be a display bug in "info numa", > cpu is correctly assigned to numa node1 in the guest. > > Now in the guest, VCPUs are assigned round-robin. But in qemu, vcpus' property 'numa_node' was assigned the default value 0. We have made a patchset to solve this successfully. But we plan to send the patchset to the community later. Regards, Zhu > - Mail original - > De: "aderumier" > À: "Zhu Guihua" > Cc: "qemu-devel" , tangc...@cn.fujitsu.com, "guz fnst" > , "isimatu yasuaki" > , "Anshul Makkar" > , "chen fan fnst" > , "Igor Mammedov" , > "afaerber" > Envoyé: Lundi 26 Janvier 2015 04:19:52 > Objet: Re: [Qemu-devel] [PATCH v2 00/11] cpu: add i386 cpu hot remove support > > Thanks for your reply. > > 2 others things: > > 1) > on cpu unplug, I see that the cpu is correctly removed from my linux guest > but not from qemu > > starting with a guest with 3cpus: > > guest: #ls -lah /sys/devices/system/ |grep cpu > drwxr-xr-x 6 root root 0 Jan 25 22:16 cpu0 > drwxr-xr-x 6 root root 0 Jan 25 22:16 cpu1 > drwxr-xr-x 6 root root 0 Jan 25 22:16 cpu2 > > hmp: # info cpus > * CPU #0: pc=0x81057022 (halted) thread_id=24972 > CPU #1: pc=0x81057022 (halted) thread_id=24973 > CPU #2: pc=0x81048bc1 (halted) thread_id=25102 > > > then unplug cpu2 > hmp : device_del cpu2 > > guest: > > dmesg: > [ 176.219754] Unregister pv shared memory for cpu 2 > [ 176.278881] smpboot: CPU 2 is now offline > > #ls -lah /sys/devices/system/ |grep cpu > drwxr-xr-x 6 root root 0 Jan 25 22:16 cpu0 > drwxr-xr-x 6 root root 0 Jan 25 22:16 cpu1 > > hmp: # info cpus > * CPU #0: pc=0x81057022 (halted) thread_id=24972 > CPU #1: pc=0x81057022 (halted) thread_id=24973 > CPU #2: pc=0x81048bc1 (halted) thread_id=25102 > > > > > 2)when numa is used, the hotplugged cpu is always on numa node 0 > (cpu_add or device_add cpu) > > > starting a guest, with 2 sockets,1 cores > > -smp 2,sockets=2,cores=1,maxcpus=2 > -object memory-backend-ram,size=256M,id=ram-node0 -numa > node,nodeid=0,cpus=0,memdev=ram-node0 > -object memory-backend-ram,size=256M,id=ram-node1 -numa > node,nodeid=1,cpus=1,memdev=ram-node1 > > hmp: > # info numa > 2 nodes > node 0 cpus: 0 > node 0 size: 256 MB > node 1 cpus: 1 > node 1 size: 256 MB > > ok > > now > > starting with same topology, but with 1cpu at start > -smp 2,sockets=2,cores=1,maxcpus=2 > -object memory-backend-ram,size=256M,id=ram-node0 -numa > node,nodeid=0,cpus=0,memdev=ram-node0 > -object memory-backend-ram,size=256M,id=ram-node1 -numa > node,nodeid=1,cpus=1,memdev=ram-node1 > > # info numa > 2 nodes > node 0 cpus: 0 > node 0 size: 256 MB > node 1 cpus: > node 1 size: 256 MB > > hotpluging a cpu > # device_add kvm64-x86_64-cpu,apic-id=1,id=cpu1 > > # info numa > 2 nodes > node 0 cpus: 0 1 > node 0 size: 256 MB > node 1 cpus: > node 1 size: 256 MB > > cpu1 should be on node1, not node0. > > > Regards, > > Alexandre > > - Mail original - > De: "Zhu Guihua" > À: "aderumier" > Cc: "qemu-devel" , tangc...@cn.fujitsu.com, "guz fnst" > , "isimatu yasuaki" > , "Anshul Makkar" > , "chen fan fnst" > , "Igor Mammedov" , > "afaerber" > Envoyé: Lundi 26 Janvier 2015 03:01:48 > Objet: Re: [Qemu-devel] [PATCH v2 00/11] cpu: add i386 cpu hot remove support > > On Fri, 2015-01-23 at 11:24 +0100, Alexandre DERUMIER wrote: > > Hello, > > > > I'm currently testing the new cpu unplug features, > > Works fine here with debian guests and kernel 3.14. > > > > Thanks for your test. > > > But I have notice some small potential bugs, but I'm not sure I'm doing it > > right. > > > > 1)first, to unplug cpu, we need an id for cpu > > > > Yes, if you want to unplug cpu, you must have an id for cpu. > > > The problem is that the current qemu command line > > -smp 1,sockets=2,cores=1,maxcpus=2 > > > > for example, will create 1 cpu on apic-id 0 without any id, so we can't > > unplug it. > > > > > > So, I have tried with
Re: [Qemu-devel] [PATCH v2 00/11] cpu: add i386 cpu hot remove support
On Mon, 2015-01-26 at 04:19 +0100, Alexandre DERUMIER wrote: > Thanks for your reply. > > 2 others things: > > 1) > on cpu unplug, I see that the cpu is correctly removed from my linux guest > but not from qemu > About this, I can do it successfully on my qemu. So can you tell us more information about your operation? And I found the patchset you applied is the last version in your last email. I think you'd better apply the latest version. Regards, Zhu > starting with a guest with 3cpus: > > guest: #ls -lah /sys/devices/system/ |grep cpu > drwxr-xr-x 6 root root0 Jan 25 22:16 cpu0 > drwxr-xr-x 6 root root0 Jan 25 22:16 cpu1 > drwxr-xr-x 6 root root0 Jan 25 22:16 cpu2 > > hmp: # info cpus > * CPU #0: pc=0x81057022 (halted) thread_id=24972 > CPU #1: pc=0x81057022 (halted) thread_id=24973 > CPU #2: pc=0x81048bc1 (halted) thread_id=25102 > > > then unplug cpu2 > hmp : device_del cpu2 > > guest: > > dmesg: > [ 176.219754] Unregister pv shared memory for cpu 2 > [ 176.278881] smpboot: CPU 2 is now offline > > #ls -lah /sys/devices/system/ |grep cpu > drwxr-xr-x 6 root root0 Jan 25 22:16 cpu0 > drwxr-xr-x 6 root root0 Jan 25 22:16 cpu1 > > hmp: # info cpus > * CPU #0: pc=0x81057022 (halted) thread_id=24972 > CPU #1: pc=0x81057022 (halted) thread_id=24973 > CPU #2: pc=0x81048bc1 (halted) thread_id=25102 > > > > > 2)when numa is used, the hotplugged cpu is always on numa node 0 > (cpu_add or device_add cpu) > > > starting a guest, with 2 sockets,1 cores > > -smp 2,sockets=2,cores=1,maxcpus=2 > -object memory-backend-ram,size=256M,id=ram-node0 -numa > node,nodeid=0,cpus=0,memdev=ram-node0 > -object memory-backend-ram,size=256M,id=ram-node1 -numa > node,nodeid=1,cpus=1,memdev=ram-node1 > > hmp: > # info numa > 2 nodes > node 0 cpus: 0 > node 0 size: 256 MB > node 1 cpus: 1 > node 1 size: 256 MB > > ok > > now > > starting with same topology, but with 1cpu at start > -smp 2,sockets=2,cores=1,maxcpus=2 > -object memory-backend-ram,size=256M,id=ram-node0 -numa > node,nodeid=0,cpus=0,memdev=ram-node0 > -object memory-backend-ram,size=256M,id=ram-node1 -numa > node,nodeid=1,cpus=1,memdev=ram-node1 > > # info numa > 2 nodes > node 0 cpus: 0 > node 0 size: 256 MB > node 1 cpus: > node 1 size: 256 MB > > hotpluging a cpu > # device_add kvm64-x86_64-cpu,apic-id=1,id=cpu1 > > # info numa > 2 nodes > node 0 cpus: 0 1 > node 0 size: 256 MB > node 1 cpus: > node 1 size: 256 MB > > cpu1 should be on node1, not node0. > > > Regards, > > Alexandre > > - Mail original - > De: "Zhu Guihua" > À: "aderumier" > Cc: "qemu-devel" , tangc...@cn.fujitsu.com, "guz fnst" > , "isimatu yasuaki" > , "Anshul Makkar" > , "chen fan fnst" > , "Igor Mammedov" , > "afaerber" > Envoyé: Lundi 26 Janvier 2015 03:01:48 > Objet: Re: [Qemu-devel] [PATCH v2 00/11] cpu: add i386 cpu hot remove support > > On Fri, 2015-01-23 at 11:24 +0100, Alexandre DERUMIER wrote: > > Hello, > > > > I'm currently testing the new cpu unplug features, > > Works fine here with debian guests and kernel 3.14. > > > > Thanks for your test. > > > But I have notice some small potential bugs, but I'm not sure I'm doing it > > right. > > > > 1)first, to unplug cpu, we need an id for cpu > > > > Yes, if you want to unplug cpu, you must have an id for cpu. > > > The problem is that the current qemu command line > > -smp 1,sockets=2,cores=1,maxcpus=2 > > > > for example, will create 1 cpu on apic-id 0 without any id, so we can't > > unplug it. > > > > > > So, I have tried with > > > > -smp 1,sockets=2,cores=1,maxcpus=2 -device > > kvm64-x86_64-cpu,apic-id=0,id=cpu0 > > > > But this give me an error: > > "-device kvm64-x86_64-cpu,apic-id=0,id=cpu0: CPU with APIC ID 0 exists" > > > > APIC ID 0 was used by the cpu of '-smp 1'. > So you should use apic-id=1 > > > (also try to set -smp 0, but it's not working). > > > > > > > > 2) second problem, if I start with > > -smp 1,sockets=2,cores=1,maxcpus=2 > > > > then hmp: > > device_add kvm64-x86_64-cpu,apic-id=1,id=cpu1 > > > > then hmp : device_del cpu1 > > > > Got an error:" > > This is the last cpu, should not be removed!" > > > > > > Oh, it's our problem, thanks for your pointing out. > I will fix it in next version. > > Regards, > Zhu > > > > > This is coming from > > [PATCH 06/12] pc: add cpu hot unplug request callback support > > + if (smp_cpus == 1) { > > + error_setg(&local_err, > > + "This is the last cpu, should not be removed!"); > > + goto out; > > + } > > > > > > > > So, the only way unplug is working for me, is to start with -smp 2 minimum > > -smp 2,sockets=2,cores=1,maxcpus=4 > > > > Then I can hotplug|unplug cpuid >= 2 > > > > > > > > Regards, > > > > Alexandre Derumier > [...]
Re: [Qemu-devel] [PATCH v2 00/11] cpu: add i386 cpu hot remove support
On Mon, 2015-01-26 at 12:27 +0100, Alexandre DERUMIER wrote: > >>About this, I can do it successfully on my qemu. > >>So can you tell us more information about your operation? > simply start with > > -smp 2,sockets=2,cores=2,maxcpus=4 -device kvm64-x86_64-cpu,apic-id=2,id=cpu2 > > then > > #device_del cpu2 > > Guest return > [ 324.195024] Unregister pv shared memory for cpu 2 > [ 324.250579] smpboot: CPU 2 is now offline > > but cpu is not remove in qemu. > > I had also try to eject manualy from guest > echo 1 > /sys/bus/acpi/devices/LNXCPU\:02/eject > > But I have this error message > ACPI: \_SB_.CP02: Eject incomplete - status 0xf > > (maybe is it normal ? or maybe is it a guest bug (kernel 3.16 from debian > wheezy backports) ?) > According to your description, the guest has invoked _EJ0 method, but the method was executed unsuccessfully. Thus, only hot-unplug request was invoked in qemu, but hot-unplug was not so that cpu was still in qemu. Did you test any other kernel version? I will try kernel 3.16 to investigate this problem later. Regards, Zhu > > >>And I found the patchset you applied is the last version in your last > >>email. I think you'd better apply the latest version. > > I have applied on top of git theses patches series > > https://www.mail-archive.com/qemu-devel%40nongnu.org/msg272745.html > [Qemu-devel] [RESEND PATCH v1 0/5] Common unplug and unplug request cb for > memory and CPU hot-unplug. > https://lists.nongnu.org/archive/html/qemu-devel/2015-01/msg01552.html > [Qemu-devel] [PATCH v3 0/7] cpu: add device_add foo-x86_64-cpusupport > https://www.mail-archive.com/qemu-devel@nongnu.org/msg273870.html > [Qemu-devel] [PATCH v2 00/11] cpu: add i386 cpu hot remove support > > - Mail original - > De: "Zhu Guihua" > À: "aderumier" > Cc: "qemu-devel" , tangc...@cn.fujitsu.com, "guz fnst" > , "isimatu yasuaki" > , "Anshul Makkar" > , "chen fan fnst" > , "Igor Mammedov" , > "afaerber" > Envoyé: Lundi 26 Janvier 2015 04:47:13 > Objet: Re: [Qemu-devel] [PATCH v2 00/11] cpu: add i386 cpu hot remove support > > On Mon, 2015-01-26 at 04:19 +0100, Alexandre DERUMIER wrote: > > Thanks for your reply. > > > > 2 others things: > > > > 1) > > on cpu unplug, I see that the cpu is correctly removed from my linux guest > > but not from qemu > > > > About this, I can do it successfully on my qemu. > So can you tell us more information about your operation? > > And I found the patchset you applied is the last version in your last > email. I think you'd better apply the latest version. > > Regards, > Zhu > > > starting with a guest with 3cpus: > > > > guest: #ls -lah /sys/devices/system/ |grep cpu > > drwxr-xr-x 6 root root 0 Jan 25 22:16 cpu0 > > drwxr-xr-x 6 root root 0 Jan 25 22:16 cpu1 > > drwxr-xr-x 6 root root 0 Jan 25 22:16 cpu2 > > > > hmp: # info cpus > > * CPU #0: pc=0x81057022 (halted) thread_id=24972 > > CPU #1: pc=0x81057022 (halted) thread_id=24973 > > CPU #2: pc=0x81048bc1 (halted) thread_id=25102 > > > > > > then unplug cpu2 > > hmp : device_del cpu2 > > > > guest: > > > > dmesg: > > [ 176.219754] Unregister pv shared memory for cpu 2 > > [ 176.278881] smpboot: CPU 2 is now offline > > > > #ls -lah /sys/devices/system/ |grep cpu > > drwxr-xr-x 6 root root 0 Jan 25 22:16 cpu0 > > drwxr-xr-x 6 root root 0 Jan 25 22:16 cpu1 > > > > hmp: # info cpus > > * CPU #0: pc=0x81057022 (halted) thread_id=24972 > > CPU #1: pc=0x81057022 (halted) thread_id=24973 > > CPU #2: pc=0x81048bc1 (halted) thread_id=25102 > > > > > > > > > > 2)when numa is used, the hotplugged cpu is always on numa node 0 > > (cpu_add or device_add cpu) > > > > > > starting a guest, with 2 sockets,1 cores > > > > -smp 2,sockets=2,cores=1,maxcpus=2 > > -object memory-backend-ram,size=256M,id=ram-node0 -numa > > node,nodeid=0,cpus=0,memdev=ram-node0 > > -object memory-backend-ram,size=256M,id=ram-node1 -numa > > node,nodeid=1,cpus=1,memdev=ram-node1 > > > > hmp: > > # info numa > > 2 nodes > > node 0 cpus: 0 > > node 0 size: 256 MB > > node 1 cpus: 1 > > node 1 size: 256 MB > > > > ok > > > > now > > > > starting with same topology, but with 1cpu at start > &
[Qemu-devel] [PATCH v2 2/5] acpi, ich9: Add hotunplug request cb for ich9.
From: Tang Chen Memory and CPU hot unplug are both asynchronous procedures. They both need unplug request cb when the unplug operation happens. This patch adds hotunplug request cb for ich9, and memory and CPU hot unplug will share it. Reviewed-by: Igor Mammedov Signed-off-by: Tang Chen Signed-off-by: Zhu Guihua --- hw/acpi/ich9.c | 7 +++ hw/isa/lpc_ich9.c | 5 +++-- include/hw/acpi/ich9.h | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 884dab3..5fe1eb8 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -397,6 +397,13 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp) } } +void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, + Error **errp) +{ +error_setg(errp, "acpi: device unplug request for not supported device" + " type: %s", object_get_typename(OBJECT(dev))); +} + void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) { ICH9LPCState *s = ICH9_LPC_DEVICE(adev); diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 530b074..d00b223 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -610,8 +610,9 @@ static void ich9_device_plug_cb(HotplugHandler *hotplug_dev, static void ich9_device_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { -error_setg(errp, "acpi: device unplug request for not supported device" - " type: %s", object_get_typename(OBJECT(dev))); +ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); + +ich9_pm_device_unplug_request_cb(&lpc->pm, dev, errp); } static bool ich9_rst_cnt_needed(void *opaque) diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index 12d7a7a..eaef0c3 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -63,6 +63,8 @@ extern const VMStateDescription vmstate_ich9_pm; void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp); void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp); +void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, + Error **errp); void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); #endif /* HW_ACPI_ICH9_H */ -- 1.9.3