Allow to do finalize and abort from kernel modules, so LUO could drive the KHO sequence via its own state machine. Signed-off-by: Pasha Tatashin --- include/linux/kexec_handover.h | 15 +++++++++ kernel/kexec_handover.c | 56 ++++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h index 348844cffb13..f98565def593 100644 --- a/include/linux/kexec_handover.h +++ b/include/linux/kexec_handover.h @@ -54,6 +54,10 @@ void kho_memory_init(void); void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_phys, u64 scratch_len); + +int kho_finalize(void); +int kho_abort(void); + #else static inline bool kho_is_enabled(void) { @@ -104,6 +108,17 @@ static inline void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_phys, u64 scratch_len) { } + +static inline int kho_finalize(void) +{ + return -EOPNOTSUPP; +} + +static inline int kho_abort(void) +{ + return -EOPNOTSUPP; +} + #endif /* CONFIG_KEXEC_HANDOVER */ #endif /* LINUX_KEXEC_HANDOVER_H */ diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c index c2b7e8b86db0..2c22a9f3b278 100644 --- a/kernel/kexec_handover.c +++ b/kernel/kexec_handover.c @@ -757,7 +757,7 @@ static int kho_out_update_debugfs_fdt(void) return err; } -static int kho_abort(void) +static int __kho_abort(void) { int err; unsigned long order; @@ -790,7 +790,33 @@ static int kho_abort(void) return err; } -static int kho_finalize(void) +int kho_abort(void) +{ + int ret = 0; + + if (!kho_enable) + return -EOPNOTSUPP; + + mutex_lock(&kho_out.lock); + + if (!kho_out.finalized) { + ret = -ENOENT; + goto unlock; + } + + ret = __kho_abort(); + if (ret) + goto unlock; + + kho_out.finalized = false; + ret = kho_out_update_debugfs_fdt(); + +unlock: + mutex_unlock(&kho_out.lock); + return ret; +} + +static int __kho_finalize(void) { int err = 0; u64 *preserved_mem_map; @@ -839,6 +865,32 @@ static int kho_finalize(void) return err; } +int kho_finalize(void) +{ + int ret = 0; + + if (!kho_enable) + return -EOPNOTSUPP; + + mutex_lock(&kho_out.lock); + + if (kho_out.finalized) { + ret = -EEXIST; + goto unlock; + } + + ret = __kho_finalize(); + if (ret) + goto unlock; + + kho_out.finalized = true; + ret = kho_out_update_debugfs_fdt(); + +unlock: + mutex_unlock(&kho_out.lock); + return ret; +} + static int kho_out_finalize_get(void *data, u64 *val) { mutex_lock(&kho_out.lock); -- 2.50.1.565.gc32cd1483b-goog