diff options
author | Renato Botelho <renato@netgate.com> | 2017-01-09 12:07:59 -0200 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2017-01-09 12:07:59 -0200 |
commit | baeac042059786f1ed0cca7ca4a4a32721362cab (patch) | |
tree | 3b848bddaf0f478d0c0651c8ee62129d3d9bacf5 /lib/libc | |
parent | 1af1408e09373ae856cfef567d79849c7e7e0d25 (diff) | |
parent | f91948fdd5322d9aae1e8785976df69612c1999f (diff) | |
download | FreeBSD-src-baeac042059786f1ed0cca7ca4a4a32721362cab.zip FreeBSD-src-baeac042059786f1ed0cca7ca4a4a32721362cab.tar.gz |
Merge remote-tracking branch 'origin/stable/11' into devel-11
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/locale/mblocal.h | 24 | ||||
-rw-r--r-- | lib/libc/net/getaddrinfo.c | 12 | ||||
-rw-r--r-- | lib/libc/x86/sys/__vdso_gettc.c | 73 |
3 files changed, 89 insertions, 20 deletions
diff --git a/lib/libc/locale/mblocal.h b/lib/libc/locale/mblocal.h index c4724b5..acb1c21 100644 --- a/lib/libc/locale/mblocal.h +++ b/lib/libc/locale/mblocal.h @@ -65,18 +65,18 @@ extern struct xlocale_ctype __xlocale_global_ctype; /* * Rune initialization function prototypes. */ -__hidden int _none_init(struct xlocale_ctype *, _RuneLocale *); -__hidden int _ascii_init(struct xlocale_ctype *, _RuneLocale *); -__hidden int _UTF8_init(struct xlocale_ctype *, _RuneLocale *); -__hidden int _EUC_CN_init(struct xlocale_ctype *, _RuneLocale *); -__hidden int _EUC_JP_init(struct xlocale_ctype *, _RuneLocale *); -__hidden int _EUC_KR_init(struct xlocale_ctype *, _RuneLocale *); -__hidden int _EUC_TW_init(struct xlocale_ctype *, _RuneLocale *); -__hidden int _GB18030_init(struct xlocale_ctype *, _RuneLocale *); -__hidden int _GB2312_init(struct xlocale_ctype *, _RuneLocale *); -__hidden int _GBK_init(struct xlocale_ctype *, _RuneLocale *); -__hidden int _BIG5_init(struct xlocale_ctype *, _RuneLocale *); -__hidden int _MSKanji_init(struct xlocale_ctype *, _RuneLocale *); +int _none_init(struct xlocale_ctype *, _RuneLocale *) __hidden; +int _UTF8_init(struct xlocale_ctype *, _RuneLocale *) __hidden; +int _EUC_CN_init(struct xlocale_ctype *, _RuneLocale *) __hidden; +int _EUC_JP_init(struct xlocale_ctype *, _RuneLocale *) __hidden; +int _EUC_KR_init(struct xlocale_ctype *, _RuneLocale *) __hidden; +int _EUC_TW_init(struct xlocale_ctype *, _RuneLocale *) __hidden; +int _GB18030_init(struct xlocale_ctype *, _RuneLocale *) __hidden; +int _GB2312_init(struct xlocale_ctype *, _RuneLocale *) __hidden; +int _GBK_init(struct xlocale_ctype *, _RuneLocale *) __hidden; +int _BIG5_init(struct xlocale_ctype *, _RuneLocale *) __hidden; +int _MSKanji_init(struct xlocale_ctype *, _RuneLocale *) __hidden; +int _ascii_init(struct xlocale_ctype *, _RuneLocale *) __hidden; typedef size_t (*mbrtowc_pfn_t)(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c index f5271c6..5988ebc 100644 --- a/lib/libc/net/getaddrinfo.c +++ b/lib/libc/net/getaddrinfo.c @@ -691,9 +691,8 @@ reorder(struct addrinfo *sentinel) return(n); /* allocate a temporary array for sort and initialization of it. */ - if ((aio = malloc(sizeof(*aio) * n)) == NULL) + if ((aio = calloc(n, sizeof(*aio))) == NULL) return(n); /* give up reordering */ - memset(aio, 0, sizeof(*aio) * n); /* retrieve address selection policy from the kernel */ TAILQ_INIT(&policyhead); @@ -1449,9 +1448,8 @@ copy_ai(const struct addrinfo *pai) size_t l; l = sizeof(*ai) + pai->ai_addrlen; - if ((ai = (struct addrinfo *)malloc(l)) == NULL) + if ((ai = calloc(1, l)) == NULL) return NULL; - memset(ai, 0, l); memcpy(ai, pai, sizeof(*ai)); ai->ai_addr = (struct sockaddr *)(void *)(ai + 1); memcpy(ai->ai_addr, pai->ai_addr, pai->ai_addrlen); @@ -1874,8 +1872,7 @@ addrinfo_unmarshal_func(char *buffer, size_t buffer_size, void *retval, size = new_ai.ai_addrlen + sizeof(struct addrinfo) + _ALIGNBYTES; - sentinel = (struct addrinfo *)malloc(size); - memset(sentinel, 0, size); + sentinel = calloc(1, size); memcpy(sentinel, &new_ai, sizeof(struct addrinfo)); sentinel->ai_addr = (struct sockaddr *)_ALIGN((char *)sentinel + @@ -1888,8 +1885,7 @@ addrinfo_unmarshal_func(char *buffer, size_t buffer_size, void *retval, memcpy(&size, p, sizeof(size_t)); p += sizeof(size_t); - sentinel->ai_canonname = (char *)malloc(size + 1); - memset(sentinel->ai_canonname, 0, size + 1); + sentinel->ai_canonname = calloc(1, size + 1); memcpy(sentinel->ai_canonname, p, size); p += size; diff --git a/lib/libc/x86/sys/__vdso_gettc.c b/lib/libc/x86/sys/__vdso_gettc.c index 743b3ad..5097ad5 100644 --- a/lib/libc/x86/sys/__vdso_gettc.c +++ b/lib/libc/x86/sys/__vdso_gettc.c @@ -45,6 +45,10 @@ __FBSDID("$FreeBSD$"); #include <machine/cpufunc.h> #include <machine/specialreg.h> #include <dev/acpica/acpi_hpet.h> +#ifdef __amd64__ +#include <machine/atomic.h> +#include <dev/hyperv/hyperv.h> +#endif #include "libc_private.h" static void @@ -144,6 +148,67 @@ __vdso_init_hpet(uint32_t u) _close(fd); } +#ifdef __amd64__ + +#define HYPERV_REFTSC_DEVPATH "/dev/" HYPERV_REFTSC_DEVNAME + +/* + * NOTE: + * We use 'NULL' for this variable to indicate that initialization + * is required. And if this variable is 'MAP_FAILED', then Hyper-V + * reference TSC can not be used, e.g. in misconfigured jail. + */ +static struct hyperv_reftsc *hyperv_ref_tsc; + +static void +__vdso_init_hyperv_tsc(void) +{ + int fd; + + fd = _open(HYPERV_REFTSC_DEVPATH, O_RDONLY); + if (fd < 0) { + /* Prevent the caller from re-entering. */ + hyperv_ref_tsc = MAP_FAILED; + return; + } + hyperv_ref_tsc = mmap(NULL, sizeof(*hyperv_ref_tsc), PROT_READ, + MAP_SHARED, fd, 0); + _close(fd); +} + +static int +__vdso_hyperv_tsc(struct hyperv_reftsc *tsc_ref, u_int *tc) +{ + uint64_t disc, ret, tsc, scale; + uint32_t seq; + int64_t ofs; + + while ((seq = atomic_load_acq_int(&tsc_ref->tsc_seq)) != 0) { + scale = tsc_ref->tsc_scale; + ofs = tsc_ref->tsc_ofs; + + lfence_mb(); + tsc = rdtsc(); + + /* ret = ((tsc * scale) >> 64) + ofs */ + __asm__ __volatile__ ("mulq %3" : + "=d" (ret), "=a" (disc) : + "a" (tsc), "r" (scale)); + ret += ofs; + + atomic_thread_fence_acq(); + if (tsc_ref->tsc_seq == seq) { + *tc = ret; + return (0); + } + + /* Sequence changed; re-sync. */ + } + return (ENOSYS); +} + +#endif /* __amd64__ */ + #pragma weak __vdso_gettc int __vdso_gettc(const struct vdso_timehands *th, u_int *tc) @@ -165,6 +230,14 @@ __vdso_gettc(const struct vdso_timehands *th, u_int *tc) return (ENOSYS); *tc = *(volatile uint32_t *)(hpet_dev_map + HPET_MAIN_COUNTER); return (0); +#ifdef __amd64__ + case VDSO_TH_ALGO_X86_HVTSC: + if (hyperv_ref_tsc == NULL) + __vdso_init_hyperv_tsc(); + if (hyperv_ref_tsc == MAP_FAILED) + return (ENOSYS); + return (__vdso_hyperv_tsc(hyperv_ref_tsc, tc)); +#endif default: return (ENOSYS); } |