From 7c9db6a2e3082b41af3e62b241d49553f5bb8492 Mon Sep 17 00:00:00 2001
From: Wei Gao <gaowei66@huawei.com>
Date: Wed, 18 Aug 2021 14:30:08 +0800
Subject: [PATCH 2/8] migration: fix an error during migration interface on
 aarch64.

Change the order of GICv3 device register to the end. Because it rely on
vcpu_init if boot with multi vcpu.

Signed-off-by: Wei Gao <gaowei66@huawei.com>
---
 .../src/interrupt_controller/aarch64/gicv3.rs    |  3 ++-
 hypervisor/src/kvm/mod.rs                        |  1 +
 machine/src/lib.rs                               |  2 +-
 migration/src/manager.rs                         | 16 ++++++++++++----
 4 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/devices/src/interrupt_controller/aarch64/gicv3.rs b/devices/src/interrupt_controller/aarch64/gicv3.rs
index 3303b32..6559e73 100644
--- a/devices/src/interrupt_controller/aarch64/gicv3.rs
+++ b/devices/src/interrupt_controller/aarch64/gicv3.rs
@@ -389,13 +389,14 @@ impl GICDevice for GICv3 {
         gic_conf: &GICConfig,
     ) -> Result<Arc<dyn GICDevice + std::marker::Send + std::marker::Sync>> {
         let gicv3 = Arc::new(GICv3::new(gic_conf)?);
-        MigrationManager::register_device_instance(GICv3State::descriptor(), gicv3.clone());
         if gicv3.its_dev.is_some() {
             MigrationManager::register_device_instance(
                 GICv3ItsState::descriptor(),
                 gicv3.its_dev.as_ref().unwrap().clone(),
+                true,
             );
         }
+        MigrationManager::register_device_instance(GICv3State::descriptor(), gicv3.clone(), true);
 
         Ok(gicv3)
     }
diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs
index 5b5be94..19193db 100644
--- a/hypervisor/src/kvm/mod.rs
+++ b/hypervisor/src/kvm/mod.rs
@@ -60,6 +60,7 @@ impl KVMFds {
         migration::MigrationManager::register_device_instance(
             state::KvmDeviceState::descriptor(),
             Arc::new(state::KvmDevice {}),
+            false,
         );
 
         kvm_fds
diff --git a/machine/src/lib.rs b/machine/src/lib.rs
index 8a095b3..9eb3039 100644
--- a/machine/src/lib.rs
+++ b/machine/src/lib.rs
@@ -233,7 +233,7 @@ pub trait MachineOps {
             ));
             cpus.push(cpu.clone());
 
-            MigrationManager::register_device_instance(cpu::ArchCPU::descriptor(), cpu);
+            MigrationManager::register_device_instance(cpu::ArchCPU::descriptor(), cpu, false);
         }
 
         if let Some(boot_config) = boot_cfg {
diff --git a/migration/src/manager.rs b/migration/src/manager.rs
index 480b59b..7ec4767 100644
--- a/migration/src/manager.rs
+++ b/migration/src/manager.rs
@@ -162,14 +162,22 @@ impl MigrationManager {
     ///
     /// * `device_desc` - The `DeviceStateDesc` of device instance.
     /// * `entry` - Device instance with migratable interface.
-    pub fn register_device_instance<T>(device_desc: DeviceStateDesc, device_entry: Arc<T>)
-    where
+    /// * `reverse` - Register device in order or in the reverse order.
+    pub fn register_device_instance<T>(
+        device_desc: DeviceStateDesc,
+        device_entry: Arc<T>,
+        reverse: bool,
+    ) where
         T: MigrationHook + Sync + Send + 'static,
     {
         Self::register_device_desc(device_desc);
 
         let entry = MigrationEntry::Safe(device_entry);
-        let nr_entry = Self::entry_db_len();
+        let nr_entry = if reverse {
+            !0 - Self::entry_db_len()
+        } else {
+            Self::entry_db_len()
+        };
 
         MIGRATION_MANAGER
             .entry
@@ -333,7 +341,7 @@ mod tests {
         let device_v2 = Arc::new(DeviceV2::default());
         let device_v2_mutex = Arc::new(Mutex::new(DeviceV2::default()));
 
-        MigrationManager::register_device_instance(DeviceV1State::descriptor(), device_v1);
+        MigrationManager::register_device_instance(DeviceV1State::descriptor(), device_v1, false);
         MigrationManager::register_memory_instance(device_v2);
         MigrationManager::register_device_instance_mutex(
             DeviceV2State::descriptor(),
-- 
2.25.1

