1e4c2c0ffSHans de Goede // SPDX-License-Identifier: GPL-2.0 2e4c2c0ffSHans de Goede 3e4c2c0ffSHans de Goede #include <linux/efi_embedded_fw.h> 4e4c2c0ffSHans de Goede #include <linux/property.h> 5e4c2c0ffSHans de Goede #include <linux/security.h> 6e4c2c0ffSHans de Goede #include <linux/vmalloc.h> 7e4c2c0ffSHans de Goede 8e4c2c0ffSHans de Goede #include "fallback.h" 9e4c2c0ffSHans de Goede #include "firmware.h" 10e4c2c0ffSHans de Goede firmware_fallback_platform(struct fw_priv * fw_priv)11*89287c16SKees Cookint firmware_fallback_platform(struct fw_priv *fw_priv) 12e4c2c0ffSHans de Goede { 13e4c2c0ffSHans de Goede const u8 *data; 14e4c2c0ffSHans de Goede size_t size; 15e4c2c0ffSHans de Goede int rc; 16e4c2c0ffSHans de Goede 17*89287c16SKees Cook if (!(fw_priv->opt_flags & FW_OPT_FALLBACK_PLATFORM)) 18e4c2c0ffSHans de Goede return -ENOENT; 19e4c2c0ffSHans de Goede 204f2d99b0SKees Cook rc = security_kernel_load_data(LOADING_FIRMWARE, true); 21e4c2c0ffSHans de Goede if (rc) 22e4c2c0ffSHans de Goede return rc; 23e4c2c0ffSHans de Goede 24e4c2c0ffSHans de Goede rc = efi_get_embedded_fw(fw_priv->fw_name, &data, &size); 25e4c2c0ffSHans de Goede if (rc) 26e4c2c0ffSHans de Goede return rc; /* rc == -ENOENT when the fw was not found */ 27e4c2c0ffSHans de Goede 284fb60b15SKees Cook if (fw_priv->data && size > fw_priv->allocated_size) 294fb60b15SKees Cook return -ENOMEM; 304f2d99b0SKees Cook 314f2d99b0SKees Cook rc = security_kernel_post_load_data((u8 *)data, size, LOADING_FIRMWARE, 324f2d99b0SKees Cook "platform"); 334f2d99b0SKees Cook if (rc) 344f2d99b0SKees Cook return rc; 354f2d99b0SKees Cook 364fb60b15SKees Cook if (!fw_priv->data) 37e4c2c0ffSHans de Goede fw_priv->data = vmalloc(size); 38e4c2c0ffSHans de Goede if (!fw_priv->data) 39e4c2c0ffSHans de Goede return -ENOMEM; 40e4c2c0ffSHans de Goede 41e4c2c0ffSHans de Goede memcpy(fw_priv->data, data, size); 42e4c2c0ffSHans de Goede fw_priv->size = size; 43e4c2c0ffSHans de Goede fw_state_done(fw_priv); 44e4c2c0ffSHans de Goede return 0; 45e4c2c0ffSHans de Goede } 46