18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#include <linux/efi_embedded_fw.h>
48c2ecf20Sopenharmony_ci#include <linux/property.h>
58c2ecf20Sopenharmony_ci#include <linux/security.h>
68c2ecf20Sopenharmony_ci#include <linux/vmalloc.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include "fallback.h"
98c2ecf20Sopenharmony_ci#include "firmware.h"
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ciint firmware_fallback_platform(struct fw_priv *fw_priv)
128c2ecf20Sopenharmony_ci{
138c2ecf20Sopenharmony_ci	const u8 *data;
148c2ecf20Sopenharmony_ci	size_t size;
158c2ecf20Sopenharmony_ci	int rc;
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci	if (!(fw_priv->opt_flags & FW_OPT_FALLBACK_PLATFORM))
188c2ecf20Sopenharmony_ci		return -ENOENT;
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci	rc = security_kernel_load_data(LOADING_FIRMWARE, true);
218c2ecf20Sopenharmony_ci	if (rc)
228c2ecf20Sopenharmony_ci		return rc;
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci	rc = efi_get_embedded_fw(fw_priv->fw_name, &data, &size);
258c2ecf20Sopenharmony_ci	if (rc)
268c2ecf20Sopenharmony_ci		return rc; /* rc == -ENOENT when the fw was not found */
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	if (fw_priv->data && size > fw_priv->allocated_size)
298c2ecf20Sopenharmony_ci		return -ENOMEM;
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci	rc = security_kernel_post_load_data((u8 *)data, size, LOADING_FIRMWARE,
328c2ecf20Sopenharmony_ci						"platform");
338c2ecf20Sopenharmony_ci	if (rc)
348c2ecf20Sopenharmony_ci		return rc;
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	if (!fw_priv->data)
378c2ecf20Sopenharmony_ci		fw_priv->data = vmalloc(size);
388c2ecf20Sopenharmony_ci	if (!fw_priv->data)
398c2ecf20Sopenharmony_ci		return -ENOMEM;
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	memcpy(fw_priv->data, data, size);
428c2ecf20Sopenharmony_ci	fw_priv->size = size;
438c2ecf20Sopenharmony_ci	fw_state_done(fw_priv);
448c2ecf20Sopenharmony_ci	return 0;
458c2ecf20Sopenharmony_ci}
46