
On Sat, May 13, 2017 at 1:07 AM, Ruchika Gupta ruchika.gupta@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.gupta@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