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