Deleted Added
full compact
__vdso_gettc.c (311376) __vdso_gettc.c (311927)
1/*-
2 * Copyright (c) 2012 Konstantin Belousov <kib@FreeBSD.org>
1/*-
2 * Copyright (c) 2012 Konstantin Belousov <kib@FreeBSD.org>
3 * Copyright (c) 2016 The FreeBSD Foundation
3 * Copyright (c) 2016, 2017 The FreeBSD Foundation
4 * All rights reserved.
5 *
6 * Portions of this software were developed by Konstantin Belousov
7 * under sponsorship from the FreeBSD Foundation.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:

--- 12 unchanged lines hidden (view full) ---

24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
4 * All rights reserved.
5 *
6 * Portions of this software were developed by Konstantin Belousov
7 * under sponsorship from the FreeBSD Foundation.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:

--- 12 unchanged lines hidden (view full) ---

24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: stable/11/lib/libc/x86/sys/__vdso_gettc.c 311376 2017-01-05 07:42:08Z sephe $");
32__FBSDID("$FreeBSD: stable/11/lib/libc/x86/sys/__vdso_gettc.c 311927 2017-01-11 11:25:18Z kib $");
33
34#include <sys/param.h>
35#include "namespace.h"
36#include <sys/elf.h>
37#include <sys/fcntl.h>
38#include <sys/mman.h>
39#include <sys/time.h>
40#include <sys/vdso.h>
41#include <errno.h>
42#include <string.h>
43#include <unistd.h>
44#include "un-namespace.h"
33
34#include <sys/param.h>
35#include "namespace.h"
36#include <sys/elf.h>
37#include <sys/fcntl.h>
38#include <sys/mman.h>
39#include <sys/time.h>
40#include <sys/vdso.h>
41#include <errno.h>
42#include <string.h>
43#include <unistd.h>
44#include "un-namespace.h"
45#include <machine/atomic.h>
45#include <machine/cpufunc.h>
46#include <machine/specialreg.h>
47#include <dev/acpica/acpi_hpet.h>
48#ifdef __amd64__
46#include <machine/cpufunc.h>
47#include <machine/specialreg.h>
48#include <dev/acpica/acpi_hpet.h>
49#ifdef __amd64__
49#include <machine/atomic.h>
50#include <dev/hyperv/hyperv.h>
51#endif
52#include "libc_private.h"
53
54static void
55lfence_mb(void)
56{
57#if defined(__i386__)

--- 52 unchanged lines hidden (view full) ---

110static u_int
111__vdso_rdtsc32(void)
112{
113
114 lfence_mb();
115 return (rdtsc32());
116}
117
50#include <dev/hyperv/hyperv.h>
51#endif
52#include "libc_private.h"
53
54static void
55lfence_mb(void)
56{
57#if defined(__i386__)

--- 52 unchanged lines hidden (view full) ---

110static u_int
111__vdso_rdtsc32(void)
112{
113
114 lfence_mb();
115 return (rdtsc32());
116}
117
118static char *hpet_dev_map = NULL;
119static uint32_t hpet_idx = 0xffffffff;
118#define HPET_DEV_MAP_MAX 10
119static volatile char *hpet_dev_map[HPET_DEV_MAP_MAX];
120
121static void
122__vdso_init_hpet(uint32_t u)
123{
124 static const char devprefix[] = "/dev/hpet";
125 char devname[64], *c, *c1, t;
120
121static void
122__vdso_init_hpet(uint32_t u)
123{
124 static const char devprefix[] = "/dev/hpet";
125 char devname[64], *c, *c1, t;
126 volatile char *new_map, *old_map;
127 uint32_t u1;
126 int fd;
127
128 c1 = c = stpcpy(devname, devprefix);
128 int fd;
129
130 c1 = c = stpcpy(devname, devprefix);
129 u = hpet_idx;
131 u1 = u;
130 do {
132 do {
131 *c++ = u % 10 + '0';
132 u /= 10;
133 } while (u != 0);
133 *c++ = u1 % 10 + '0';
134 u1 /= 10;
135 } while (u1 != 0);
134 *c = '\0';
135 for (c--; c1 != c; c1++, c--) {
136 t = *c1;
137 *c1 = *c;
138 *c = t;
139 }
136 *c = '\0';
137 for (c--; c1 != c; c1++, c--) {
138 t = *c1;
139 *c1 = *c;
140 *c = t;
141 }
142
143 old_map = hpet_dev_map[u];
144 if (old_map != NULL)
145 return;
146
140 fd = _open(devname, O_RDONLY);
141 if (fd == -1) {
147 fd = _open(devname, O_RDONLY);
148 if (fd == -1) {
142 hpet_dev_map = MAP_FAILED;
149 atomic_cmpset_rel_ptr((volatile uintptr_t *)&hpet_dev_map[u],
150 (uintptr_t)old_map, (uintptr_t)MAP_FAILED);
143 return;
144 }
151 return;
152 }
145 if (hpet_dev_map != NULL && hpet_dev_map != MAP_FAILED)
146 munmap(hpet_dev_map, PAGE_SIZE);
147 hpet_dev_map = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, 0);
153 new_map = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, 0);
148 _close(fd);
154 _close(fd);
155 if (atomic_cmpset_rel_ptr((volatile uintptr_t *)&hpet_dev_map[u],
156 (uintptr_t)old_map, (uintptr_t)new_map) == 0 &&
157 new_map != MAP_FAILED)
158 munmap((void *)new_map, PAGE_SIZE);
149}
150
151#ifdef __amd64__
152
153#define HYPERV_REFTSC_DEVPATH "/dev/" HYPERV_REFTSC_DEVNAME
154
155/*
156 * NOTE:

--- 51 unchanged lines hidden (view full) ---

208}
209
210#endif /* __amd64__ */
211
212#pragma weak __vdso_gettc
213int
214__vdso_gettc(const struct vdso_timehands *th, u_int *tc)
215{
159}
160
161#ifdef __amd64__
162
163#define HYPERV_REFTSC_DEVPATH "/dev/" HYPERV_REFTSC_DEVNAME
164
165/*
166 * NOTE:

--- 51 unchanged lines hidden (view full) ---

218}
219
220#endif /* __amd64__ */
221
222#pragma weak __vdso_gettc
223int
224__vdso_gettc(const struct vdso_timehands *th, u_int *tc)
225{
216 uint32_t tmp;
226 volatile char *map;
227 uint32_t idx;
217
218 switch (th->th_algo) {
219 case VDSO_TH_ALGO_X86_TSC:
220 *tc = th->th_x86_shift > 0 ? __vdso_gettc_rdtsc_low(th) :
221 __vdso_rdtsc32();
222 return (0);
223 case VDSO_TH_ALGO_X86_HPET:
228
229 switch (th->th_algo) {
230 case VDSO_TH_ALGO_X86_TSC:
231 *tc = th->th_x86_shift > 0 ? __vdso_gettc_rdtsc_low(th) :
232 __vdso_rdtsc32();
233 return (0);
234 case VDSO_TH_ALGO_X86_HPET:
224 tmp = th->th_x86_hpet_idx;
225 if (hpet_dev_map == NULL || tmp != hpet_idx) {
226 hpet_idx = tmp;
227 __vdso_init_hpet(hpet_idx);
235 idx = th->th_x86_hpet_idx;
236 if (idx >= HPET_DEV_MAP_MAX)
237 return (ENOSYS);
238 map = (volatile char *)atomic_load_acq_ptr(
239 (volatile uintptr_t *)&hpet_dev_map[idx]);
240 if (map == NULL) {
241 __vdso_init_hpet(idx);
242 map = (volatile char *)atomic_load_acq_ptr(
243 (volatile uintptr_t *)&hpet_dev_map[idx]);
228 }
244 }
229 if (hpet_dev_map == MAP_FAILED)
245 if (map == MAP_FAILED)
230 return (ENOSYS);
246 return (ENOSYS);
231 *tc = *(volatile uint32_t *)(hpet_dev_map + HPET_MAIN_COUNTER);
247 *tc = *(volatile uint32_t *)(map + HPET_MAIN_COUNTER);
232 return (0);
233#ifdef __amd64__
234 case VDSO_TH_ALGO_X86_HVTSC:
235 if (hyperv_ref_tsc == NULL)
236 __vdso_init_hyperv_tsc();
237 if (hyperv_ref_tsc == MAP_FAILED)
238 return (ENOSYS);
239 return (__vdso_hyperv_tsc(hyperv_ref_tsc, tc));

--- 13 unchanged lines hidden ---
248 return (0);
249#ifdef __amd64__
250 case VDSO_TH_ALGO_X86_HVTSC:
251 if (hyperv_ref_tsc == NULL)
252 __vdso_init_hyperv_tsc();
253 if (hyperv_ref_tsc == MAP_FAILED)
254 return (ENOSYS);
255 return (__vdso_hyperv_tsc(hyperv_ref_tsc, tc));

--- 13 unchanged lines hidden ---