On Tue, Apr 21, 2020 at 04:15:31PM +0100, Will Deacon wrote: > do_csum() over-reads the source buffer and therefore abuses > READ_ONCE_NOCHECK() to avoid tripping up KASAN. In preparation for > READ_ONCE_NOCHECK() becoming a macro, and therefore losing its > '__no_sanitize_address' annotation, just annotate do_csum() explicitly > and fall back to normal loads. > > Cc: Mark Rutland <mark.rutland@xxxxxxx> > Cc: Robin Murphy <robin.murphy@xxxxxxx> > Signed-off-by: Will Deacon <will@xxxxxxxxxx> >From a functional perspective: Acked-by: Mark Rutland <mark.rutland@xxxxxxx> I know that Robin had a concern w.r.t. how this would affect the codegen, but I think we can follow that up after the series as a whole is merged. Thanks, Mark. > --- > arch/arm64/lib/csum.c | 20 ++++++++++++-------- > 1 file changed, 12 insertions(+), 8 deletions(-) > > diff --git a/arch/arm64/lib/csum.c b/arch/arm64/lib/csum.c > index 60eccae2abad..78b87a64ca0a 100644 > --- a/arch/arm64/lib/csum.c > +++ b/arch/arm64/lib/csum.c > @@ -14,7 +14,11 @@ static u64 accumulate(u64 sum, u64 data) > return tmp + (tmp >> 64); > } > > -unsigned int do_csum(const unsigned char *buff, int len) > +/* > + * We over-read the buffer and this makes KASAN unhappy. Instead, disable > + * instrumentation and call kasan explicitly. > + */ > +unsigned int __no_sanitize_address do_csum(const unsigned char *buff, int len) > { > unsigned int offset, shift, sum; > const u64 *ptr; > @@ -42,7 +46,7 @@ unsigned int do_csum(const unsigned char *buff, int len) > * odd/even alignment, and means we can ignore it until the very end. > */ > shift = offset * 8; > - data = READ_ONCE_NOCHECK(*ptr++); > + data = *ptr++; > #ifdef __LITTLE_ENDIAN > data = (data >> shift) << shift; > #else > @@ -58,10 +62,10 @@ unsigned int do_csum(const unsigned char *buff, int len) > while (unlikely(len > 64)) { > __uint128_t tmp1, tmp2, tmp3, tmp4; > > - tmp1 = READ_ONCE_NOCHECK(*(__uint128_t *)ptr); > - tmp2 = READ_ONCE_NOCHECK(*(__uint128_t *)(ptr + 2)); > - tmp3 = READ_ONCE_NOCHECK(*(__uint128_t *)(ptr + 4)); > - tmp4 = READ_ONCE_NOCHECK(*(__uint128_t *)(ptr + 6)); > + tmp1 = *(__uint128_t *)ptr; > + tmp2 = *(__uint128_t *)(ptr + 2); > + tmp3 = *(__uint128_t *)(ptr + 4); > + tmp4 = *(__uint128_t *)(ptr + 6); > > len -= 64; > ptr += 8; > @@ -85,7 +89,7 @@ unsigned int do_csum(const unsigned char *buff, int len) > __uint128_t tmp; > > sum64 = accumulate(sum64, data); > - tmp = READ_ONCE_NOCHECK(*(__uint128_t *)ptr); > + tmp = *(__uint128_t *)ptr; > > len -= 16; > ptr += 2; > @@ -100,7 +104,7 @@ unsigned int do_csum(const unsigned char *buff, int len) > } > if (len > 0) { > sum64 = accumulate(sum64, data); > - data = READ_ONCE_NOCHECK(*ptr); > + data = *ptr; > len -= 8; > } > /* > -- > 2.26.1.301.g55bc3eb7cb9-goog >