diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index 62bd8e2d5d4c..95fe802ccdfd 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -28,6 +28,7 @@ #include #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; @@ -744,6 +745,7 @@ static int pseries_migrate_partition(u64 handle) * 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) @@ -770,6 +772,7 @@ static int pseries_migrate_partition(u64 handle) out: vas_migration_handler(VAS_RESUME); + hvpipe_migration_handler(HVPIPE_RESUME); return ret; } diff --git a/arch/powerpc/platforms/pseries/papr-hvpipe.c b/arch/powerpc/platforms/pseries/papr-hvpipe.c index 65368dbb134b..21a2f447c43f 100644 --- a/arch/powerpc/platforms/pseries/papr-hvpipe.c +++ b/arch/powerpc/platforms/pseries/papr-hvpipe.c @@ -27,6 +27,7 @@ static unsigned char hvpipe_ras_buf[RTAS_ERROR_LOG_MAX]; 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 @@ -233,6 +234,12 @@ static ssize_t papr_hvpipe_handle_write(struct file *file, unsigned long ret, len; __be64 *area_be; + /* + * Return -ENXIO during migration + */ + if (!hvpipe_feature) + return -ENXIO; + if (!src_info) return -EIO; @@ -323,6 +330,12 @@ static ssize_t papr_hvpipe_handle_read(struct file *file, struct papr_hvpipe_hdr hdr; long ret; + /* + * Return -ENXIO during migration + */ + if (!hvpipe_feature) + return -ENXIO; + if (!src_info) return -EIO; @@ -399,6 +412,13 @@ static __poll_t papr_hvpipe_handle_poll(struct file *filp, { 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; @@ -539,6 +559,12 @@ static long papr_hvpipe_dev_ioctl(struct file *filp, unsigned int ioctl, u32 srcID; long ret; + /* + * Return -ENXIO during migration + */ + if (!hvpipe_feature) + return -ENXIO; + if (get_user(srcID, argp)) return -EFAULT; @@ -697,6 +723,44 @@ static int __init enable_hvpipe_IRQ(void) 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, }; @@ -740,6 +804,7 @@ static int __init papr_hvpipe_init(void) if (!ret) { pr_info("hvpipe feature is enabled\n"); + hvpipe_feature = true; return 0; } diff --git a/arch/powerpc/platforms/pseries/papr-hvpipe.h b/arch/powerpc/platforms/pseries/papr-hvpipe.h index aab7f77e087d..c343f4230865 100644 --- a/arch/powerpc/platforms/pseries/papr-hvpipe.h +++ b/arch/powerpc/platforms/pseries/papr-hvpipe.h @@ -11,6 +11,11 @@ #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; @@ -33,4 +38,5 @@ struct hvpipe_event_buf { /* with specified src ID */ }; +void hvpipe_migration_handler(int action); #endif /* _PAPR_HVPIPE_H */