Message ID | 1476089061-15197-5-git-send-email-stewart@linux.vnet.ibm.com |
---|---|
State | Accepted |
Headers | show |
On 10/10/16 19:43, Stewart Smith wrote: > From: Claudio Carvalho <cclaudio@linux.vnet.ibm.com> > > This adds memcpy_from_ci, a cache inhibited version of memcpy, required > by secure boot. The secure boot verification code is stored in a secure > ROM and the logic that contains the ROM within the processor is > implemented in a way that it only responds to CI (cache inhibited) > operations. Due to performance issues we copy the verification code from > the secure ROM to RAM and we use memcpy_ci for that. > > What makes memcpy_ci vs ordinary memcpy? > I think the changelog is not properly all converted over, it still has references to memcpy_ci as opposed to memcpy_from_ci. > memcpy copies data like in the example below and the compiler translates that > to load instructions that are not cache inhibited (e.g. lbzx - load byte and > zero indexed). In other words, the data is cached. > > a[i] = b[i] > > memcpy_ci copies data using the cache inhibited version of load instructions: > in_8() and in_be32(), both defined in include/io.h. These functions use lbzcix > and lwzcix assembly instructions, respectively. In this case, the data is not > cached as required by the logic that contains the ROM. > > *((uint8_t*) destp) = in_8((uint8_t*)srcp); > *((uint32_t*) destp) = in_be32((uint32_t*)srcp) > > Signed-off-by: Claudio Carvalho <cclaudio@linux.vnet.ibm.com> > Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com> > --- > libc/include/string.h | 3 ++- > libc/string/Makefile.inc | 9 +++++---- > libc/string/memcpy_from_ci.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 54 insertions(+), 5 deletions(-) > create mode 100644 libc/string/memcpy_from_ci.c > > diff --git a/libc/include/string.h b/libc/include/string.h > index 890ffc2..e4b4fac 100644 > --- a/libc/include/string.h > +++ b/libc/include/string.h > @@ -1,5 +1,5 @@ > /****************************************************************************** > - * Copyright (c) 2004, 2008 IBM Corporation > + * Copyright (c) 2004, 2016 IBM Corporation > * All rights reserved. > * This program and the accompanying materials > * are made available under the terms of the BSD License > @@ -32,6 +32,7 @@ char *strdup(const char *src); > void *memset(void *s, int c, size_t n); > void *memchr(const void *s, int c, size_t n); > void *memcpy(void *dest, const void *src, size_t n); > +void *memcpy_from_ci(void *destpp, const void *srcpp, size_t len); > void *memmove(void *dest, const void *src, size_t n); > int memcmp(const void *s1, const void *s2, size_t n); > > diff --git a/libc/string/Makefile.inc b/libc/string/Makefile.inc > index 3b7c8ce..fb2f037 100644 > --- a/libc/string/Makefile.inc > +++ b/libc/string/Makefile.inc > @@ -1,5 +1,5 @@ > # ***************************************************************************** > -# * Copyright (c) 2004, 2008 IBM Corporation > +# * Copyright (c) 2004, 2016 IBM Corporation > # * All rights reserved. > # * This program and the accompanying materials > # * are made available under the terms of the BSD License > @@ -12,9 +12,10 @@ > > SUBDIRS += $(LIBCDIR)/string > > -STRING_OBJS = strcat.o strchr.o strcmp.o strcpy.o strlen.o strncmp.o \ > - strncpy.o strstr.o memset.o memcpy.o memmove.o memchr.o \ > - memcmp.o strcasecmp.o strncasecmp.o strtok.o strdup.o > +STRING_OBJS = strcat.o strchr.o strcmp.o strcpy.o strlen.o \ > + strncmp.o strncpy.o strstr.o memset.o memcpy.o memcpy_from_ci.o \ > + memmove.o memchr.o memcmp.o strcasecmp.o strncasecmp.o \ > + strtok.o strdup.o > STRING = $(LIBCDIR)/string/built-in.o > $(STRING): $(STRING_OBJS:%=$(LIBCDIR)/string/%) > > diff --git a/libc/string/memcpy_from_ci.c b/libc/string/memcpy_from_ci.c > new file mode 100644 > index 0000000..02affa3 > --- /dev/null > +++ b/libc/string/memcpy_from_ci.c > @@ -0,0 +1,47 @@ > +/* Copyright 2013-2016 IBM Corp > + * > + * Licensed under the Apache License, Version 2.0 (the "License"); > + * you may not use this file except in compliance with the License. > + * You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > + * implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > + */ > + > +#include <string.h> > +#include <ccan/short_types/short_types.h> > +#include <io.h> > + > +void* memcpy_from_ci(void *destpp, const void *srcpp, size_t len) > +{ > + const size_t block = sizeof(uint64_t); > + unsigned long int destp = (long int) destpp; > + unsigned long int srcp = (long int) srcpp; > + > + /* Copy as many blocks as possible if srcp is block aligned */ > + if ((srcp % block) == 0) { > + while ((len - block) > -1) { > + *((uint64_t*) destp) = in_be64((uint64_t*)srcp); > + srcp += block; > + destp += block; > + len -= block; > + } > + } > + /* > + * Byte-by-byte copy if srcp is not block aligned or len is/becomes > + * less than one block > + */ Can we have a pr_log(PR_devel,..) for unaligned copies to warn users? Balbir Singh.
Balbir Singh <bsingharora@gmail.com> writes: > On 10/10/16 19:43, Stewart Smith wrote: >> From: Claudio Carvalho <cclaudio@linux.vnet.ibm.com> >> >> This adds memcpy_from_ci, a cache inhibited version of memcpy, required >> by secure boot. The secure boot verification code is stored in a secure >> ROM and the logic that contains the ROM within the processor is >> implemented in a way that it only responds to CI (cache inhibited) >> operations. Due to performance issues we copy the verification code from >> the secure ROM to RAM and we use memcpy_ci for that. >> >> What makes memcpy_ci vs ordinary memcpy? >> > > I think the changelog is not properly all converted over, it still has > references to memcpy_ci as opposed to memcpy_from_ci. Doh, I missed that too. >> + /* >> + * Byte-by-byte copy if srcp is not block aligned or len is/becomes >> + * less than one block >> + */ > > Can we have a pr_log(PR_devel,..) for unaligned copies to warn users? I guess there isn't an issue calling in from libc... want to send a patch? :)
On 11/10/16 13:31, Stewart Smith wrote: > Balbir Singh <bsingharora@gmail.com> writes: >> On 10/10/16 19:43, Stewart Smith wrote: >>> From: Claudio Carvalho <cclaudio@linux.vnet.ibm.com> >>> >>> This adds memcpy_from_ci, a cache inhibited version of memcpy, required >>> by secure boot. The secure boot verification code is stored in a secure >>> ROM and the logic that contains the ROM within the processor is >>> implemented in a way that it only responds to CI (cache inhibited) >>> operations. Due to performance issues we copy the verification code from >>> the secure ROM to RAM and we use memcpy_ci for that. >>> >>> What makes memcpy_ci vs ordinary memcpy? >>> >> >> I think the changelog is not properly all converted over, it still has >> references to memcpy_ci as opposed to memcpy_from_ci. > > Doh, I missed that too. > >>> + /* >>> + * Byte-by-byte copy if srcp is not block aligned or len is/becomes >>> + * less than one block >>> + */ >> >> Can we have a pr_log(PR_devel,..) for unaligned copies to warn users? > > I guess there isn't an issue calling in from libc... want to send a > patch? :) > Sure, will do Just reading through the other patches in the series Balbir
diff --git a/libc/include/string.h b/libc/include/string.h index 890ffc2..e4b4fac 100644 --- a/libc/include/string.h +++ b/libc/include/string.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation + * Copyright (c) 2004, 2016 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License @@ -32,6 +32,7 @@ char *strdup(const char *src); void *memset(void *s, int c, size_t n); void *memchr(const void *s, int c, size_t n); void *memcpy(void *dest, const void *src, size_t n); +void *memcpy_from_ci(void *destpp, const void *srcpp, size_t len); void *memmove(void *dest, const void *src, size_t n); int memcmp(const void *s1, const void *s2, size_t n); diff --git a/libc/string/Makefile.inc b/libc/string/Makefile.inc index 3b7c8ce..fb2f037 100644 --- a/libc/string/Makefile.inc +++ b/libc/string/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2008 IBM Corporation +# * Copyright (c) 2004, 2016 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -12,9 +12,10 @@ SUBDIRS += $(LIBCDIR)/string -STRING_OBJS = strcat.o strchr.o strcmp.o strcpy.o strlen.o strncmp.o \ - strncpy.o strstr.o memset.o memcpy.o memmove.o memchr.o \ - memcmp.o strcasecmp.o strncasecmp.o strtok.o strdup.o +STRING_OBJS = strcat.o strchr.o strcmp.o strcpy.o strlen.o \ + strncmp.o strncpy.o strstr.o memset.o memcpy.o memcpy_from_ci.o \ + memmove.o memchr.o memcmp.o strcasecmp.o strncasecmp.o \ + strtok.o strdup.o STRING = $(LIBCDIR)/string/built-in.o $(STRING): $(STRING_OBJS:%=$(LIBCDIR)/string/%) diff --git a/libc/string/memcpy_from_ci.c b/libc/string/memcpy_from_ci.c new file mode 100644 index 0000000..02affa3 --- /dev/null +++ b/libc/string/memcpy_from_ci.c @@ -0,0 +1,47 @@ +/* Copyright 2013-2016 IBM Corp + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string.h> +#include <ccan/short_types/short_types.h> +#include <io.h> + +void* memcpy_from_ci(void *destpp, const void *srcpp, size_t len) +{ + const size_t block = sizeof(uint64_t); + unsigned long int destp = (long int) destpp; + unsigned long int srcp = (long int) srcpp; + + /* Copy as many blocks as possible if srcp is block aligned */ + if ((srcp % block) == 0) { + while ((len - block) > -1) { + *((uint64_t*) destp) = in_be64((uint64_t*)srcp); + srcp += block; + destp += block; + len -= block; + } + } + /* + * Byte-by-byte copy if srcp is not block aligned or len is/becomes + * less than one block + */ + while (len > 0) { + *((uint8_t*) destp) = in_8((uint8_t*)srcp); + srcp += 1; + destp += 1; + len--; + } + return destpp; +}