On Thu, Aug 24, 2017 at 06:04:40PM +0100, Mark Rutland wrote: > On Thu, Aug 24, 2017 at 05:18:06PM +0900, AKASHI Takahiro wrote: > > Most of sha256 code is based on crypto/sha256-glue.c, particularly using > > non-neon version. > > > > Please note that we won't be able to re-use lib/mem*.S for purgatory > > because unaligned memory access is not allowed in purgatory where mmu > > is turned off. > > > > Since purgatory is not linked with the other part of kernel, care must be > > taken of selecting an appropriate set of compiler options in order to > > prevent undefined symbol references from being generated. > > What is the point in performing this check in the purgatory code, when > this will presumably have been checked when the image is loaded? Well, this is what x86 does :) On powerpc, meanwhile, they don't have this check. Maybe to avoid booting corrupted kernel after loading? (loaded data are now protected by making them unmapped, though.) > [...] > > > diff --git a/arch/arm64/purgatory/entry.S b/arch/arm64/purgatory/entry.S > > index bc4e6b3bf8a1..74d028b838bd 100644 > > --- a/arch/arm64/purgatory/entry.S > > +++ b/arch/arm64/purgatory/entry.S > > @@ -6,6 +6,11 @@ > > .text > > > > ENTRY(purgatory_start) > > + adr x19, .Lstack > > + mov sp, x19 > > + > > + bl purgatory > > + > > /* Start new image. */ > > ldr x17, arm64_kernel_entry > > ldr x0, arm64_dtb_addr > > @@ -15,6 +20,14 @@ ENTRY(purgatory_start) > > br x17 > > END(purgatory_start) > > > > +.ltorg > > + > > +.align 4 > > + .rept 256 > > + .quad 0 > > + .endr > > +.Lstack: > > + > > .data > > Why is the stack in .text? to call verify_sha256_digest() from asm > Does this need to be zeroed? No :) > If it does, why not something like: > > .fill PURGATORY_STACK_SIZE 1, 0 > > > > > .align 3 > > diff --git a/arch/arm64/purgatory/purgatory.c b/arch/arm64/purgatory/purgatory.c > > new file mode 100644 > > index 000000000000..7fcbefa786bc > > --- /dev/null > > +++ b/arch/arm64/purgatory/purgatory.c > > @@ -0,0 +1,20 @@ > > +/* > > + * purgatory: Runs between two kernels > > + * > > + * Copyright (c) 2017 Linaro Limited > > + * Author: AKASHI Takahiro <takahiro.akashi at linaro.org> > > + */ > > + > > +#include "sha256.h" > > + > > +void purgatory(void) > > +{ > > + int ret; > > + > > + ret = verify_sha256_digest(); > > + if (ret) { > > + /* loop forever */ > > + for (;;) > > + ; > > + } > > +} > > Surely we can do something slightly better than a busy loop? e.g. > something like the __no_granule_support loop in head.s? Okey. > > diff --git a/arch/arm64/purgatory/sha256-core.S b/arch/arm64/purgatory/sha256-core.S > > new file mode 100644 > > index 000000000000..24f5ce25b61e > > --- /dev/null > > +++ b/arch/arm64/purgatory/sha256-core.S > > @@ -0,0 +1 @@ > > +#include "../crypto/sha256-core.S_shipped" > > diff --git a/arch/arm64/purgatory/sha256.c b/arch/arm64/purgatory/sha256.c > > new file mode 100644 > > index 000000000000..5d20d81767e3 > > --- /dev/null > > +++ b/arch/arm64/purgatory/sha256.c > > @@ -0,0 +1,79 @@ > > +#include <linux/kexec.h> > > +#include <linux/purgatory.h> > > +#include <linux/types.h> > > + > > +/* > > + * Under KASAN, those are defined as un-instrumented version, __memxxx() > > + */ > > +#undef memcmp > > +#undef memcpy > > +#undef memset > > This doesn't look like the right place for this undeffery; it looks > rather fragile. Yeah, I agree, but if not there, __memxxx() are used. > > diff --git a/arch/arm64/purgatory/string.c b/arch/arm64/purgatory/string.c > > new file mode 100644 > > index 000000000000..33233a210a65 > > --- /dev/null > > +++ b/arch/arm64/purgatory/string.c > > @@ -0,0 +1,32 @@ > > +#include <linux/types.h> > > + > > +void *memcpy(void *dst, const void *src, size_t len) > > +{ > > + int i; > > + > > + for (i = 0; i < len; i++) > > + ((u8 *)dst)[i] = ((u8 *)src)[i]; > > + > > + return NULL; > > +} > > + > > +void *memset(void *dst, int c, size_t len) > > +{ > > + int i; > > + > > + for (i = 0; i < len; i++) > > + ((u8 *)dst)[i] = (u8)c; > > + > > + return NULL; > > +} > > + > > +int memcmp(const void *src, const void *dst, size_t len) > > +{ > > + int i; > > + > > + for (i = 0; i < len; i++) > > + if (*(char *)src != *(char *)dst) > > + return 1; > > + > > + return 0; > > +} > > How is the compiler prevented from "optimising" these into calls to > themselves? I don't get what you mean by "calls to themselves." Thanks, -Takahiro AKASHI > I suspect these will need to be written in asm. > > Thanks, > Mark.