tree: https://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git next head: ff1f49b2ed7c150a69d1537a374c27e9db8acbb0 commit: 19c5678d5c1bad385a1beb8eaa00c9d50f4ce836 [2/3] efi/random: Increase size of firmware supplied randomness config: arm64-defconfig (attached as .config) compiler: aarch64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git checkout 19c5678d5c1bad385a1beb8eaa00c9d50f4ce836 # save the attached .config to linux build tree make.cross ARCH=arm64 All errors (new ones prefixed by >>): In file included from drivers/firmware/efi/libstub/random.c:12:0: drivers/firmware/efi/libstub/random.c: In function 'efi_random_get_seed': >> drivers/firmware/efi/libstub/random.c:163:21: error: 'RANDOM_SEED_SIZE' undeclared (first use in this function) sizeof(*seed) + RANDOM_SEED_SIZE, ^ arch/arm64/include/asm/efi.h:73:60: note: in definition of macro 'efi_call_early' #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) ^~~~~~~~~~~ drivers/firmware/efi/libstub/random.c:163:21: note: each undeclared identifier is reported only once for each function it appears in sizeof(*seed) + RANDOM_SEED_SIZE, ^ arch/arm64/include/asm/efi.h:73:60: note: in definition of macro 'efi_call_early' #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) ^~~~~~~~~~~ vim +/RANDOM_SEED_SIZE +163 drivers/firmware/efi/libstub/random.c e4fbf476 Ard Biesheuvel 2016-01-10 @12 #include <asm/efi.h> e4fbf476 Ard Biesheuvel 2016-01-10 13 e4fbf476 Ard Biesheuvel 2016-01-10 14 #include "efistub.h" e4fbf476 Ard Biesheuvel 2016-01-10 15 e4fbf476 Ard Biesheuvel 2016-01-10 16 struct efi_rng_protocol { e4fbf476 Ard Biesheuvel 2016-01-10 17 efi_status_t (*get_info)(struct efi_rng_protocol *, e4fbf476 Ard Biesheuvel 2016-01-10 18 unsigned long *, efi_guid_t *); e4fbf476 Ard Biesheuvel 2016-01-10 19 efi_status_t (*get_rng)(struct efi_rng_protocol *, e4fbf476 Ard Biesheuvel 2016-01-10 20 efi_guid_t *, unsigned long, u8 *out); e4fbf476 Ard Biesheuvel 2016-01-10 21 }; e4fbf476 Ard Biesheuvel 2016-01-10 22 e4fbf476 Ard Biesheuvel 2016-01-10 23 efi_status_t efi_get_random_bytes(efi_system_table_t *sys_table_arg, e4fbf476 Ard Biesheuvel 2016-01-10 24 unsigned long size, u8 *out) e4fbf476 Ard Biesheuvel 2016-01-10 25 { e4fbf476 Ard Biesheuvel 2016-01-10 26 efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID; e4fbf476 Ard Biesheuvel 2016-01-10 27 efi_status_t status; e4fbf476 Ard Biesheuvel 2016-01-10 28 struct efi_rng_protocol *rng; e4fbf476 Ard Biesheuvel 2016-01-10 29 e4fbf476 Ard Biesheuvel 2016-01-10 30 status = efi_call_early(locate_protocol, &rng_proto, NULL, e4fbf476 Ard Biesheuvel 2016-01-10 31 (void **)&rng); e4fbf476 Ard Biesheuvel 2016-01-10 32 if (status != EFI_SUCCESS) e4fbf476 Ard Biesheuvel 2016-01-10 33 return status; e4fbf476 Ard Biesheuvel 2016-01-10 34 e4fbf476 Ard Biesheuvel 2016-01-10 35 return rng->get_rng(rng, NULL, size, out); e4fbf476 Ard Biesheuvel 2016-01-10 36 } 2ddbfc81 Ard Biesheuvel 2016-01-11 37 2ddbfc81 Ard Biesheuvel 2016-01-11 38 /* 2ddbfc81 Ard Biesheuvel 2016-01-11 39 * Return the number of slots covered by this entry, i.e., the number of 2ddbfc81 Ard Biesheuvel 2016-01-11 40 * addresses it covers that are suitably aligned and supply enough room 2ddbfc81 Ard Biesheuvel 2016-01-11 41 * for the allocation. 2ddbfc81 Ard Biesheuvel 2016-01-11 42 */ 2ddbfc81 Ard Biesheuvel 2016-01-11 43 static unsigned long get_entry_num_slots(efi_memory_desc_t *md, 2ddbfc81 Ard Biesheuvel 2016-01-11 44 unsigned long size, a6a14469 Ard Biesheuvel 2016-11-12 45 unsigned long align_shift) 2ddbfc81 Ard Biesheuvel 2016-01-11 46 { a6a14469 Ard Biesheuvel 2016-11-12 47 unsigned long align = 1UL << align_shift; 018edcfa Ard Biesheuvel 2016-11-24 48 u64 first_slot, last_slot, region_end; 2ddbfc81 Ard Biesheuvel 2016-01-11 49 2ddbfc81 Ard Biesheuvel 2016-01-11 50 if (md->type != EFI_CONVENTIONAL_MEMORY) 2ddbfc81 Ard Biesheuvel 2016-01-11 51 return 0; 2ddbfc81 Ard Biesheuvel 2016-01-11 52 018edcfa Ard Biesheuvel 2016-11-24 53 region_end = min((u64)ULONG_MAX, md->phys_addr + md->num_pages*EFI_PAGE_SIZE - 1); 2ddbfc81 Ard Biesheuvel 2016-01-11 54 018edcfa Ard Biesheuvel 2016-11-24 55 first_slot = round_up(md->phys_addr, align); 018edcfa Ard Biesheuvel 2016-11-24 56 last_slot = round_down(region_end - size + 1, align); 018edcfa Ard Biesheuvel 2016-11-24 57 018edcfa Ard Biesheuvel 2016-11-24 58 if (first_slot > last_slot) 2ddbfc81 Ard Biesheuvel 2016-01-11 59 return 0; 2ddbfc81 Ard Biesheuvel 2016-01-11 60 018edcfa Ard Biesheuvel 2016-11-24 61 return ((unsigned long)(last_slot - first_slot) >> align_shift) + 1; 2ddbfc81 Ard Biesheuvel 2016-01-11 62 } 2ddbfc81 Ard Biesheuvel 2016-01-11 63 2ddbfc81 Ard Biesheuvel 2016-01-11 64 /* 2ddbfc81 Ard Biesheuvel 2016-01-11 65 * The UEFI memory descriptors have a virtual address field that is only used 2ddbfc81 Ard Biesheuvel 2016-01-11 66 * when installing the virtual mapping using SetVirtualAddressMap(). Since it 2ddbfc81 Ard Biesheuvel 2016-01-11 67 * is unused here, we can reuse it to keep track of each descriptor's slot 2ddbfc81 Ard Biesheuvel 2016-01-11 68 * count. 2ddbfc81 Ard Biesheuvel 2016-01-11 69 */ 2ddbfc81 Ard Biesheuvel 2016-01-11 70 #define MD_NUM_SLOTS(md) ((md)->virt_addr) 2ddbfc81 Ard Biesheuvel 2016-01-11 71 2ddbfc81 Ard Biesheuvel 2016-01-11 72 efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg, 2ddbfc81 Ard Biesheuvel 2016-01-11 73 unsigned long size, 2ddbfc81 Ard Biesheuvel 2016-01-11 74 unsigned long align, 2ddbfc81 Ard Biesheuvel 2016-01-11 75 unsigned long *addr, 2ddbfc81 Ard Biesheuvel 2016-01-11 76 unsigned long random_seed) 2ddbfc81 Ard Biesheuvel 2016-01-11 77 { 2ddbfc81 Ard Biesheuvel 2016-01-11 78 unsigned long map_size, desc_size, total_slots = 0, target_slot; dadb57ab Jeffrey Hugo 2016-08-29 79 unsigned long buff_size; 2ddbfc81 Ard Biesheuvel 2016-01-11 80 efi_status_t status; 2ddbfc81 Ard Biesheuvel 2016-01-11 81 efi_memory_desc_t *memory_map; 2ddbfc81 Ard Biesheuvel 2016-01-11 82 int map_offset; dadb57ab Jeffrey Hugo 2016-08-29 83 struct efi_boot_memmap map; 2ddbfc81 Ard Biesheuvel 2016-01-11 84 dadb57ab Jeffrey Hugo 2016-08-29 85 map.map = &memory_map; dadb57ab Jeffrey Hugo 2016-08-29 86 map.map_size = &map_size; dadb57ab Jeffrey Hugo 2016-08-29 87 map.desc_size = &desc_size; dadb57ab Jeffrey Hugo 2016-08-29 88 map.desc_ver = NULL; dadb57ab Jeffrey Hugo 2016-08-29 89 map.key_ptr = NULL; dadb57ab Jeffrey Hugo 2016-08-29 90 map.buff_size = &buff_size; dadb57ab Jeffrey Hugo 2016-08-29 91 dadb57ab Jeffrey Hugo 2016-08-29 92 status = efi_get_memory_map(sys_table_arg, &map); 2ddbfc81 Ard Biesheuvel 2016-01-11 93 if (status != EFI_SUCCESS) 2ddbfc81 Ard Biesheuvel 2016-01-11 94 return status; 2ddbfc81 Ard Biesheuvel 2016-01-11 95 2ddbfc81 Ard Biesheuvel 2016-01-11 96 if (align < EFI_ALLOC_ALIGN) 2ddbfc81 Ard Biesheuvel 2016-01-11 97 align = EFI_ALLOC_ALIGN; 2ddbfc81 Ard Biesheuvel 2016-01-11 98 2ddbfc81 Ard Biesheuvel 2016-01-11 99 /* count the suitable slots in each memory map entry */ 2ddbfc81 Ard Biesheuvel 2016-01-11 100 for (map_offset = 0; map_offset < map_size; map_offset += desc_size) { 2ddbfc81 Ard Biesheuvel 2016-01-11 101 efi_memory_desc_t *md = (void *)memory_map + map_offset; 2ddbfc81 Ard Biesheuvel 2016-01-11 102 unsigned long slots; 2ddbfc81 Ard Biesheuvel 2016-01-11 103 a6a14469 Ard Biesheuvel 2016-11-12 104 slots = get_entry_num_slots(md, size, ilog2(align)); 2ddbfc81 Ard Biesheuvel 2016-01-11 105 MD_NUM_SLOTS(md) = slots; 2ddbfc81 Ard Biesheuvel 2016-01-11 106 total_slots += slots; 2ddbfc81 Ard Biesheuvel 2016-01-11 107 } 2ddbfc81 Ard Biesheuvel 2016-01-11 108 2ddbfc81 Ard Biesheuvel 2016-01-11 109 /* find a random number between 0 and total_slots */ 2ddbfc81 Ard Biesheuvel 2016-01-11 110 target_slot = (total_slots * (u16)random_seed) >> 16; 2ddbfc81 Ard Biesheuvel 2016-01-11 111 2ddbfc81 Ard Biesheuvel 2016-01-11 112 /* 2ddbfc81 Ard Biesheuvel 2016-01-11 113 * target_slot is now a value in the range [0, total_slots), and so 2ddbfc81 Ard Biesheuvel 2016-01-11 114 * it corresponds with exactly one of the suitable slots we recorded 2ddbfc81 Ard Biesheuvel 2016-01-11 115 * when iterating over the memory map the first time around. 2ddbfc81 Ard Biesheuvel 2016-01-11 116 * 2ddbfc81 Ard Biesheuvel 2016-01-11 117 * So iterate over the memory map again, subtracting the number of 2ddbfc81 Ard Biesheuvel 2016-01-11 118 * slots of each entry at each iteration, until we have found the entry 2ddbfc81 Ard Biesheuvel 2016-01-11 119 * that covers our chosen slot. Use the residual value of target_slot 2ddbfc81 Ard Biesheuvel 2016-01-11 120 * to calculate the randomly chosen address, and allocate it directly 2ddbfc81 Ard Biesheuvel 2016-01-11 121 * using EFI_ALLOCATE_ADDRESS. 2ddbfc81 Ard Biesheuvel 2016-01-11 122 */ 2ddbfc81 Ard Biesheuvel 2016-01-11 123 for (map_offset = 0; map_offset < map_size; map_offset += desc_size) { 2ddbfc81 Ard Biesheuvel 2016-01-11 124 efi_memory_desc_t *md = (void *)memory_map + map_offset; 2ddbfc81 Ard Biesheuvel 2016-01-11 125 efi_physical_addr_t target; 2ddbfc81 Ard Biesheuvel 2016-01-11 126 unsigned long pages; 2ddbfc81 Ard Biesheuvel 2016-01-11 127 2ddbfc81 Ard Biesheuvel 2016-01-11 128 if (target_slot >= MD_NUM_SLOTS(md)) { 2ddbfc81 Ard Biesheuvel 2016-01-11 129 target_slot -= MD_NUM_SLOTS(md); 2ddbfc81 Ard Biesheuvel 2016-01-11 130 continue; 2ddbfc81 Ard Biesheuvel 2016-01-11 131 } 2ddbfc81 Ard Biesheuvel 2016-01-11 132 2ddbfc81 Ard Biesheuvel 2016-01-11 133 target = round_up(md->phys_addr, align) + target_slot * align; 2ddbfc81 Ard Biesheuvel 2016-01-11 134 pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE; 2ddbfc81 Ard Biesheuvel 2016-01-11 135 2ddbfc81 Ard Biesheuvel 2016-01-11 136 status = efi_call_early(allocate_pages, EFI_ALLOCATE_ADDRESS, 2ddbfc81 Ard Biesheuvel 2016-01-11 137 EFI_LOADER_DATA, pages, &target); 2ddbfc81 Ard Biesheuvel 2016-01-11 138 if (status == EFI_SUCCESS) 2ddbfc81 Ard Biesheuvel 2016-01-11 139 *addr = target; 2ddbfc81 Ard Biesheuvel 2016-01-11 140 break; 2ddbfc81 Ard Biesheuvel 2016-01-11 141 } 2ddbfc81 Ard Biesheuvel 2016-01-11 142 2ddbfc81 Ard Biesheuvel 2016-01-11 143 efi_call_early(free_pool, memory_map); 2ddbfc81 Ard Biesheuvel 2016-01-11 144 2ddbfc81 Ard Biesheuvel 2016-01-11 145 return status; 2ddbfc81 Ard Biesheuvel 2016-01-11 146 } 568bc4e8 Ard Biesheuvel 2016-11-12 147 568bc4e8 Ard Biesheuvel 2016-11-12 148 efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg) 568bc4e8 Ard Biesheuvel 2016-11-12 149 { 568bc4e8 Ard Biesheuvel 2016-11-12 150 efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID; 568bc4e8 Ard Biesheuvel 2016-11-12 151 efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW; 568bc4e8 Ard Biesheuvel 2016-11-12 152 efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID; 568bc4e8 Ard Biesheuvel 2016-11-12 153 struct efi_rng_protocol *rng; 568bc4e8 Ard Biesheuvel 2016-11-12 154 struct linux_efi_random_seed *seed; 568bc4e8 Ard Biesheuvel 2016-11-12 155 efi_status_t status; 568bc4e8 Ard Biesheuvel 2016-11-12 156 568bc4e8 Ard Biesheuvel 2016-11-12 157 status = efi_call_early(locate_protocol, &rng_proto, NULL, 568bc4e8 Ard Biesheuvel 2016-11-12 158 (void **)&rng); 568bc4e8 Ard Biesheuvel 2016-11-12 159 if (status != EFI_SUCCESS) 568bc4e8 Ard Biesheuvel 2016-11-12 160 return status; 568bc4e8 Ard Biesheuvel 2016-11-12 161 568bc4e8 Ard Biesheuvel 2016-11-12 162 status = efi_call_early(allocate_pool, EFI_RUNTIME_SERVICES_DATA, 568bc4e8 Ard Biesheuvel 2016-11-12 @163 sizeof(*seed) + RANDOM_SEED_SIZE, :::::: The code at line 163 was first introduced by commit :::::: 568bc4e87033d232c5fd00d5b0cd22a2ccc04944 efi/arm*/libstub: Invoke EFI_RNG_PROTOCOL to seed the UEFI RNG table :::::: TO: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx> :::::: CC: Ingo Molnar <mingo@xxxxxxxxxx> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Attachment:
.config.gz
Description: application/gzip