virtio-iommu: Support migration
Add Migration support. We rely on recently added gtree and qlist migration. We only migrate the domain gtree. The endpoint gtree is re-constructed in a post-load operation. Signed-off-by: Eric Auger <eric.auger@redhat.com> Acked-by: Peter Xu <peterx@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20200214132745.23392-8-eric.auger@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
a7c1da8adc
commit
bd0ab8702f
@ -643,16 +643,6 @@ static uint64_t virtio_iommu_get_features(VirtIODevice *vdev, uint64_t f,
|
||||
return f;
|
||||
}
|
||||
|
||||
/*
|
||||
* Migration is not yet supported: most of the state consists
|
||||
* of balanced binary trees which are not yet ready for getting
|
||||
* migrated
|
||||
*/
|
||||
static const VMStateDescription vmstate_virtio_iommu_device = {
|
||||
.name = "virtio-iommu-device",
|
||||
.unmigratable = 1,
|
||||
};
|
||||
|
||||
static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
|
||||
{
|
||||
guint ua = GPOINTER_TO_UINT(a);
|
||||
@ -736,9 +726,108 @@ static void virtio_iommu_instance_init(Object *obj)
|
||||
{
|
||||
}
|
||||
|
||||
#define VMSTATE_INTERVAL \
|
||||
{ \
|
||||
.name = "interval", \
|
||||
.version_id = 1, \
|
||||
.minimum_version_id = 1, \
|
||||
.fields = (VMStateField[]) { \
|
||||
VMSTATE_UINT64(low, VirtIOIOMMUInterval), \
|
||||
VMSTATE_UINT64(high, VirtIOIOMMUInterval), \
|
||||
VMSTATE_END_OF_LIST() \
|
||||
} \
|
||||
}
|
||||
|
||||
#define VMSTATE_MAPPING \
|
||||
{ \
|
||||
.name = "mapping", \
|
||||
.version_id = 1, \
|
||||
.minimum_version_id = 1, \
|
||||
.fields = (VMStateField[]) { \
|
||||
VMSTATE_UINT64(phys_addr, VirtIOIOMMUMapping),\
|
||||
VMSTATE_UINT32(flags, VirtIOIOMMUMapping), \
|
||||
VMSTATE_END_OF_LIST() \
|
||||
}, \
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_interval_mapping[2] = {
|
||||
VMSTATE_MAPPING, /* value */
|
||||
VMSTATE_INTERVAL /* key */
|
||||
};
|
||||
|
||||
static int domain_preload(void *opaque)
|
||||
{
|
||||
VirtIOIOMMUDomain *domain = opaque;
|
||||
|
||||
domain->mappings = g_tree_new_full((GCompareDataFunc)interval_cmp,
|
||||
NULL, g_free, g_free);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_endpoint = {
|
||||
.name = "endpoint",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32(id, VirtIOIOMMUEndpoint),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_domain = {
|
||||
.name = "domain",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.pre_load = domain_preload,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32(id, VirtIOIOMMUDomain),
|
||||
VMSTATE_GTREE_V(mappings, VirtIOIOMMUDomain, 1,
|
||||
vmstate_interval_mapping,
|
||||
VirtIOIOMMUInterval, VirtIOIOMMUMapping),
|
||||
VMSTATE_QLIST_V(endpoint_list, VirtIOIOMMUDomain, 1,
|
||||
vmstate_endpoint, VirtIOIOMMUEndpoint, next),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static gboolean reconstruct_endpoints(gpointer key, gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
VirtIOIOMMU *s = (VirtIOIOMMU *)data;
|
||||
VirtIOIOMMUDomain *d = (VirtIOIOMMUDomain *)value;
|
||||
VirtIOIOMMUEndpoint *iter;
|
||||
|
||||
QLIST_FOREACH(iter, &d->endpoint_list, next) {
|
||||
iter->domain = d;
|
||||
g_tree_insert(s->endpoints, GUINT_TO_POINTER(iter->id), iter);
|
||||
}
|
||||
return false; /* continue the domain traversal */
|
||||
}
|
||||
|
||||
static int iommu_post_load(void *opaque, int version_id)
|
||||
{
|
||||
VirtIOIOMMU *s = opaque;
|
||||
|
||||
g_tree_foreach(s->domains, reconstruct_endpoints, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_virtio_iommu_device = {
|
||||
.name = "virtio-iommu-device",
|
||||
.minimum_version_id = 1,
|
||||
.version_id = 1,
|
||||
.post_load = iommu_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_GTREE_DIRECT_KEY_V(domains, VirtIOIOMMU, 1,
|
||||
&vmstate_domain, VirtIOIOMMUDomain),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_virtio_iommu = {
|
||||
.name = "virtio-iommu",
|
||||
.minimum_version_id = 1,
|
||||
.priority = MIG_PRI_IOMMU,
|
||||
.version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_VIRTIO_DEVICE,
|
||||
|
Loading…
Reference in New Issue
Block a user