summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/mobility.c
diff options
context:
space:
mode:
authorNathan Lynch <nathanl@linux.ibm.com>2020-12-07 15:51:45 -0600
committerMichael Ellerman <mpe@ellerman.id.au>2020-12-08 21:40:58 +1100
commit37cddc7d6cf4568a7fb69aeff6f26e4c8a3bc0f7 (patch)
treed703b5ccacacc10e8c7b01687e8ff9a29a008710 /arch/powerpc/platforms/pseries/mobility.c
parent9327dc0aeef36a3cbb9d94f79b79cc4f91ff8a41 (diff)
downloadlinux-37cddc7d6cf4568a7fb69aeff6f26e4c8a3bc0f7.tar.bz2
powerpc/pseries/mobility: signal suspend cancellation to platform
If we're returning an error to user space, use H_VASI_SIGNAL to send a cancellation request to the platform. This isn't strictly required but it communicates that Linux will not attempt to complete the suspend, which allows the various entities involved to promptly end the operation in progress. Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20201207215200.1785968-14-nathanl@linux.ibm.com
Diffstat (limited to 'arch/powerpc/platforms/pseries/mobility.c')
-rw-r--r--arch/powerpc/platforms/pseries/mobility.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 5a3951626a96..f234a7ed87aa 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -513,6 +513,35 @@ static int do_join(void *arg)
return ret;
}
+/*
+ * Abort reason code byte 0. We use only the 'Migrating partition' value.
+ */
+enum vasi_aborting_entity {
+ ORCHESTRATOR = 1,
+ VSP_SOURCE = 2,
+ PARTITION_FIRMWARE = 3,
+ PLATFORM_FIRMWARE = 4,
+ VSP_TARGET = 5,
+ MIGRATING_PARTITION = 6,
+};
+
+static void pseries_cancel_migration(u64 handle, int err)
+{
+ u32 reason_code;
+ u32 detail;
+ u8 entity;
+ long hvrc;
+
+ entity = MIGRATING_PARTITION;
+ detail = abs(err) & 0xffffff;
+ reason_code = (entity << 24) | detail;
+
+ hvrc = plpar_hcall_norets(H_VASI_SIGNAL, handle,
+ H_VASI_SIGNAL_CANCEL, reason_code);
+ if (hvrc)
+ pr_err("H_VASI_SIGNAL error: %ld\n", hvrc);
+}
+
static int pseries_migrate_partition(u64 handle)
{
atomic_t counter = ATOMIC_INIT(0);
@@ -525,6 +554,8 @@ static int pseries_migrate_partition(u64 handle)
ret = stop_machine(do_join, &counter, cpu_online_mask);
if (ret == 0)
post_mobility_fixup();
+ else
+ pseries_cancel_migration(handle, ret);
return ret;
}