152194fe9c
The input events use struct timeval to store event time, unfortunately
this structure is not y2038 safe and is being replaced in kernel with
y2038 safe structures.
Because of ABI concerns we can not change the size or the layout of
structure input_event, so we opt to re-interpreting the 'seconds' part
of timestamp as an unsigned value, effectively doubling the range of
values, to year 2106.
Newer glibc that has support for 32 bit applications to use 64 bit
time_t supplies __USE_TIME_BITS64 define [1], that we can use to present
the userspace with updated input_event layout. The updated layout will
cause the compile time breakage, alerting applications and distributions
maintainers to the issue. Existing 32 binaries will continue working
without any changes until 2038.
Ultimately userspace applications should switch to using monotonic or
boot time clocks, as realtime clock is not very well suited for input
event timestamps as it can go backwards (see a80b83b7b8
"Input: evdev -
add CLOCK_BOOTTIME support" by by John Stultz). With monotonic clock the
practical range of reported times will always fit into the pair of 32
bit values, as we do not expect any system to stay up for a hundred
years without a single reboot.
[1] https://sourceware.org/glibc/wiki/Y2038ProofnessDesign
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
Patchwork-Id: 10148083
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
81 lines
1.7 KiB
C
81 lines
1.7 KiB
C
#ifndef _INPUT_COMPAT_H
|
|
#define _INPUT_COMPAT_H
|
|
|
|
/*
|
|
* 32bit compatibility wrappers for the input subsystem.
|
|
*
|
|
* Very heavily based on evdev.c - Copyright (c) 1999-2002 Vojtech Pavlik
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 as published by
|
|
* the Free Software Foundation.
|
|
*/
|
|
|
|
#include <linux/compiler.h>
|
|
#include <linux/compat.h>
|
|
#include <linux/input.h>
|
|
|
|
#ifdef CONFIG_COMPAT
|
|
|
|
struct input_event_compat {
|
|
compat_ulong_t sec;
|
|
compat_ulong_t usec;
|
|
__u16 type;
|
|
__u16 code;
|
|
__s32 value;
|
|
};
|
|
|
|
struct ff_periodic_effect_compat {
|
|
__u16 waveform;
|
|
__u16 period;
|
|
__s16 magnitude;
|
|
__s16 offset;
|
|
__u16 phase;
|
|
|
|
struct ff_envelope envelope;
|
|
|
|
__u32 custom_len;
|
|
compat_uptr_t custom_data;
|
|
};
|
|
|
|
struct ff_effect_compat {
|
|
__u16 type;
|
|
__s16 id;
|
|
__u16 direction;
|
|
struct ff_trigger trigger;
|
|
struct ff_replay replay;
|
|
|
|
union {
|
|
struct ff_constant_effect constant;
|
|
struct ff_ramp_effect ramp;
|
|
struct ff_periodic_effect_compat periodic;
|
|
struct ff_condition_effect condition[2]; /* One for each axis */
|
|
struct ff_rumble_effect rumble;
|
|
} u;
|
|
};
|
|
|
|
static inline size_t input_event_size(void)
|
|
{
|
|
return (in_compat_syscall() && !COMPAT_USE_64BIT_TIME) ?
|
|
sizeof(struct input_event_compat) : sizeof(struct input_event);
|
|
}
|
|
|
|
#else
|
|
|
|
static inline size_t input_event_size(void)
|
|
{
|
|
return sizeof(struct input_event);
|
|
}
|
|
|
|
#endif /* CONFIG_COMPAT */
|
|
|
|
int input_event_from_user(const char __user *buffer,
|
|
struct input_event *event);
|
|
|
|
int input_event_to_user(char __user *buffer,
|
|
const struct input_event *event);
|
|
|
|
int input_ff_effect_from_user(const char __user *buffer, size_t size,
|
|
struct ff_effect *effect);
|
|
|
|
#endif /* _INPUT_COMPAT_H */
|