* same fault IRQ is not freed by the OS before.
         */
        mutex_lock(&vas_pseries_mutex);
-       if (migration_in_progress)
+       if (migration_in_progress) {
                rc = -EBUSY;
-       else
+       } else {
                rc = allocate_setup_window(txwin, (u64 *)&domain[0],
                                   cop_feat_caps->win_type);
+               if (!rc)
+                       caps->nr_open_wins_progress++;
+       }
+
        mutex_unlock(&vas_pseries_mutex);
        if (rc)
                goto out;
                goto out_free;
 
        txwin->win_type = cop_feat_caps->win_type;
-       mutex_lock(&vas_pseries_mutex);
+
        /*
+        * The migration SUSPEND thread sets migration_in_progress and
+        * closes all open windows from the list. But the window is
+        * added to the list after open and modify HCALLs. So possible
+        * that migration_in_progress is set before modify HCALL which
+        * may cause some windows are still open when the hypervisor
+        * initiates the migration.
+        * So checks the migration_in_progress flag again and close all
+        * open windows.
+        *
         * Possible to lose the acquired credit with DLPAR core
         * removal after the window is opened. So if there are any
         * closed windows (means with lost credits), do not give new
         * after the existing windows are reopened when credits are
         * available.
         */
-       if (!caps->nr_close_wins) {
+       mutex_lock(&vas_pseries_mutex);
+       if (!caps->nr_close_wins && !migration_in_progress) {
                list_add(&txwin->win_list, &caps->list);
                caps->nr_open_windows++;
+               caps->nr_open_wins_progress--;
                mutex_unlock(&vas_pseries_mutex);
                vas_user_win_add_mm_context(&txwin->vas_win.task_ref);
                return &txwin->vas_win;
         */
        free_irq_setup(txwin);
        h_deallocate_vas_window(txwin->vas_win.winid);
+       /*
+        * Hold mutex and reduce nr_open_wins_progress counter.
+        */
+       mutex_lock(&vas_pseries_mutex);
+       caps->nr_open_wins_progress--;
+       mutex_unlock(&vas_pseries_mutex);
 out:
        atomic_dec(&cop_feat_caps->nr_used_credits);
        kfree(txwin);
        struct vas_caps *vcaps;
        int i, rc = 0;
 
+       pr_info("VAS migration event %d\n", action);
+
        /*
         * NX-GZIP is not enabled. Nothing to do for migration.
         */
        if (!copypaste_feat)
                return rc;
 
-       mutex_lock(&vas_pseries_mutex);
-
        if (action == VAS_SUSPEND)
                migration_in_progress = true;
        else
 
                switch (action) {
                case VAS_SUSPEND:
+                       mutex_lock(&vas_pseries_mutex);
                        rc = reconfig_close_windows(vcaps, vcaps->nr_open_windows,
                                                        true);
+                       /*
+                        * Windows are included in the list after successful
+                        * open. So wait for closing these in-progress open
+                        * windows in vas_allocate_window() which will be
+                        * done if the migration_in_progress is set.
+                        */
+                       while (vcaps->nr_open_wins_progress) {
+                               mutex_unlock(&vas_pseries_mutex);
+                               msleep(10);
+                               mutex_lock(&vas_pseries_mutex);
+                       }
+                       mutex_unlock(&vas_pseries_mutex);
                        break;
                case VAS_RESUME:
+                       mutex_lock(&vas_pseries_mutex);
                        atomic_set(&caps->nr_total_credits, new_nr_creds);
                        rc = reconfig_open_windows(vcaps, new_nr_creds, true);
+                       mutex_unlock(&vas_pseries_mutex);
                        break;
                default:
                        /* should not happen */
                        goto out;
        }
 
+       pr_info("VAS migration event (%d) successful\n", action);
+
 out:
-       mutex_unlock(&vas_pseries_mutex);
        return rc;
 }