From 235ad0ff5dee271011bf75579cef7ff726705bf9 Mon Sep 17 00:00:00 2001 From: "Li, Fei1" Date: Mon, 17 Dec 2018 22:55:09 +0800 Subject: [PATCH] hv: refine memcpy_s Use enhanced rep fast-string operation to refine memcpy_s. And assume that the destination and the source would not overlap. Tracked-On: #861 Signed-off-by: Li, Fei1 --- hypervisor/include/lib/rtl.h | 2 +- hypervisor/lib/memory.c | 104 ++++++++--------------------------- 2 files changed, 23 insertions(+), 83 deletions(-) diff --git a/hypervisor/include/lib/rtl.h b/hypervisor/include/lib/rtl.h index 41d5458544..c22fd36aaf 100644 --- a/hypervisor/include/lib/rtl.h +++ b/hypervisor/include/lib/rtl.h @@ -28,7 +28,7 @@ char *strncpy_s(char *d_arg, size_t dmax, const char *s_arg, size_t slen_arg); char *strchr(char *s_arg, char ch); size_t strnlen_s(const char *str_arg, size_t maxlen_arg); void *memset(void *base, uint8_t v, size_t n); -void *memcpy_s(void *d, size_t dmax, const void *s, size_t slen_arg); +void *memcpy_s(void *d, size_t dmax, const void *s, size_t slen); int32_t atoi(const char *str); long strtol_deci(const char *nptr); uint64_t strtoul_hex(const char *nptr); diff --git a/hypervisor/lib/memory.c b/hypervisor/lib/memory.c index 95272ebd13..9ee65a1a8c 100644 --- a/hypervisor/lib/memory.c +++ b/hypervisor/lib/memory.c @@ -274,96 +274,36 @@ void *memchr(const void *void_s, int32_t c, size_t n) return NULL; } -/*********************************************************************** - * - * FUNCTION - * - * memcpy_s - * - * DESCRIPTION - * - * Copies at most slen bytes from src address to dest address, - * up to dmax. +static inline void memcpy_erms(void *d, const void *s, size_t slen) +{ + asm volatile ("rep; movsb" + : "=&D"(d), "=&S"(s) + : "c"(slen), "0" (d), "1" (s) + : "memory"); +} + +/* + * @brief Copies at most slen bytes from src address to dest address, up to dmax. * * INPUTS * - * d pointer to Destination address - * dmax maximum length of dest - * s pointer to Source address - * slen maximum number of bytes of src to copy + * @param[in] d pointer to Destination address + * @param[in] dmax maximum length of dest + * @param[in] s pointer to Source address + * @param[in] slen maximum number of bytes of src to copy * - * OUTPUTS + * @return pointer to destination address. * - * void * pointer to destination address if successful, - * or else return null. - * - ***********************************************************************/ -void *memcpy_s(void *d, size_t dmax, const void *s, size_t slen_arg) + * @pre d and s will not overlap. + */ +void *memcpy_s(void *d, size_t dmax, const void *s, size_t slen) { - uint8_t *dest8; - uint8_t *src8; - size_t slen = slen_arg; - - if ((slen == 0U) || (dmax == 0U) || (dmax < slen)) { - ASSERT(false); - } - - if ((((d) > (s)) && ((d) <= ((s + slen) - 1U))) - || (((d) < (s)) && ((s) <= ((d + dmax) - 1U)))) { - ASSERT(false); - } - - /* same memory block, no need to copy */ - if (d == s) { - return d; - } - - dest8 = (uint8_t *)d; - src8 = (uint8_t *)s; - - /* small data block */ - if (slen < 8U) { - while (slen != 0U) { - *dest8 = *src8; - dest8++; - src8++; - slen--; - } - - return d; - } - - /* make sure 8bytes-aligned for at least one addr. */ - if ((!mem_aligned_check((uint64_t)src8, 8UL)) && - (!mem_aligned_check((uint64_t)dest8, 8UL))) { - for (; (slen != 0U) && ((((uint64_t)src8) & 7UL) != 0UL); - slen--) { - *dest8 = *src8; - dest8++; - src8++; + if ((slen != 0U) && (dmax != 0U) && (dmax >= slen)) { + /* same memory block, no need to copy */ + if (d != s) { + memcpy_erms(d, s, slen); } } - - /* copy main data blocks, with rep prefix */ - if (slen > 8U) { - uint32_t ecx; - - asm volatile ("cld; rep; movsq" - : "=&c"(ecx), "=&D"(dest8), "=&S"(src8) - : "0" (slen >> 3), "1" (dest8), "2" (src8) - : "memory"); - - slen = slen & 0x7U; - } - - /* tail bytes */ - while (slen != 0U) { - *dest8 = *src8; - dest8++; - src8++; - slen--; - } - return d; }