1
In vhost-user protocol we have VHOST_USER_BACKEND_CONFIG_CHANGE_MSG,
1
v4:
2
which backend may send to notify Qemu, that we should re-read the
2
Fixes 01-02 from v3 are already merged.
3
config, and notify the guest.
3
02: new, split out from 03
4
03: refacting vhost_user_blk_handle_config_change() split out to 02
5
drop current_run_state_str() helper
6
some rewordings (Markus)
4
7
5
Still that's not always convenient: backend may not support this
8
Vladimir Sementsov-Ogievskiy (3):
6
message. Also, having QMP command to force config sync is more reliable
9
qdev-monitor: add option to report GenericError from find_device_state
7
than waiting for notification from external program. It also may be
10
vhost-user-blk: split vhost_user_blk_sync_config()
8
helpful for debug/restore: if we have changed disk size, but guest
11
qapi: introduce device-sync-config
9
doesn't see that, it's good to have a separate QMP command to trigger
10
resync of the config.
11
12
12
So, the series proposes two experimental APIs:
13
hw/block/vhost-user-blk.c | 27 ++++++++++++-----
13
14
hw/virtio/virtio-pci.c | 9 ++++++
14
1. x-device-sync-config command, to trigger config synchronization
15
include/hw/qdev-core.h | 3 ++
15
16
qapi/qdev.json | 23 ++++++++++++++
16
2. X_CONFIG_READ event, which notify management tool that guest read the
17
system/qdev-monitor.c | 63 ++++++++++++++++++++++++++++++++++++---
17
updated config. Of course, that can't guarantee that the guest correctly
18
5 files changed, 114 insertions(+), 11 deletions(-)
18
handled the updated config, but it's still better than nothing: for sure
19
guest will not show new disk size until it read the updated config. So,
20
management tool may wait for this event to report success to the user.
21
22
23
The series is based on "[PATCH v8 0/4] pci hotplug tracking": it doesn't
24
depend on it, but just modify same files, so I just to avoid extra
25
conflicts.
26
Based-on: <20231005092926.56231-1-vsementsov@yandex-team.ru>
27
28
Vladimir Sementsov-Ogievskiy (4):
29
vhost-user-blk: simplify and fix vhost_user_blk_handle_config_change
30
qapi: introduce device-sync-config
31
qapi: device-sync-config: check runstate
32
qapi: introduce CONFIG_READ event
33
34
hw/block/vhost-user-blk.c | 32 ++++++++++++++---------
35
hw/virtio/virtio-pci.c | 18 +++++++++++++
36
include/hw/qdev-core.h | 3 +++
37
include/monitor/qdev.h | 1 +
38
include/sysemu/runstate.h | 1 +
39
monitor/monitor.c | 1 +
40
qapi/qdev.json | 36 ++++++++++++++++++++++++++
41
softmmu/qdev-monitor.c | 53 +++++++++++++++++++++++++++++++++++++++
42
softmmu/runstate.c | 5 ++++
43
9 files changed, 138 insertions(+), 12 deletions(-)
44
19
45
--
20
--
46
2.34.1
21
2.34.1
diff view generated by jsdifflib
1
Command result is racy if allow it during migration. Let's allow the
1
Here we just prepare for the following patch, making possible to report
2
sync only in RUNNING state.
2
GenericError as recommended.
3
4
This patch doesn't aim to prevent further use of DeviceNotFound by
5
future interfaces:
6
7
- find_device_state() is used in blk_by_qdev_id() and qmp_get_blk()
8
functions, which may lead to spread of DeviceNotFound anyway
9
- also, nothing prevent simply copy-pasting find_device_state() calls
10
with false argument
3
11
4
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
5
---
13
---
6
include/sysemu/runstate.h | 1 +
14
system/qdev-monitor.c | 15 +++++++++++----
7
softmmu/qdev-monitor.c | 27 ++++++++++++++++++++++++++-
15
1 file changed, 11 insertions(+), 4 deletions(-)
8
softmmu/runstate.c | 5 +++++
9
3 files changed, 32 insertions(+), 1 deletion(-)
10
16
11
diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h
17
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/include/sysemu/runstate.h
19
--- a/system/qdev-monitor.c
14
+++ b/include/sysemu/runstate.h
20
+++ b/system/qdev-monitor.c
15
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
16
#include "qemu/notify.h"
22
object_unref(OBJECT(dev));
17
23
}
18
bool runstate_check(RunState state);
24
19
+const char *current_run_state_str(void);
25
-static DeviceState *find_device_state(const char *id, Error **errp)
20
void runstate_set(RunState new_state);
26
+/*
21
RunState runstate_get(void);
27
+ * Note that creating new APIs using error classes other than GenericError is
22
bool runstate_is_running(void);
28
+ * not recommended. Set use_generic_error=true for new interfaces.
23
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
29
+ */
24
index XXXXXXX..XXXXXXX 100644
30
+static DeviceState *find_device_state(const char *id, bool use_generic_error,
25
--- a/softmmu/qdev-monitor.c
31
+ Error **errp)
26
+++ b/softmmu/qdev-monitor.c
32
{
27
@@ -XXX,XX +XXX,XX @@
33
Object *obj = object_resolve_path_at(qdev_get_peripheral(), id);
28
#include "monitor/monitor.h"
34
DeviceState *dev;
29
#include "monitor/qdev.h"
35
30
#include "sysemu/arch_init.h"
36
if (!obj) {
31
+#include "sysemu/runstate.h"
37
- error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
32
#include "qapi/error.h"
38
+ error_set(errp,
33
#include "qapi/qapi-commands-qdev.h"
39
+ (use_generic_error ?
34
#include "qapi/qapi-events-qdev.h"
40
+ ERROR_CLASS_GENERIC_ERROR : ERROR_CLASS_DEVICE_NOT_FOUND),
35
@@ -XXX,XX +XXX,XX @@ int qdev_sync_config(DeviceState *dev, Error **errp)
41
"Device '%s' not found", id);
36
42
return NULL;
37
void qmp_x_device_sync_config(const char *id, Error **errp)
43
}
44
@@ -XXX,XX +XXX,XX @@ void qdev_unplug(DeviceState *dev, Error **errp)
45
46
void qmp_device_del(const char *id, Error **errp)
38
{
47
{
39
- DeviceState *dev = find_device_state(id, errp);
48
- DeviceState *dev = find_device_state(id, errp);
40
+ MigrationState *s = migrate_get_current();
49
+ DeviceState *dev = find_device_state(id, false, errp);
41
+ DeviceState *dev;
50
if (dev != NULL) {
42
+
51
if (dev->pending_deleted_event &&
43
+ /*
52
(dev->pending_deleted_expires_ms == 0 ||
44
+ * During migration there is a race between syncing`config and migrating it,
53
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_by_qdev_id(const char *id, Error **errp)
45
+ * so let's just not allow it.
54
46
+ *
55
GLOBAL_STATE_CODE();
47
+ * Moreover, let's not rely on setting up interrupts in paused state, which
56
48
+ * may be a part of migration process.
57
- dev = find_device_state(id, errp);
49
+ */
58
+ dev = find_device_state(id, false, errp);
50
+
59
if (dev == NULL) {
51
+ if (migration_is_running(s->state)) {
60
return NULL;
52
+ error_setg(errp, "Config synchronization is not allowed "
53
+ "during migration.");
54
+ return;
55
+ }
56
+
57
+ if (!runstate_is_running()) {
58
+ error_setg(errp, "Config synchronization allowed only in '%s' state, "
59
+ "current state is '%s'", RunState_str(RUN_STATE_RUNNING),
60
+ current_run_state_str());
61
+ return;
62
+ }
63
+
64
+ dev = find_device_state(id, errp);
65
if (!dev) {
66
return;
67
}
61
}
68
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/softmmu/runstate.c
71
+++ b/softmmu/runstate.c
72
@@ -XXX,XX +XXX,XX @@ bool runstate_check(RunState state)
73
return current_run_state == state;
74
}
75
76
+const char *current_run_state_str(void)
77
+{
78
+ return RunState_str(current_run_state);
79
+}
80
+
81
static void runstate_init(void)
82
{
83
const RunStateTransition *p;
84
--
62
--
85
2.34.1
63
2.34.1
diff view generated by jsdifflib
1
Let's not care about what was changed and update the whole config,
1
Split vhost_user_blk_sync_config() out from
2
reasons:
2
vhost_user_blk_handle_config_change(), to be reused in the following
3
3
commit.
4
1. config->geometry should be updated together with capacity, so we fix
5
a bug.
6
7
2. Vhost-user protocol doesn't say anything about config change
8
limitation. Silent ignore of changes doesn't seem to be correct.
9
10
3. vhost-user-vsock reads the whole config
11
12
4. on realize we don't do any checks on retrieved config, so no reason
13
to care here
14
15
Also, let's notify guest unconditionally:
16
17
1. So does vhost-user-vsock
18
19
2. We are going to reuse the functionality in new cases when we do want
20
to notify the guest unconditionally. So, no reason to create extra
21
branches in the logic.
22
4
23
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
24
---
6
---
25
hw/block/vhost-user-blk.c | 11 +++--------
7
hw/block/vhost-user-blk.c | 26 +++++++++++++++++++-------
26
1 file changed, 3 insertions(+), 8 deletions(-)
8
1 file changed, 19 insertions(+), 7 deletions(-)
27
9
28
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
10
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
29
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/block/vhost-user-blk.c
12
--- a/hw/block/vhost-user-blk.c
31
+++ b/hw/block/vhost-user-blk.c
13
+++ b/hw/block/vhost-user-blk.c
32
@@ -XXX,XX +XXX,XX @@ static void vhost_user_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
14
@@ -XXX,XX +XXX,XX @@ static void vhost_user_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
15
s->blkcfg.wce = blkcfg->wce;
16
}
17
18
+static int vhost_user_blk_sync_config(DeviceState *dev, Error **errp)
19
+{
20
+ int ret;
21
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
22
+ VHostUserBlk *s = VHOST_USER_BLK(vdev);
23
+
24
+ ret = vhost_dev_get_config(&s->dev, (uint8_t *)&s->blkcfg,
25
+ vdev->config_len, errp);
26
+ if (ret < 0) {
27
+ return ret;
28
+ }
29
+
30
+ memcpy(vdev->config, &s->blkcfg, vdev->config_len);
31
+ virtio_notify_config(vdev);
32
+
33
+ return 0;
34
+}
35
+
33
static int vhost_user_blk_handle_config_change(struct vhost_dev *dev)
36
static int vhost_user_blk_handle_config_change(struct vhost_dev *dev)
34
{
37
{
35
int ret;
38
int ret;
36
- struct virtio_blk_config blkcfg;
39
- VirtIODevice *vdev = dev->vdev;
37
VirtIODevice *vdev = dev->vdev;
40
- VHostUserBlk *s = VHOST_USER_BLK(dev->vdev);
38
VHostUserBlk *s = VHOST_USER_BLK(dev->vdev);
39
Error *local_err = NULL;
41
Error *local_err = NULL;
40
@@ -XXX,XX +XXX,XX @@ static int vhost_user_blk_handle_config_change(struct vhost_dev *dev)
42
43
if (!dev->started) {
41
return 0;
44
return 0;
42
}
45
}
43
46
44
- ret = vhost_dev_get_config(dev, (uint8_t *)&blkcfg,
47
- ret = vhost_dev_get_config(dev, (uint8_t *)&s->blkcfg,
45
+ ret = vhost_dev_get_config(dev, (uint8_t *)&s->blkcfg,
48
- vdev->config_len, &local_err);
46
vdev->config_len, &local_err);
49
+ ret = vhost_user_blk_sync_config(DEVICE(dev->vdev), &local_err);
47
if (ret < 0) {
50
if (ret < 0) {
48
error_report_err(local_err);
51
error_report_err(local_err);
49
return ret;
52
return ret;
50
}
53
}
51
54
52
- /* valid for resize only */
55
- memcpy(dev->vdev->config, &s->blkcfg, vdev->config_len);
53
- if (blkcfg.capacity != s->blkcfg.capacity) {
56
- virtio_notify_config(dev->vdev);
54
- s->blkcfg.capacity = blkcfg.capacity;
57
-
55
- memcpy(dev->vdev->config, &s->blkcfg, vdev->config_len);
56
- virtio_notify_config(dev->vdev);
57
- }
58
+ memcpy(dev->vdev->config, &s->blkcfg, vdev->config_len);
59
+ virtio_notify_config(dev->vdev);
60
61
return 0;
58
return 0;
62
}
59
}
60
63
--
61
--
64
2.34.1
62
2.34.1
diff view generated by jsdifflib
1
Add command to sync config from vhost-user backend to the device. It
1
Add command to sync config from vhost-user backend to the device. It
2
may be helpful when VHOST_USER_SLAVE_CONFIG_CHANGE_MSG failed or not
2
may be helpful when VHOST_USER_SLAVE_CONFIG_CHANGE_MSG failed or not
3
triggered interrupt to the guest or just not available (not supported
3
triggered interrupt to the guest or just not available (not supported
4
by vhost-user server).
4
by vhost-user server).
5
5
6
Command result is racy if allow it during migration. Let's allow the
7
sync only in RUNNING state.
8
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
7
---
10
---
8
hw/block/vhost-user-blk.c | 27 ++++++++++++++++++++-------
11
hw/block/vhost-user-blk.c | 1 +
9
hw/virtio/virtio-pci.c | 9 +++++++++
12
hw/virtio/virtio-pci.c | 9 ++++++++
10
include/hw/qdev-core.h | 3 +++
13
include/hw/qdev-core.h | 3 +++
11
qapi/qdev.json | 14 ++++++++++++++
14
qapi/qdev.json | 23 +++++++++++++++++++
12
softmmu/qdev-monitor.c | 23 +++++++++++++++++++++++
15
system/qdev-monitor.c | 48 +++++++++++++++++++++++++++++++++++++++
13
5 files changed, 69 insertions(+), 7 deletions(-)
16
5 files changed, 84 insertions(+)
14
17
15
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
18
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/block/vhost-user-blk.c
20
--- a/hw/block/vhost-user-blk.c
18
+++ b/hw/block/vhost-user-blk.c
21
+++ b/hw/block/vhost-user-blk.c
19
@@ -XXX,XX +XXX,XX @@ static void vhost_user_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
20
s->blkcfg.wce = blkcfg->wce;
21
}
22
23
+static int vhost_user_blk_sync_config(DeviceState *dev, Error **errp)
24
+{
25
+ int ret;
26
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
27
+ VHostUserBlk *s = VHOST_USER_BLK(vdev);
28
+
29
+ ret = vhost_dev_get_config(&s->dev, (uint8_t *)&s->blkcfg,
30
+ vdev->config_len, errp);
31
+ if (ret < 0) {
32
+ return ret;
33
+ }
34
+
35
+ memcpy(vdev->config, &s->blkcfg, vdev->config_len);
36
+ virtio_notify_config(vdev);
37
+
38
+ return 0;
39
+}
40
+
41
static int vhost_user_blk_handle_config_change(struct vhost_dev *dev)
42
{
43
int ret;
44
- VirtIODevice *vdev = dev->vdev;
45
- VHostUserBlk *s = VHOST_USER_BLK(dev->vdev);
46
Error *local_err = NULL;
47
48
if (!dev->started) {
49
return 0;
50
}
51
52
- ret = vhost_dev_get_config(dev, (uint8_t *)&s->blkcfg,
53
- vdev->config_len, &local_err);
54
+ ret = vhost_user_blk_sync_config(DEVICE(dev->vdev), &local_err);
55
if (ret < 0) {
56
error_report_err(local_err);
57
return ret;
58
}
59
60
- memcpy(dev->vdev->config, &s->blkcfg, vdev->config_len);
61
- virtio_notify_config(dev->vdev);
62
-
63
return 0;
64
}
65
66
@@ -XXX,XX +XXX,XX @@ static void vhost_user_blk_class_init(ObjectClass *klass, void *data)
22
@@ -XXX,XX +XXX,XX @@ static void vhost_user_blk_class_init(ObjectClass *klass, void *data)
67
23
68
device_class_set_props(dc, vhost_user_blk_properties);
24
device_class_set_props(dc, vhost_user_blk_properties);
69
dc->vmsd = &vmstate_vhost_user_blk;
25
dc->vmsd = &vmstate_vhost_user_blk;
70
+ dc->sync_config = vhost_user_blk_sync_config;
26
+ dc->sync_config = vhost_user_blk_sync_config;
...
...
129
diff --git a/qapi/qdev.json b/qapi/qdev.json
85
diff --git a/qapi/qdev.json b/qapi/qdev.json
130
index XXXXXXX..XXXXXXX 100644
86
index XXXXXXX..XXXXXXX 100644
131
--- a/qapi/qdev.json
87
--- a/qapi/qdev.json
132
+++ b/qapi/qdev.json
88
+++ b/qapi/qdev.json
133
@@ -XXX,XX +XXX,XX @@
89
@@ -XXX,XX +XXX,XX @@
134
# Since: 8.2
135
##
90
##
136
{ 'event': 'X_DEVICE_ON', 'data': 'DeviceAndPath' }
91
{ 'event': 'DEVICE_UNPLUG_GUEST_ERROR',
92
'data': { '*device': 'str', 'path': 'str' } }
137
+
93
+
138
+##
94
+##
139
+# @x-device-sync-config:
95
+# @device-sync-config:
140
+#
96
+#
141
+# Sync config from backend to the guest.
97
+# Synchronize device configuration from host to guest part. First,
98
+# copy the configuration from the host part (backend) to the guest
99
+# part (frontend). Then notify guest software that device
100
+# configuration changed.
101
+# The command may be used to notify the guest about block device
102
+# capcity change. Currently only vhost-user-blk device supports
103
+# this.
142
+#
104
+#
143
+# @id: the device's ID or QOM path
105
+# @id: the device's ID or QOM path
144
+#
106
+#
145
+# Returns: Nothing on success
107
+# Features:
146
+# If @id is not a valid device, DeviceNotFound
147
+#
108
+#
148
+# Since: 8.2
109
+# @unstable: The command is experimental.
110
+#
111
+# Since: 9.1
149
+##
112
+##
150
+{ 'command': 'x-device-sync-config', 'data': {'id': 'str'} }
113
+{ 'command': 'device-sync-config',
151
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
114
+ 'features': [ 'unstable' ],
115
+ 'data': {'id': 'str'} }
116
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
152
index XXXXXXX..XXXXXXX 100644
117
index XXXXXXX..XXXXXXX 100644
153
--- a/softmmu/qdev-monitor.c
118
--- a/system/qdev-monitor.c
154
+++ b/softmmu/qdev-monitor.c
119
+++ b/system/qdev-monitor.c
155
@@ -XXX,XX +XXX,XX @@ HotplugInfo *qmp_x_query_hotplug(const char *id, Error **errp)
120
@@ -XXX,XX +XXX,XX @@
156
return hotplug_handler_get_state(hotplug_ctrl, dev, errp);
121
#include "monitor/monitor.h"
122
#include "monitor/qdev.h"
123
#include "sysemu/arch_init.h"
124
+#include "sysemu/runstate.h"
125
#include "qapi/error.h"
126
#include "qapi/qapi-commands-qdev.h"
127
#include "qapi/qmp/dispatch.h"
128
@@ -XXX,XX +XXX,XX @@ void qmp_device_del(const char *id, Error **errp)
129
}
157
}
130
}
158
131
159
+int qdev_sync_config(DeviceState *dev, Error **errp)
132
+int qdev_sync_config(DeviceState *dev, Error **errp)
160
+{
133
+{
161
+ DeviceClass *dc = DEVICE_GET_CLASS(dev);
134
+ DeviceClass *dc = DEVICE_GET_CLASS(dev);
...
...
167
+ }
140
+ }
168
+
141
+
169
+ return dc->sync_config(dev, errp);
142
+ return dc->sync_config(dev, errp);
170
+}
143
+}
171
+
144
+
172
+void qmp_x_device_sync_config(const char *id, Error **errp)
145
+void qmp_device_sync_config(const char *id, Error **errp)
173
+{
146
+{
174
+ DeviceState *dev = find_device_state(id, errp);
147
+ DeviceState *dev;
148
+
149
+ /*
150
+ * During migration there is a race between syncing`configuration and
151
+ * migrating it (if migrate first, that target would get outdated version),
152
+ * so let's just not allow it.
153
+ *
154
+ * Moreover, let's not rely on setting up interrupts in paused
155
+ * state, which may be a part of migration process.
156
+ */
157
+
158
+ if (migration_is_running()) {
159
+ error_setg(errp, "Config synchronization is not allowed "
160
+ "during migration");
161
+ return;
162
+ }
163
+
164
+ if (!runstate_is_running()) {
165
+ error_setg(errp, "Config synchronization allowed only in '%s' state, "
166
+ "current state is '%s'", RunState_str(RUN_STATE_RUNNING),
167
+ RunState_str(runstate_get()));
168
+ return;
169
+ }
170
+
171
+ dev = find_device_state(id, true, errp);
175
+ if (!dev) {
172
+ if (!dev) {
176
+ return;
173
+ return;
177
+ }
174
+ }
178
+
175
+
179
+ qdev_sync_config(dev, errp);
176
+ qdev_sync_config(dev, errp);
...
...
diff view generated by jsdifflib
Deleted patch
1
Send a new event when guest reads virtio-pci config after
2
virtio_notify_config() call.
3
1
4
That's useful to check that guest fetched modified config, for example
5
after resizing disk backend.
6
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
8
---
9
hw/virtio/virtio-pci.c | 9 +++++++++
10
include/monitor/qdev.h | 1 +
11
monitor/monitor.c | 1 +
12
qapi/qdev.json | 22 ++++++++++++++++++++++
13
softmmu/qdev-monitor.c | 5 +++++
14
5 files changed, 38 insertions(+)
15
16
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/virtio/virtio-pci.c
19
+++ b/hw/virtio/virtio-pci.c
20
@@ -XXX,XX +XXX,XX @@
21
#include "hw/boards.h"
22
#include "hw/virtio/virtio.h"
23
#include "migration/qemu-file-types.h"
24
+#include "monitor/qdev.h"
25
#include "hw/pci/pci.h"
26
#include "hw/pci/pci_bus.h"
27
#include "hw/qdev-properties.h"
28
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
29
}
30
addr -= config;
31
32
+ if (vdev->generation > 0) {
33
+ qdev_config_read_event(DEVICE(proxy));
34
+ }
35
+
36
switch (size) {
37
case 1:
38
val = virtio_config_readb(vdev, addr);
39
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_pci_device_read(void *opaque, hwaddr addr,
40
return UINT64_MAX;
41
}
42
43
+ if (vdev->generation > 0) {
44
+ qdev_config_read_event(DEVICE(proxy));
45
+ }
46
+
47
switch (size) {
48
case 1:
49
val = virtio_config_modern_readb(vdev, addr);
50
diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/include/monitor/qdev.h
53
+++ b/include/monitor/qdev.h
54
@@ -XXX,XX +XXX,XX @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
55
const char *qdev_set_id(DeviceState *dev, char *id, Error **errp);
56
57
void qdev_hotplug_device_on_event(DeviceState *dev);
58
+void qdev_config_read_event(DeviceState *dev);
59
60
DeviceAndPath *qdev_new_device_and_path(DeviceState *dev);
61
62
diff --git a/monitor/monitor.c b/monitor/monitor.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/monitor/monitor.c
65
+++ b/monitor/monitor.c
66
@@ -XXX,XX +XXX,XX @@ static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = {
67
[QAPI_EVENT_QUORUM_FAILURE] = { 1000 * SCALE_MS },
68
[QAPI_EVENT_VSERPORT_CHANGE] = { 1000 * SCALE_MS },
69
[QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE] = { 1000 * SCALE_MS },
70
+ [QAPI_EVENT_X_CONFIG_READ] = { 300 * SCALE_MS },
71
};
72
73
/*
74
diff --git a/qapi/qdev.json b/qapi/qdev.json
75
index XXXXXXX..XXXXXXX 100644
76
--- a/qapi/qdev.json
77
+++ b/qapi/qdev.json
78
@@ -XXX,XX +XXX,XX @@
79
# Since: 8.2
80
##
81
{ 'command': 'x-device-sync-config', 'data': {'id': 'str'} }
82
+
83
+##
84
+# @X_CONFIG_READ:
85
+#
86
+# Emitted whenever guest reads virtio device config after config change.
87
+#
88
+# @device: device name
89
+#
90
+# @path: device path
91
+#
92
+# Since: 5.0.1-24
93
+#
94
+# Example:
95
+#
96
+# <- { "event": "X_CONFIG_READ",
97
+# "data": { "device": "virtio-net-pci-0",
98
+# "path": "/machine/peripheral/virtio-net-pci-0" },
99
+# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
100
+#
101
+##
102
+{ 'event': 'X_CONFIG_READ',
103
+ 'data': { '*device': 'str', 'path': 'str' } }
104
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/softmmu/qdev-monitor.c
107
+++ b/softmmu/qdev-monitor.c
108
@@ -XXX,XX +XXX,XX @@ void qdev_hotplug_device_on_event(DeviceState *dev)
109
dev->device_on_event_sent = true;
110
qapi_event_send_x_device_on(dev->id, dev->canonical_path);
111
}
112
+
113
+void qdev_config_read_event(DeviceState *dev)
114
+{
115
+ qapi_event_send_x_config_read(dev->id, dev->canonical_path);
116
+}
117
--
118
2.34.1
diff view generated by jsdifflib