Commit 71960fe1 authored by Pasha Tatashin's avatar Pasha Tatashin Committed by Andrew Morton
Browse files

kho: simplify serialization and remove __kho_abort

Currently, __kho_finalize() performs memory serialization in the middle of
FDT construction.  If FDT construction fails later, the function must
manually clean up the serialized memory via __kho_abort().

Refactor __kho_finalize() to perform kho_mem_serialize() only after the
FDT has been successfully constructed and finished.  This reordering has
two benefits:
1. It avoids expensive serialization work if FDT generation fails.
2. It removes the need for cleanup in the FDT error path.

As a result, the internal helper __kho_abort() is no longer needed for
internal error handling.  Inline its remaining logic (cleanup of the
preserved memory map) directly into kho_abort() and remove the helper.

Link: https://lkml.kernel.org/r/20251114190002.3311679-8-pasha.tatashin@soleen.com


Signed-off-by: default avatarPasha Tatashin <pasha.tatashin@soleen.com>
Reviewed-by: default avatarMike Rapoport (Microsoft) <rppt@kernel.org>
Reviewed-by: default avatarPratyush Yadav <pratyush@kernel.org>
Cc: Alexander Graf <graf@amazon.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Baoquan He <bhe@redhat.com>
Cc: Coiby Xu <coxu@redhat.com>
Cc: Dave Vasilevsky <dave@vasilevsky.ca>
Cc: Eric Biggers <ebiggers@google.com>
Cc: Kees Cook <kees@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent e268689a
Loading
Loading
Loading
Loading
+17 −24
Original line number Diff line number Diff line
@@ -1214,14 +1214,6 @@ void kho_restore_free(void *mem)
}
EXPORT_SYMBOL_GPL(kho_restore_free);

static void __kho_abort(void)
{
	if (kho_out.preserved_mem_map) {
		kho_mem_ser_free(kho_out.preserved_mem_map);
		kho_out.preserved_mem_map = NULL;
	}
}

int kho_abort(void)
{
	if (!kho_enable)
@@ -1231,7 +1223,8 @@ int kho_abort(void)
	if (!kho_out.finalized)
		return -ENOENT;

	__kho_abort();
	kho_mem_ser_free(kho_out.preserved_mem_map);
	kho_out.preserved_mem_map = NULL;
	kho_out.finalized = false;

	return 0;
@@ -1239,12 +1232,12 @@ int kho_abort(void)

static int __kho_finalize(void)
{
	int err = 0;
	u64 *preserved_mem_map;
	void *root = kho_out.fdt;
	struct kho_sub_fdt *fdt;
	u64 *preserved_mem_map;
	int err;

	err |= fdt_create(root, PAGE_SIZE);
	err = fdt_create(root, PAGE_SIZE);
	err |= fdt_finish_reservemap(root);
	err |= fdt_begin_node(root, "");
	err |= fdt_property_string(root, "compatible", KHO_FDT_COMPATIBLE);
@@ -1257,13 +1250,7 @@ static int __kho_finalize(void)
					sizeof(*preserved_mem_map),
					(void **)&preserved_mem_map);
	if (err)
		goto abort;

	err = kho_mem_serialize(&kho_out);
	if (err)
		goto abort;

	*preserved_mem_map = (u64)virt_to_phys(kho_out.preserved_mem_map);
		goto err_exit;

	mutex_lock(&kho_out.fdts_lock);
	list_for_each_entry(fdt, &kho_out.sub_fdts, l) {
@@ -1277,13 +1264,19 @@ static int __kho_finalize(void)

	err |= fdt_end_node(root);
	err |= fdt_finish(root);
	if (err)
		goto err_exit;

abort:
	if (err) {
		pr_err("Failed to convert KHO state tree: %d\n", err);
		__kho_abort();
	}
	err = kho_mem_serialize(&kho_out);
	if (err)
		goto err_exit;

	*preserved_mem_map = (u64)virt_to_phys(kho_out.preserved_mem_map);

	return 0;

err_exit:
	pr_err("Failed to convert KHO state tree: %d\n", err);
	return err;
}