#include <asm/rtas.h>
#include "pseries.h"
#include "vas.h" /* vas_migration_handler() */
+#include "papr-hvpipe.h" /* hvpipe_migration_handler() */
#include "../../kernel/cacheinfo.h"
static struct kobject *mobility_kobj;
* by closing VAS windows at the beginning of this function.
*/
vas_migration_handler(VAS_SUSPEND);
+ hvpipe_migration_handler(HVPIPE_SUSPEND);
ret = wait_for_vasi_session_suspending(handle);
if (ret)
out:
vas_migration_handler(VAS_RESUME);
+ hvpipe_migration_handler(HVPIPE_RESUME);
return ret;
}
static struct workqueue_struct *papr_hvpipe_wq;
static struct work_struct *papr_hvpipe_work;
static int hvpipe_check_exception_token;
+static bool hvpipe_feature;
/*
* New PowerPC FW provides support for partitions and various
unsigned long ret, len;
__be64 *area_be;
+ /*
+ * Return -ENXIO during migration
+ */
+ if (!hvpipe_feature)
+ return -ENXIO;
+
if (!src_info)
return -EIO;
struct papr_hvpipe_hdr hdr;
long ret;
+ /*
+ * Return -ENXIO during migration
+ */
+ if (!hvpipe_feature)
+ return -ENXIO;
+
if (!src_info)
return -EIO;
{
struct hvpipe_source_info *src_info = filp->private_data;
+ /*
+ * HVPIPE is disabled during SUSPEND and enabled after migration.
+ * So return POLLRDHUP during migration
+ */
+ if (!hvpipe_feature)
+ return POLLRDHUP;
+
if (!src_info)
return POLLNVAL;
u32 srcID;
long ret;
+ /*
+ * Return -ENXIO during migration
+ */
+ if (!hvpipe_feature)
+ return -ENXIO;
+
if (get_user(srcID, argp))
return -EFAULT;
return 0;
}
+void hvpipe_migration_handler(int action)
+{
+ pr_info("hvpipe migration event %d\n", action);
+
+ /*
+ * HVPIPE is not used (Failed to create /dev/papr-hvpipe).
+ * So nothing to do for migration.
+ */
+ if (!papr_hvpipe_work)
+ return;
+
+ switch (action) {
+ case HVPIPE_SUSPEND:
+ if (hvpipe_feature) {
+ /*
+ * Disable hvpipe_feature to the user space.
+ * It will be enabled with RESUME event.
+ */
+ hvpipe_feature = false;
+ /*
+ * set system parameter hvpipe 'disable'
+ */
+ set_hvpipe_sys_param(0);
+ }
+ break;
+ case HVPIPE_RESUME:
+ /*
+ * set system parameter hvpipe 'enable'
+ */
+ if (!set_hvpipe_sys_param(1))
+ hvpipe_feature = true;
+ else
+ pr_err("hvpipe is not enabled after migration\n");
+
+ break;
+ }
+}
+
static const struct file_operations papr_hvpipe_ops = {
.unlocked_ioctl = papr_hvpipe_dev_ioctl,
};
if (!ret) {
pr_info("hvpipe feature is enabled\n");
+ hvpipe_feature = true;
return 0;
}
#define HVPIPE_HDR_LEN sizeof(struct papr_hvpipe_hdr)
+enum hvpipe_migrate_action {
+ HVPIPE_SUSPEND,
+ HVPIPE_RESUME,
+};
+
struct hvpipe_source_info {
struct list_head list; /* list of sources */
u32 srcID;
/* with specified src ID */
};
+void hvpipe_migration_handler(int action);
#endif /* _PAPR_HVPIPE_H */