summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2017-01-09 12:07:59 -0200
committerRenato Botelho <renato@netgate.com>2017-01-09 12:07:59 -0200
commitbaeac042059786f1ed0cca7ca4a4a32721362cab (patch)
tree3b848bddaf0f478d0c0651c8ee62129d3d9bacf5 /lib/libc
parent1af1408e09373ae856cfef567d79849c7e7e0d25 (diff)
parentf91948fdd5322d9aae1e8785976df69612c1999f (diff)
downloadFreeBSD-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.h24
-rw-r--r--lib/libc/net/getaddrinfo.c12
-rw-r--r--lib/libc/x86/sys/__vdso_gettc.c73
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);
}
OpenPOWER on IntegriCloud