1 // SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause 2 /* 3 * Copyright(c) 2015, 2016 Intel Corporation. 4 */ 5 6 #include <linux/ctype.h> 7 #include "efivar.h" 8 9 /* GUID for HFI1 variables in EFI */ 10 #define HFI1_EFIVAR_GUID EFI_GUID(0xc50a953e, 0xa8b2, 0x42a6, \ 11 0xbf, 0x89, 0xd3, 0x33, 0xa6, 0xe9, 0xe6, 0xd4) 12 /* largest EFI data size we expect */ 13 #define EFI_DATA_SIZE 4096 14 15 /* 16 * Read the named EFI variable. Return the size of the actual data in *size 17 * and a kmalloc'ed buffer in *return_data. The caller must free the 18 * data. It is guaranteed that *return_data will be NULL and *size = 0 19 * if this routine fails. 20 * 21 * Return 0 on success, -errno on failure. 22 */ 23 static int read_efi_var(const char *name, unsigned long *size, 24 void **return_data) 25 { 26 efi_status_t status; 27 efi_char16_t *uni_name; 28 efi_guid_t guid; 29 unsigned long temp_size; 30 void *temp_buffer; 31 void *data; 32 int i; 33 int ret; 34 35 /* set failure return values */ 36 *size = 0; 37 *return_data = NULL; 38 39 if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) 40 return -EOPNOTSUPP; 41 42 uni_name = kcalloc(strlen(name) + 1, sizeof(efi_char16_t), GFP_KERNEL); 43 temp_buffer = kzalloc(EFI_DATA_SIZE, GFP_KERNEL); 44 45 if (!uni_name || !temp_buffer) { 46 ret = -ENOMEM; 47 goto fail; 48 } 49 50 /* input: the size of the buffer */ 51 temp_size = EFI_DATA_SIZE; 52 53 /* convert ASCII to unicode - it is a 1:1 mapping */ 54 for (i = 0; name[i]; i++) 55 uni_name[i] = name[i]; 56 57 /* need a variable for our GUID */ 58 guid = HFI1_EFIVAR_GUID; 59 60 /* call into EFI runtime services */ 61 status = efi.get_variable( 62 uni_name, 63 &guid, 64 NULL, 65 &temp_size, 66 temp_buffer); 67 68 /* 69 * It would be nice to call efi_status_to_err() here, but that 70 * is in the EFIVAR_FS code and may not be compiled in. 71 * However, even that is insufficient since it does not cover 72 * EFI_BUFFER_TOO_SMALL which could be an important return. 73 * For now, just split out succces or not found. 74 */ 75 ret = status == EFI_SUCCESS ? 0 : 76 status == EFI_NOT_FOUND ? -ENOENT : 77 -EINVAL; 78 if (ret) 79 goto fail; 80 81 /* 82 * We have successfully read the EFI variable into our 83 * temporary buffer. Now allocate a correctly sized 84 * buffer. 85 */ 86 data = kmemdup(temp_buffer, temp_size, GFP_KERNEL); 87 if (!data) { 88 ret = -ENOMEM; 89 goto fail; 90 } 91 92 *size = temp_size; 93 *return_data = data; 94 95 fail: 96 kfree(uni_name); 97 kfree(temp_buffer); 98 99 return ret; 100 } 101 102 /* 103 * Read an HFI1 EFI variable of the form: 104 * <PCIe address>-<kind> 105 * Return an kalloc'ed array and size of the data. 106 * 107 * Returns 0 on success, -errno on failure. 108 */ 109 int read_hfi1_efi_var(struct hfi1_devdata *dd, const char *kind, 110 unsigned long *size, void **return_data) 111 { 112 char prefix_name[64]; 113 char name[64]; 114 int result; 115 int i; 116 117 /* create a common prefix */ 118 snprintf(prefix_name, sizeof(prefix_name), "%04x:%02x:%02x.%x", 119 pci_domain_nr(dd->pcidev->bus), 120 dd->pcidev->bus->number, 121 PCI_SLOT(dd->pcidev->devfn), 122 PCI_FUNC(dd->pcidev->devfn)); 123 snprintf(name, sizeof(name), "%s-%s", prefix_name, kind); 124 result = read_efi_var(name, size, return_data); 125 126 /* 127 * If reading the lowercase EFI variable fail, read the uppercase 128 * variable. 129 */ 130 if (result) { 131 /* Converting to uppercase */ 132 for (i = 0; prefix_name[i]; i++) 133 if (isalpha(prefix_name[i])) 134 prefix_name[i] = toupper(prefix_name[i]); 135 snprintf(name, sizeof(name), "%s-%s", prefix_name, kind); 136 result = read_efi_var(name, size, return_data); 137 } 138 139 return result; 140 } 141