Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2016 Linaro Ltd;  <ard.biesheuvel@linaro.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <asm/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include "efistub.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * Return the number of slots covered by this entry, i.e., the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * addresses it covers that are suitably aligned and supply enough room
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * for the allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) static unsigned long get_entry_num_slots(efi_memory_desc_t *md,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 					 unsigned long size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 					 unsigned long align_shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	unsigned long align = 1UL << align_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	u64 first_slot, last_slot, region_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	if (md->type != EFI_CONVENTIONAL_MEMORY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	if (efi_soft_reserve_enabled() &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	    (md->attribute & EFI_MEMORY_SP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	region_end = min(md->phys_addr + md->num_pages * EFI_PAGE_SIZE - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 			 (u64)ULONG_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	if (region_end < size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	first_slot = round_up(md->phys_addr, align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	last_slot = round_down(region_end - size + 1, align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	if (first_slot > last_slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	return ((unsigned long)(last_slot - first_slot) >> align_shift) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * The UEFI memory descriptors have a virtual address field that is only used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * when installing the virtual mapping using SetVirtualAddressMap(). Since it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * is unused here, we can reuse it to keep track of each descriptor's slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define MD_NUM_SLOTS(md)	((md)->virt_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) efi_status_t efi_random_alloc(unsigned long size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			      unsigned long align,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 			      unsigned long *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 			      unsigned long random_seed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	unsigned long map_size, desc_size, total_slots = 0, target_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	unsigned long buff_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	efi_status_t status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	efi_memory_desc_t *memory_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	int map_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct efi_boot_memmap map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	map.map =	&memory_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	map.map_size =	&map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	map.desc_size =	&desc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	map.desc_ver =	NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	map.key_ptr =	NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	map.buff_size =	&buff_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	status = efi_get_memory_map(&map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	if (status != EFI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	if (align < EFI_ALLOC_ALIGN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		align = EFI_ALLOC_ALIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	size = round_up(size, EFI_ALLOC_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	/* count the suitable slots in each memory map entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	for (map_offset = 0; map_offset < map_size; map_offset += desc_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		efi_memory_desc_t *md = (void *)memory_map + map_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		unsigned long slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		slots = get_entry_num_slots(md, size, ilog2(align));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		MD_NUM_SLOTS(md) = slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		total_slots += slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	/* find a random number between 0 and total_slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	target_slot = (total_slots * (u64)(random_seed & U32_MAX)) >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	 * target_slot is now a value in the range [0, total_slots), and so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	 * it corresponds with exactly one of the suitable slots we recorded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	 * when iterating over the memory map the first time around.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	 * So iterate over the memory map again, subtracting the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	 * slots of each entry at each iteration, until we have found the entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	 * that covers our chosen slot. Use the residual value of target_slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	 * to calculate the randomly chosen address, and allocate it directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	 * using EFI_ALLOCATE_ADDRESS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	for (map_offset = 0; map_offset < map_size; map_offset += desc_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		efi_memory_desc_t *md = (void *)memory_map + map_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		efi_physical_addr_t target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		unsigned long pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		if (target_slot >= MD_NUM_SLOTS(md)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			target_slot -= MD_NUM_SLOTS(md);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		target = round_up(md->phys_addr, align) + target_slot * align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		pages = size / EFI_PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 				     EFI_LOADER_DATA, pages, &target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		if (status == EFI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			*addr = target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	efi_bs_call(free_pool, memory_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }