Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

lib/vdso: Allow architectures to provide the vdso data pointer

On powerpc, __arch_get_vdso_data() clobbers the link register, requiring
the caller to save it.

As the parent function already has to set a stack frame and saves the link
register before calling the C vdso function, retrieving the vdso data
pointer there is less overhead.

Split out the functional code from the __cvdso.*() interfaces into new
static functions which can either be called from the existing interfaces
with the vdso data pointer supplied via __arch_get_vdso_data() or directly
from ASM code.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Link: https://lore.kernel.org/r/abf97996602ef07223fec30c005df78e5ed41b2e.1580399657.git.christophe.leroy@c-s.fr
Link: https://lkml.kernel.org/r/20200207124403.965789141@linutronix.de



authored by

Christophe Leroy and committed by
Thomas Gleixner
e876f0b6 8345228c

+57 -17
+57 -17
lib/vdso/gettimeofday.c
··· 233 233 } 234 234 235 235 static __maybe_unused int 236 - __cvdso_clock_gettime_common(clockid_t clock, struct __kernel_timespec *ts) 236 + __cvdso_clock_gettime_common(const struct vdso_data *vd, clockid_t clock, 237 + struct __kernel_timespec *ts) 237 238 { 238 - const struct vdso_data *vd = __arch_get_vdso_data(); 239 239 u32 msk; 240 240 241 241 /* Check for negative values or invalid clocks */ ··· 260 260 } 261 261 262 262 static __maybe_unused int 263 - __cvdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts) 263 + __cvdso_clock_gettime_data(const struct vdso_data *vd, clockid_t clock, 264 + struct __kernel_timespec *ts) 264 265 { 265 - int ret = __cvdso_clock_gettime_common(clock, ts); 266 + int ret = __cvdso_clock_gettime_common(vd, clock, ts); 266 267 267 268 if (unlikely(ret)) 268 269 return clock_gettime_fallback(clock, ts); 269 270 return 0; 270 271 } 271 272 273 + static __maybe_unused int 274 + __cvdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts) 275 + { 276 + return __cvdso_clock_gettime_data(__arch_get_vdso_data(), clock, ts); 277 + } 278 + 272 279 #ifdef BUILD_VDSO32 273 280 static __maybe_unused int 274 - __cvdso_clock_gettime32(clockid_t clock, struct old_timespec32 *res) 281 + __cvdso_clock_gettime32_data(const struct vdso_data *vd, clockid_t clock, 282 + struct old_timespec32 *res) 275 283 { 276 284 struct __kernel_timespec ts; 277 285 int ret; 278 286 279 - ret = __cvdso_clock_gettime_common(clock, &ts); 287 + ret = __cvdso_clock_gettime_common(vd, clock, &ts); 280 288 281 289 if (unlikely(ret)) 282 290 return clock_gettime32_fallback(clock, res); ··· 295 287 296 288 return ret; 297 289 } 290 + 291 + static __maybe_unused int 292 + __cvdso_clock_gettime32(clockid_t clock, struct old_timespec32 *res) 293 + { 294 + return __cvdso_clock_gettime32_data(__arch_get_vdso_data(), clock, res); 295 + } 298 296 #endif /* BUILD_VDSO32 */ 299 297 300 298 static __maybe_unused int 301 - __cvdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) 299 + __cvdso_gettimeofday_data(const struct vdso_data *vd, 300 + struct __kernel_old_timeval *tv, struct timezone *tz) 302 301 { 303 - const struct vdso_data *vd = __arch_get_vdso_data(); 304 302 305 303 if (likely(tv != NULL)) { 306 304 struct __kernel_timespec ts; ··· 330 316 return 0; 331 317 } 332 318 333 - #ifdef VDSO_HAS_TIME 334 - static __maybe_unused __kernel_old_time_t __cvdso_time(__kernel_old_time_t *time) 319 + static __maybe_unused int 320 + __cvdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) 335 321 { 336 - const struct vdso_data *vd = __arch_get_vdso_data(); 322 + return __cvdso_gettimeofday_data(__arch_get_vdso_data(), tv, tz); 323 + } 324 + 325 + #ifdef VDSO_HAS_TIME 326 + static __maybe_unused __kernel_old_time_t 327 + __cvdso_time_data(const struct vdso_data *vd, __kernel_old_time_t *time) 328 + { 337 329 __kernel_old_time_t t; 338 330 339 331 if (IS_ENABLED(CONFIG_TIME_NS) && ··· 353 333 354 334 return t; 355 335 } 336 + 337 + static __maybe_unused __kernel_old_time_t __cvdso_time(__kernel_old_time_t *time) 338 + { 339 + return __cvdso_time_data(__arch_get_vdso_data(), time); 340 + } 356 341 #endif /* VDSO_HAS_TIME */ 357 342 358 343 #ifdef VDSO_HAS_CLOCK_GETRES 359 344 static __maybe_unused 360 - int __cvdso_clock_getres_common(clockid_t clock, struct __kernel_timespec *res) 345 + int __cvdso_clock_getres_common(const struct vdso_data *vd, clockid_t clock, 346 + struct __kernel_timespec *res) 361 347 { 362 - const struct vdso_data *vd = __arch_get_vdso_data(); 363 348 u32 msk; 364 349 u64 ns; 365 350 ··· 403 378 } 404 379 405 380 static __maybe_unused 406 - int __cvdso_clock_getres(clockid_t clock, struct __kernel_timespec *res) 381 + int __cvdso_clock_getres_data(const struct vdso_data *vd, clockid_t clock, 382 + struct __kernel_timespec *res) 407 383 { 408 - int ret = __cvdso_clock_getres_common(clock, res); 384 + int ret = __cvdso_clock_getres_common(vd, clock, res); 409 385 410 386 if (unlikely(ret)) 411 387 return clock_getres_fallback(clock, res); 412 388 return 0; 413 389 } 414 390 391 + static __maybe_unused 392 + int __cvdso_clock_getres(clockid_t clock, struct __kernel_timespec *res) 393 + { 394 + return __cvdso_clock_getres_data(__arch_get_vdso_data(), clock, res); 395 + } 396 + 415 397 #ifdef BUILD_VDSO32 416 398 static __maybe_unused int 417 - __cvdso_clock_getres_time32(clockid_t clock, struct old_timespec32 *res) 399 + __cvdso_clock_getres_time32_data(const struct vdso_data *vd, clockid_t clock, 400 + struct old_timespec32 *res) 418 401 { 419 402 struct __kernel_timespec ts; 420 403 int ret; 421 404 422 - ret = __cvdso_clock_getres_common(clock, &ts); 405 + ret = __cvdso_clock_getres_common(vd, clock, &ts); 423 406 424 407 if (unlikely(ret)) 425 408 return clock_getres32_fallback(clock, res); ··· 437 404 res->tv_nsec = ts.tv_nsec; 438 405 } 439 406 return ret; 407 + } 408 + 409 + static __maybe_unused int 410 + __cvdso_clock_getres_time32(clockid_t clock, struct old_timespec32 *res) 411 + { 412 + return __cvdso_clock_getres_time32_data(__arch_get_vdso_data(), 413 + clock, res); 440 414 } 441 415 #endif /* BUILD_VDSO32 */ 442 416 #endif /* VDSO_HAS_CLOCK_GETRES */