| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- // SPDX-License-Identifier: GPL-2.0-only
- // Copyright 2022 Google LLC
- // Author: Ard Biesheuvel <ardb@google.com>
- // NOTE: code in this file runs *very* early, and is not permitted to use
- // global variables or anything that relies on absolute addressing.
- #include <linux/libfdt.h>
- #include <linux/init.h>
- #include <linux/linkage.h>
- #include <linux/types.h>
- #include <linux/sizes.h>
- #include <linux/string.h>
- #include <asm/archrandom.h>
- #include <asm/memory.h>
- #include <asm/pgtable.h>
- #include "pi.h"
- extern u16 memstart_offset_seed;
- static u64 __init get_kaslr_seed(void *fdt, int node)
- {
- static char const seed_str[] __initconst = "kaslr-seed";
- fdt64_t *prop;
- u64 ret;
- int len;
- if (node < 0)
- return 0;
- prop = fdt_getprop_w(fdt, node, seed_str, &len);
- if (!prop || len != sizeof(u64))
- return 0;
- ret = fdt64_to_cpu(*prop);
- *prop = 0;
- return ret;
- }
- u64 __init kaslr_early_init(void *fdt, int chosen)
- {
- u64 seed, range;
- if (kaslr_disabled_cmdline())
- return 0;
- seed = get_kaslr_seed(fdt, chosen);
- if (!seed) {
- if (!__early_cpu_has_rndr() ||
- !__arm64_rndr((unsigned long *)&seed))
- return 0;
- }
- memstart_offset_seed = seed & U16_MAX;
- /*
- * OK, so we are proceeding with KASLR enabled. Calculate a suitable
- * kernel image offset from the seed. Let's place the kernel in the
- * 'middle' half of the VMALLOC area, and stay clear of the lower and
- * upper quarters to avoid colliding with other allocations.
- */
- range = (VMALLOC_END - KIMAGE_VADDR) / 2;
- return range / 2 + (((__uint128_t)range * seed) >> 64);
- }
|