|
@@ -18,6 +18,22 @@
|
|
|
|
|
|
#include "efistub.h"
|
|
|
|
|
|
+/*
|
|
|
+ * This is the base address at which to start allocating virtual memory ranges
|
|
|
+ * for UEFI Runtime Services. This is in the low TTBR0 range so that we can use
|
|
|
+ * any allocation we choose, and eliminate the risk of a conflict after kexec.
|
|
|
+ * The value chosen is the largest non-zero power of 2 suitable for this purpose
|
|
|
+ * both on 32-bit and 64-bit ARM CPUs, to maximize the likelihood that it can
|
|
|
+ * be mapped efficiently.
|
|
|
+ * Since 32-bit ARM could potentially execute with a 1G/3G user/kernel split,
|
|
|
+ * map everything below 1 GB. (512 MB is a reasonable upper bound for the
|
|
|
+ * entire footprint of the UEFI runtime services memory regions)
|
|
|
+ */
|
|
|
+#define EFI_RT_VIRTUAL_BASE SZ_512M
|
|
|
+#define EFI_RT_VIRTUAL_SIZE SZ_512M
|
|
|
+
|
|
|
+static u64 virtmap_base = EFI_RT_VIRTUAL_BASE;
|
|
|
+
|
|
|
efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
|
|
|
void *__image, void **__fh)
|
|
|
{
|
|
@@ -213,6 +229,25 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
|
|
|
|
|
|
efi_random_get_seed(sys_table);
|
|
|
|
|
|
+ if (!nokaslr()) {
|
|
|
+ /*
|
|
|
+ * Randomize the base of the UEFI runtime services region.
|
|
|
+ * Preserve the 2 MB alignment of the region by taking a
|
|
|
+ * shift of 21 bit positions into account when scaling
|
|
|
+ * the headroom value using a 32-bit random value.
|
|
|
+ */
|
|
|
+ u64 headroom = TASK_SIZE - EFI_RT_VIRTUAL_BASE -
|
|
|
+ EFI_RT_VIRTUAL_SIZE;
|
|
|
+ u32 rnd;
|
|
|
+
|
|
|
+ status = efi_get_random_bytes(sys_table, sizeof(rnd),
|
|
|
+ (u8 *)&rnd);
|
|
|
+ if (status == EFI_SUCCESS) {
|
|
|
+ virtmap_base = EFI_RT_VIRTUAL_BASE +
|
|
|
+ (((headroom >> 21) * rnd) >> (32 - 21));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
new_fdt_addr = fdt_addr;
|
|
|
status = allocate_new_fdt_and_exit_boot(sys_table, handle,
|
|
|
&new_fdt_addr, efi_get_max_fdt_addr(dram_base),
|
|
@@ -242,18 +277,6 @@ fail:
|
|
|
return EFI_ERROR;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * This is the base address at which to start allocating virtual memory ranges
|
|
|
- * for UEFI Runtime Services. This is in the low TTBR0 range so that we can use
|
|
|
- * any allocation we choose, and eliminate the risk of a conflict after kexec.
|
|
|
- * The value chosen is the largest non-zero power of 2 suitable for this purpose
|
|
|
- * both on 32-bit and 64-bit ARM CPUs, to maximize the likelihood that it can
|
|
|
- * be mapped efficiently.
|
|
|
- * Since 32-bit ARM could potentially execute with a 1G/3G user/kernel split,
|
|
|
- * map everything below 1 GB.
|
|
|
- */
|
|
|
-#define EFI_RT_VIRTUAL_BASE SZ_512M
|
|
|
-
|
|
|
static int cmp_mem_desc(const void *l, const void *r)
|
|
|
{
|
|
|
const efi_memory_desc_t *left = l, *right = r;
|
|
@@ -303,7 +326,7 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
|
|
|
unsigned long desc_size, efi_memory_desc_t *runtime_map,
|
|
|
int *count)
|
|
|
{
|
|
|
- u64 efi_virt_base = EFI_RT_VIRTUAL_BASE;
|
|
|
+ u64 efi_virt_base = virtmap_base;
|
|
|
efi_memory_desc_t *in, *prev = NULL, *out = runtime_map;
|
|
|
int l;
|
|
|
|