162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#include <linux/efi_embedded_fw.h>
462306a36Sopenharmony_ci#include <linux/property.h>
562306a36Sopenharmony_ci#include <linux/security.h>
662306a36Sopenharmony_ci#include <linux/vmalloc.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "fallback.h"
962306a36Sopenharmony_ci#include "firmware.h"
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciint firmware_fallback_platform(struct fw_priv *fw_priv)
1262306a36Sopenharmony_ci{
1362306a36Sopenharmony_ci	const u8 *data;
1462306a36Sopenharmony_ci	size_t size;
1562306a36Sopenharmony_ci	int rc;
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci	if (!(fw_priv->opt_flags & FW_OPT_FALLBACK_PLATFORM))
1862306a36Sopenharmony_ci		return -ENOENT;
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci	rc = security_kernel_load_data(LOADING_FIRMWARE, true);
2162306a36Sopenharmony_ci	if (rc)
2262306a36Sopenharmony_ci		return rc;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	rc = efi_get_embedded_fw(fw_priv->fw_name, &data, &size);
2562306a36Sopenharmony_ci	if (rc)
2662306a36Sopenharmony_ci		return rc; /* rc == -ENOENT when the fw was not found */
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci	if (fw_priv->data && size > fw_priv->allocated_size)
2962306a36Sopenharmony_ci		return -ENOMEM;
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	rc = security_kernel_post_load_data((u8 *)data, size, LOADING_FIRMWARE,
3262306a36Sopenharmony_ci						"platform");
3362306a36Sopenharmony_ci	if (rc)
3462306a36Sopenharmony_ci		return rc;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	if (!fw_priv->data)
3762306a36Sopenharmony_ci		fw_priv->data = vmalloc(size);
3862306a36Sopenharmony_ci	if (!fw_priv->data)
3962306a36Sopenharmony_ci		return -ENOMEM;
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	memcpy(fw_priv->data, data, size);
4262306a36Sopenharmony_ci	fw_priv->size = size;
4362306a36Sopenharmony_ci	fw_state_done(fw_priv);
4462306a36Sopenharmony_ci	return 0;
4562306a36Sopenharmony_ci}
46