New patch
1
Akihiko's v4 patch was doing too many things at once to
2
my taste, so I split it to follow dumbly each steps.
3
https://lore.kernel.org/qemu-devel/20250104-bus-v4-1-244cf1c6e2aa@daynix.com/
1
4
5
Akihiko Odaki (6):
6
hw/qdev: Pass bus argument to qdev_hotplug_allowed()
7
hw/qdev: Factor qdev_hotunplug_allowed() out
8
hw/qdev: Introduce qdev_hotplug_unplug_allowed_common()
9
hw/qdev: Check DevClass::hotpluggable in hotplug_unplug_allowed_common
10
hw/qdev: Check qbus_is_hotpluggable in hotplug_unplug_allowed_common
11
hw/qdev: Check machine_hotplug_handler in
12
hotplug_unplug_allowed_common
13
14
include/hw/qdev-core.h | 3 ++-
15
hw/core/qdev-hotplug.c | 42 +++++++++++++++++++++++++++++++++++++++++-
16
system/qdev-monitor.c | 37 +++++--------------------------------
17
3 files changed, 48 insertions(+), 34 deletions(-)
18
19
--
20
2.47.1
diff view generated by jsdifflib
New patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
2
3
In preparation of checking the parent bus is hot(un)pluggable
4
in a few commits, pass a 'bus' argument to qdev_hotplug_allowed().
5
6
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
---
9
include/hw/qdev-core.h | 2 +-
10
hw/core/qdev-hotplug.c | 2 +-
11
system/qdev-monitor.c | 2 +-
12
3 files changed, 3 insertions(+), 3 deletions(-)
13
14
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/qdev-core.h
17
+++ b/include/hw/qdev-core.h
18
@@ -XXX,XX +XXX,XX @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
19
int required_for_version);
20
HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev);
21
HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev);
22
-bool qdev_hotplug_allowed(DeviceState *dev, Error **errp);
23
+bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp);
24
25
/**
26
* qdev_get_hotplug_handler() - Get handler responsible for device wiring
27
diff --git a/hw/core/qdev-hotplug.c b/hw/core/qdev-hotplug.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/core/qdev-hotplug.c
30
+++ b/hw/core/qdev-hotplug.c
31
@@ -XXX,XX +XXX,XX @@ HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
32
return NULL;
33
}
34
35
-bool qdev_hotplug_allowed(DeviceState *dev, Error **errp)
36
+bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp)
37
{
38
MachineState *machine;
39
MachineClass *mc;
40
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/system/qdev-monitor.c
43
+++ b/system/qdev-monitor.c
44
@@ -XXX,XX +XXX,XX @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
45
46
/* Check whether the hotplug is allowed by the machine */
47
if (phase_check(PHASE_MACHINE_READY)) {
48
- if (!qdev_hotplug_allowed(dev, errp)) {
49
+ if (!qdev_hotplug_allowed(dev, bus, errp)) {
50
goto err_del_dev;
51
}
52
53
--
54
2.47.1
55
56
diff view generated by jsdifflib
New patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
2
3
Factor qdev_hotunplug_allowed() out of qdev_unplug().
4
Start checking the device is not blocked.
5
6
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
---
9
include/hw/qdev-core.h | 1 +
10
hw/core/qdev-hotplug.c | 5 +++++
11
system/qdev-monitor.c | 2 +-
12
3 files changed, 7 insertions(+), 1 deletion(-)
13
14
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/qdev-core.h
17
+++ b/include/hw/qdev-core.h
18
@@ -XXX,XX +XXX,XX @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
19
HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev);
20
HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev);
21
bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp);
22
+bool qdev_hotunplug_allowed(DeviceState *dev, Error **errp);
23
24
/**
25
* qdev_get_hotplug_handler() - Get handler responsible for device wiring
26
diff --git a/hw/core/qdev-hotplug.c b/hw/core/qdev-hotplug.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/core/qdev-hotplug.c
29
+++ b/hw/core/qdev-hotplug.c
30
@@ -XXX,XX +XXX,XX @@ bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp)
31
return true;
32
}
33
34
+bool qdev_hotunplug_allowed(DeviceState *dev, Error **errp)
35
+{
36
+ return !qdev_unplug_blocked(dev, errp);
37
+}
38
+
39
HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev)
40
{
41
if (dev->parent_bus) {
42
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/system/qdev-monitor.c
45
+++ b/system/qdev-monitor.c
46
@@ -XXX,XX +XXX,XX @@ void qdev_unplug(DeviceState *dev, Error **errp)
47
HotplugHandlerClass *hdc;
48
Error *local_err = NULL;
49
50
- if (qdev_unplug_blocked(dev, errp)) {
51
+ if (!qdev_hotunplug_allowed(dev, errp)) {
52
return;
53
}
54
55
--
56
2.47.1
57
58
diff view generated by jsdifflib
New patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
2
3
Introduce qdev_hotplug_unplug_allowed_common() to hold
4
common code between checking hot-plug/unplug is allowed.
5
6
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
---
9
hw/core/qdev-hotplug.c | 13 ++++++++++++-
10
1 file changed, 12 insertions(+), 1 deletion(-)
11
12
diff --git a/hw/core/qdev-hotplug.c b/hw/core/qdev-hotplug.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/core/qdev-hotplug.c
15
+++ b/hw/core/qdev-hotplug.c
16
@@ -XXX,XX +XXX,XX @@ HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
17
return NULL;
18
}
19
20
+static bool qdev_hotplug_unplug_allowed_common(DeviceState *dev, BusState *bus,
21
+ Error **errp)
22
+{
23
+ return true;
24
+}
25
+
26
bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp)
27
{
28
MachineState *machine;
29
MachineClass *mc;
30
Object *m_obj = qdev_get_machine();
31
32
+ if (!qdev_hotplug_unplug_allowed_common(dev, bus, errp)) {
33
+ return false;
34
+ }
35
+
36
if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
37
machine = MACHINE(m_obj);
38
mc = MACHINE_GET_CLASS(machine);
39
@@ -XXX,XX +XXX,XX @@ bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp)
40
41
bool qdev_hotunplug_allowed(DeviceState *dev, Error **errp)
42
{
43
- return !qdev_unplug_blocked(dev, errp);
44
+ return !qdev_unplug_blocked(dev, errp) &&
45
+ qdev_hotplug_unplug_allowed_common(dev, dev->parent_bus, errp);
46
}
47
48
HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev)
49
--
50
2.47.1
51
52
diff view generated by jsdifflib
1
Commit 03fcbd9dc508 ("qdev: Check for the availability of a hotplug
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
controller before adding a device") says:
3
> The qdev_unplug() function contains a g_assert(hotplug_ctrl)
4
> statement, so QEMU crashes when the user tries to device_add +
5
> device_del a device that does not have a corresponding hotplug
6
> controller.
7
2
8
> The code in qdev_device_add() already checks whether the bus has a
3
Check the same code once in the common helper.
9
> proper hotplug controller, but for devices that do not have a
10
> corresponding bus, here is no appropriate check available yet. In that
11
> case we should check whether the machine itself provides a suitable
12
> hotplug controller and refuse to plug the device if none is available.
13
4
14
However, it forgot to add the corresponding check to qdev_unplug().
5
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
---
8
hw/core/qdev-hotplug.c | 9 +++++++++
9
system/qdev-monitor.c | 10 +---------
10
2 files changed, 10 insertions(+), 9 deletions(-)
15
11
16
Most checks are comon between the hot-plug and hot-unplug scenarios so
17
extract them and share the implementation, saving some code and fixing
18
the aforementioned bug.
19
20
Fixes: 7716b8ca74 ("qdev: HotplugHandler: Add support for unplugging BUS-less devices")
21
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
22
---
23
Changes in v4:
24
- Rebased.
25
- Link to v3: https://lore.kernel.org/r/20240218-bus-v3-1-877725ce6d15@daynix.com
26
27
Changes in v3:
28
- Extracted checks common for hot-plug and hot-unplug into a function.
29
- Link to v2: https://lore.kernel.org/r/20231210-bus-v2-1-34ebf5726fa0@daynix.com
30
31
Changes in v2:
32
- Fixed indention.
33
- Link to v1: https://lore.kernel.org/r/20231202-bus-v1-1-f7540e3a8d62@daynix.com
34
---
35
include/hw/qdev-core.h | 3 ++-
36
hw/core/qdev-hotplug.c | 42 +++++++++++++++++++++++++++++++++++++++++-
37
system/qdev-monitor.c | 37 +++++--------------------------------
38
3 files changed, 48 insertions(+), 34 deletions(-)
39
40
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/include/hw/qdev-core.h
43
+++ b/include/hw/qdev-core.h
44
@@ -XXX,XX +XXX,XX @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
45
int required_for_version);
46
HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev);
47
HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev);
48
-bool qdev_hotplug_allowed(DeviceState *dev, Error **errp);
49
+bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp);
50
+bool qdev_hotunplug_allowed(DeviceState *dev, Error **errp);
51
52
/**
53
* qdev_get_hotplug_handler() - Get handler responsible for device wiring
54
diff --git a/hw/core/qdev-hotplug.c b/hw/core/qdev-hotplug.c
12
diff --git a/hw/core/qdev-hotplug.c b/hw/core/qdev-hotplug.c
55
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/core/qdev-hotplug.c
14
--- a/hw/core/qdev-hotplug.c
57
+++ b/hw/core/qdev-hotplug.c
15
+++ b/hw/core/qdev-hotplug.c
58
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
...
...
62
+#include "qapi/error.h"
20
+#include "qapi/error.h"
63
21
64
HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
22
HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
65
{
23
{
66
@@ -XXX,XX +XXX,XX @@ HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
24
@@ -XXX,XX +XXX,XX @@ HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
67
return NULL;
25
static bool qdev_hotplug_unplug_allowed_common(DeviceState *dev, BusState *bus,
68
}
26
Error **errp)
69
27
{
70
-bool qdev_hotplug_allowed(DeviceState *dev, Error **errp)
71
+static bool qdev_hotplug_unplug_allowed_common(DeviceState *dev, BusState *bus,
72
+ Error **errp)
73
+{
74
+ DeviceClass *dc = DEVICE_GET_CLASS(dev);
28
+ DeviceClass *dc = DEVICE_GET_CLASS(dev);
75
+
29
+
76
+ if (!dc->hotpluggable) {
30
+ if (!dc->hotpluggable) {
77
+ error_setg(errp, "Device '%s' does not support hotplugging",
31
+ error_setg(errp, "Device '%s' does not support hotplugging",
78
+ object_get_typename(OBJECT(dev)));
32
+ object_get_typename(OBJECT(dev)));
79
+ return false;
33
+ return false;
80
+ }
34
+ }
81
+
35
+
82
+ if (bus) {
83
+ if (!qbus_is_hotpluggable(bus)) {
84
+ error_setg(errp, "Bus '%s' does not support hotplugging",
85
+ bus->name);
86
+ return false;
87
+ }
88
+ } else {
89
+ if (!qdev_get_machine_hotplug_handler(dev)) {
90
+ /* No bus, no machine hotplug handler --> device is not hotpluggable */
91
+ error_setg(errp, "Device '%s' can not be hotplugged on this machine",
92
+ object_get_typename(OBJECT(dev)));
93
+ return false;
94
+ }
95
+ }
96
+
97
+ return true;
98
+}
99
+
100
+bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp)
101
{
102
MachineState *machine;
103
MachineClass *mc;
104
Object *m_obj = qdev_get_machine();
105
106
+ if (!qdev_hotplug_unplug_allowed_common(dev, bus, errp)) {
107
+ return false;
108
+ }
109
+
110
if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
111
machine = MACHINE(m_obj);
112
mc = MACHINE_GET_CLASS(machine);
113
@@ -XXX,XX +XXX,XX @@ bool qdev_hotplug_allowed(DeviceState *dev, Error **errp)
114
return true;
36
return true;
115
}
37
}
116
38
117
+bool qdev_hotunplug_allowed(DeviceState *dev, Error **errp)
118
+{
119
+ return !qdev_unplug_blocked(dev, errp) &&
120
+ qdev_hotplug_unplug_allowed_common(dev, dev->parent_bus, errp);
121
+}
122
+
123
HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev)
124
{
125
if (dev->parent_bus) {
126
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
39
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
127
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
128
--- a/system/qdev-monitor.c
41
--- a/system/qdev-monitor.c
129
+++ b/system/qdev-monitor.c
42
+++ b/system/qdev-monitor.c
130
@@ -XXX,XX +XXX,XX @@ static DeviceClass *qdev_get_device_class(const char **driver, Error **errp)
43
@@ -XXX,XX +XXX,XX @@ static DeviceClass *qdev_get_device_class(const char **driver, Error **errp)
...
...
135
- (phase_check(PHASE_MACHINE_READY) && !dc->hotpluggable)) {
48
- (phase_check(PHASE_MACHINE_READY) && !dc->hotpluggable)) {
136
+ if (!dc->user_creatable) {
49
+ if (!dc->user_creatable) {
137
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
50
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
138
"a pluggable device type");
51
"a pluggable device type");
139
return NULL;
52
return NULL;
140
@@ -XXX,XX +XXX,XX @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
141
return NULL;
142
}
143
144
- if (phase_check(PHASE_MACHINE_READY) && bus && !qbus_is_hotpluggable(bus)) {
145
- error_setg(errp, "Bus '%s' does not support hotplugging", bus->name);
146
- return NULL;
147
- }
148
-
149
if (migration_is_running()) {
150
error_setg(errp, "device_add not allowed while migrating");
151
return NULL;
152
@@ -XXX,XX +XXX,XX @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
153
dev = qdev_new(driver);
154
155
/* Check whether the hotplug is allowed by the machine */
156
- if (phase_check(PHASE_MACHINE_READY)) {
157
- if (!qdev_hotplug_allowed(dev, errp)) {
158
- goto err_del_dev;
159
- }
160
-
161
- if (!bus && !qdev_get_machine_hotplug_handler(dev)) {
162
- /* No bus, no machine hotplug handler --> device is not hotpluggable */
163
- error_setg(errp, "Device '%s' can not be hotplugged on this machine",
164
- driver);
165
- goto err_del_dev;
166
- }
167
+ if (phase_check(PHASE_MACHINE_READY) &&
168
+ !qdev_hotplug_allowed(dev, bus, errp)) {
169
+ goto err_del_dev;
170
}
171
172
/*
173
@@ -XXX,XX +XXX,XX @@ static DeviceState *find_device_state(const char *id, bool use_generic_error,
53
@@ -XXX,XX +XXX,XX @@ static DeviceState *find_device_state(const char *id, bool use_generic_error,
174
54
175
void qdev_unplug(DeviceState *dev, Error **errp)
55
void qdev_unplug(DeviceState *dev, Error **errp)
176
{
56
{
177
- DeviceClass *dc = DEVICE_GET_CLASS(dev);
57
- DeviceClass *dc = DEVICE_GET_CLASS(dev);
178
HotplugHandler *hotplug_ctrl;
58
HotplugHandler *hotplug_ctrl;
179
HotplugHandlerClass *hdc;
59
HotplugHandlerClass *hdc;
180
Error *local_err = NULL;
60
Error *local_err = NULL;
181
61
@@ -XXX,XX +XXX,XX @@ void qdev_unplug(DeviceState *dev, Error **errp)
182
- if (qdev_unplug_blocked(dev, errp)) {
62
return;
63
}
64
65
- if (!dc->hotpluggable) {
66
- error_setg(errp, "Device '%s' does not support hotplugging",
67
- object_get_typename(OBJECT(dev)));
183
- return;
68
- return;
184
- }
69
- }
185
-
70
-
186
- if (dev->parent_bus && !qbus_is_hotpluggable(dev->parent_bus)) {
71
if (migration_is_running() && !dev->allow_unplug_during_migration) {
187
- error_setg(errp, "Bus '%s' does not support hotplugging",
72
error_setg(errp, "device_del not allowed while migrating");
188
- dev->parent_bus->name);
189
- return;
190
- }
191
-
192
- if (!dc->hotpluggable) {
193
- error_setg(errp, "Device '%s' does not support hotplugging",
194
- object_get_typename(OBJECT(dev)));
195
+ if (!qdev_hotunplug_allowed(dev, errp)) {
196
return;
73
return;
197
}
74
--
198
75
2.47.1
199
76
200
---
201
base-commit: 38d0939b86e2eef6f6a622c6f1f7befda0146595
202
change-id: 20231202-bus-75a454c5d959
203
77
204
Best regards,
205
--
206
Akihiko Odaki <akihiko.odaki@daynix.com>
diff view generated by jsdifflib
New patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
2
3
Check the same code once in the common helper.
4
5
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
---
8
hw/core/qdev-hotplug.c | 8 ++++++++
9
system/qdev-monitor.c | 11 -----------
10
2 files changed, 8 insertions(+), 11 deletions(-)
11
12
diff --git a/hw/core/qdev-hotplug.c b/hw/core/qdev-hotplug.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/core/qdev-hotplug.c
15
+++ b/hw/core/qdev-hotplug.c
16
@@ -XXX,XX +XXX,XX @@ static bool qdev_hotplug_unplug_allowed_common(DeviceState *dev, BusState *bus,
17
return false;
18
}
19
20
+ if (bus) {
21
+ if (!qbus_is_hotpluggable(bus)) {
22
+ error_setg(errp, "Bus '%s' does not support hotplugging",
23
+ bus->name);
24
+ return false;
25
+ }
26
+ }
27
+
28
return true;
29
}
30
31
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/system/qdev-monitor.c
34
+++ b/system/qdev-monitor.c
35
@@ -XXX,XX +XXX,XX @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
36
return NULL;
37
}
38
39
- if (phase_check(PHASE_MACHINE_READY) && bus && !qbus_is_hotpluggable(bus)) {
40
- error_setg(errp, "Bus '%s' does not support hotplugging", bus->name);
41
- return NULL;
42
- }
43
-
44
if (migration_is_running()) {
45
error_setg(errp, "device_add not allowed while migrating");
46
return NULL;
47
@@ -XXX,XX +XXX,XX @@ void qdev_unplug(DeviceState *dev, Error **errp)
48
return;
49
}
50
51
- if (dev->parent_bus && !qbus_is_hotpluggable(dev->parent_bus)) {
52
- error_setg(errp, "Bus '%s' does not support hotplugging",
53
- dev->parent_bus->name);
54
- return;
55
- }
56
-
57
if (migration_is_running() && !dev->allow_unplug_during_migration) {
58
error_setg(errp, "device_del not allowed while migrating");
59
return;
60
--
61
2.47.1
62
63
diff view generated by jsdifflib
New patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
2
3
Commit 03fcbd9dc508 ("qdev: Check for the availability of a hotplug
4
controller before adding a device") says:
5
6
> The qdev_unplug() function contains a g_assert(hotplug_ctrl)
7
> statement, so QEMU crashes when the user tries to device_add +
8
> device_del a device that does not have a corresponding hotplug
9
> controller.
10
11
> The code in qdev_device_add() already checks whether the bus has a
12
> proper hotplug controller, but for devices that do not have a
13
> corresponding bus, here is no appropriate check available yet. In that
14
> case we should check whether the machine itself provides a suitable
15
> hotplug controller and refuse to plug the device if none is available.
16
17
However, it forgot to add the corresponding check to qdev_unplug().
18
19
Check the machine hotplug handler once in the common
20
qdev_hotplug_unplug_allowed_common() helper so both hotplug
21
and hot-unplug path are covered.
22
23
Fixes: 7716b8ca74 ("qdev: HotplugHandler: Add support for unplugging BUS-less devices")
24
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
25
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
26
---
27
hw/core/qdev-hotplug.c | 7 +++++++
28
system/qdev-monitor.c | 14 +++-----------
29
2 files changed, 10 insertions(+), 11 deletions(-)
30
31
diff --git a/hw/core/qdev-hotplug.c b/hw/core/qdev-hotplug.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/core/qdev-hotplug.c
34
+++ b/hw/core/qdev-hotplug.c
35
@@ -XXX,XX +XXX,XX @@ static bool qdev_hotplug_unplug_allowed_common(DeviceState *dev, BusState *bus,
36
bus->name);
37
return false;
38
}
39
+ } else {
40
+ if (!qdev_get_machine_hotplug_handler(dev)) {
41
+ /* No bus, no machine hotplug handler --> device is not hotpluggable */
42
+ error_setg(errp, "Device '%s' can not be hotplugged on this machine",
43
+ object_get_typename(OBJECT(dev)));
44
+ return false;
45
+ }
46
}
47
48
return true;
49
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/system/qdev-monitor.c
52
+++ b/system/qdev-monitor.c
53
@@ -XXX,XX +XXX,XX @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
54
dev = qdev_new(driver);
55
56
/* Check whether the hotplug is allowed by the machine */
57
- if (phase_check(PHASE_MACHINE_READY)) {
58
- if (!qdev_hotplug_allowed(dev, bus, errp)) {
59
- goto err_del_dev;
60
- }
61
-
62
- if (!bus && !qdev_get_machine_hotplug_handler(dev)) {
63
- /* No bus, no machine hotplug handler --> device is not hotpluggable */
64
- error_setg(errp, "Device '%s' can not be hotplugged on this machine",
65
- driver);
66
- goto err_del_dev;
67
- }
68
+ if (phase_check(PHASE_MACHINE_READY) &&
69
+ !qdev_hotplug_allowed(dev, bus, errp)) {
70
+ goto err_del_dev;
71
}
72
73
/*
74
--
75
2.47.1
76
77
diff view generated by jsdifflib