On Sat, May 13, 2017 at 1:07 AM, Ruchika Gupta <ruchika.gu...@nxp.com> wrote: > kASLR support in kernel requires a random number to be passed via > chosen/kaslr-seed propert. sec_firmware generates this random seed > which can then be passed in the device tree node
Is that functionality generic that it can be consumed by other devices? > sec_firmware reserves JR3 for it's own usage. Node for JR3 is > removed from device-tree. > > Signed-off-by: Ruchika Gupta <ruchika.gu...@nxp.com> > --- > arch/arm/cpu/armv8/fsl-layerscape/fdt.c | 73 > +++++++++++++++++++++++++++++++ > arch/arm/cpu/armv8/sec_firmware.c | 53 ++++++++++++++++++++++ > arch/arm/include/asm/armv8/sec_firmware.h | 9 ++++ > 3 files changed, 135 insertions(+) > > diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c > b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c > index 05c4577..d4ca129 100644 > --- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c > +++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c > @@ -345,6 +345,75 @@ static void fdt_fixup_msi(void *blob) > } > #endif > > + > +int fdt_fixup_kaslr(void *fdt) > +{ > + int nodeoffset; > + int err, ret = 0; > + u8 rand[8]; > + > +#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) > + /* Check if random seed generation is supported */ > + if (sec_firmware_support_hwrng() == false) > + return 0; > + > + ret = sec_firmware_get_random(rand, 8); > + if (ret < 0) { > + printf("WARNING: could not get random number to set", > + "kaslr-seed\n"); > + return 0; > + } > + > + err = fdt_check_header(fdt); > + if (err < 0) { > + printf("fdt_chosen: %s\n", fdt_strerror(err)); > + return 0; > + } > + > + /* find or create "/chosen" node. */ > + nodeoffset = fdt_find_or_add_subnode(fdt, 0, "chosen"); > + if (nodeoffset < 0) > + return 0; > + > + err = fdt_setprop(fdt, nodeoffset, "kaslr-seed", rand, > + sizeof(rand)); > + if (err < 0) { > + printf("WARNING: could not set kaslr-seed %s.\n", > + fdt_strerror(err)); > + return 0; > + } > + ret = 1; > +#endif > + > + return ret; > +} > + > +/* Remove JR node used by SEC firmware */ > +void fdt_fixup_remove_jr(void *blob) > +{ > + int jr_node, addr_cells, len; > + int crypto_node = fdt_path_offset(blob, "crypto"); > + u64 jr_offset, used_jr; > + fdt32_t *reg; > + > + used_jr = sec_firmware_used_jobring_offset(); > + of_bus_default_count_cells(blob, crypto_node, &addr_cells, NULL); > + > + jr_node = fdt_node_offset_by_compatible(blob, crypto_node, > + "fsl,sec-v4.0-job-ring"); > + > + while (jr_node != -FDT_ERR_NOTFOUND) { > + reg = (fdt32_t *)fdt_getprop(blob, jr_node, "reg", &len); > + jr_offset = of_read_number(reg, addr_cells); > + if (jr_offset == used_jr) { > + fdt_del_node(blob, jr_node); > + break; > + } > + jr_node = fdt_node_offset_by_compatible(blob, jr_node, > + > "fsl,sec-v4.0-job-ring"); > + } > +} > + > void ft_cpu_setup(void *blob, bd_t *bd) > { > #ifdef CONFIG_FSL_LSCH2 > @@ -358,6 +427,9 @@ void ft_cpu_setup(void *blob, bd_t *bd) > else { > ccsr_sec_t __iomem *sec; > > + if (fdt_fixup_kaslr(blob)) > + fdt_fixup_remove_jr(blob); > + > sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR; > fdt_fixup_crypto_node(blob, sec_in32(&sec->secvid_ms)); > } > @@ -396,4 +468,5 @@ void ft_cpu_setup(void *blob, bd_t *bd) > #ifdef CONFIG_HAS_FEATURE_ENHANCED_MSI > fdt_fixup_msi(blob); > #endif > + > } > diff --git a/arch/arm/cpu/armv8/sec_firmware.c > b/arch/arm/cpu/armv8/sec_firmware.c > index 4afa3ad..f460cca 100644 > --- a/arch/arm/cpu/armv8/sec_firmware.c > +++ b/arch/arm/cpu/armv8/sec_firmware.c > @@ -232,6 +232,59 @@ unsigned int sec_firmware_support_psci_version(void) > #endif > > /* > + * Check with sec_firmware if it supports random number generation > + * via HW RNG > + * > + * The return value will be true if it is supported > + */ > +bool sec_firmware_support_hwrng(void) > +{ > + uint8_t rand[8]; > + if (sec_firmware_addr & SEC_FIRMWARE_RUNNING) { > + if (!sec_firmware_get_random(rand, 8)) > + return true; > + } > + > + return false; > +} > + > +/* > + * sec_firmware_get_random - Initialize the SEC Firmware > + * @rand: random number buffer to be filled > + * @bytes: Number of bytes of random number to be supported > + * @eret: -1 in case of error, 0 for success > + */ > +int sec_firmware_get_random(uint8_t *rand, int bytes) > +{ > + unsigned long long num; > + struct pt_regs regs; > + int param1; > + > + if (!bytes || bytes > 8) { > + printf("Max Random bytes genration supported is 8\n"); > + return -1; > + } > +#define SIP_RNG_64 0xC200FF11 > + regs.regs[0] = SIP_RNG_64; > + > + if (bytes <= 4) > + param1 = 0; > + else > + param1 = 1; > + regs.regs[1] = param1; > + > + smc_call(®s); > + > + if (regs.regs[0]) > + return -1; > + > + num = regs.regs[1]; > + memcpy(rand, &num, bytes); > + > + return 0; > +} > + > +/* > * sec_firmware_init - Initialize the SEC Firmware > * @sec_firmware_img: the SEC Firmware image address > * @eret_hold_l: the address to hold exception return address low > diff --git a/arch/arm/include/asm/armv8/sec_firmware.h > b/arch/arm/include/asm/armv8/sec_firmware.h > index bc1d97d..1dc547a 100644 > --- a/arch/arm/include/asm/armv8/sec_firmware.h > +++ b/arch/arm/include/asm/armv8/sec_firmware.h > @@ -8,10 +8,13 @@ > #define __SEC_FIRMWARE_H_ > > #define PSCI_INVALID_VER 0xffffffff > +#define SEC_JR3_OFFSET 0x40000 > > int sec_firmware_init(const void *, u32 *, u32 *); > int _sec_firmware_entry(const void *, u32 *, u32 *); > bool sec_firmware_is_valid(const void *); > +bool sec_firmware_support_hwrng(void); > +int sec_firmware_get_random(uint8_t *rand, int bytes); > #ifdef CONFIG_SEC_FIRMWARE_ARMV8_PSCI > unsigned int sec_firmware_support_psci_version(void); > unsigned int _sec_firmware_support_psci_version(void); > @@ -22,4 +25,10 @@ static inline unsigned int > sec_firmware_support_psci_version(void) > } > #endif > > +static inline unsigned int sec_firmware_used_jobring_offset(void) > +{ > + return SEC_JR3_OFFSET; > +} > + > + > #endif /* __SEC_FIRMWARE_H_ */ > -- > 2.7.4 > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > https://lists.denx.de/listinfo/u-boot _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot