ALSA: Avoid using timespec for struct snd_pcm_status
The struct snd_pcm_status will use 'timespec' type variables to record timestamp, which is not year 2038 safe on 32bits system. Userspace will use SNDRV_PCM_IOCTL_STATUS and SNDRV_PCM_IOCTL_STATUS_EXT as commands to issue ioctl() to fill the 'snd_pcm_status' structure in userspace. The command number is always defined through _IOR/_IOW/IORW, so when userspace changes the definition of 'struct timespec' to use 64-bit types, the command number also changes. Thus in the kernel, we now need to define two versions of each such ioctl and corresponding ioctl commands to handle 32bit time_t and 64bit time_t in native mode: struct snd_pcm_status32 { ...... s32 trigger_tstamp_sec; s32 trigger_tstamp_nsec; ...... s32 audio_tstamp_sec; s32 audio_tstamp_nsec; ...... }; struct snd_pcm_status64 { ...... s32 trigger_tstamp_sec; s32 trigger_tstamp_nsec; ...... s32 audio_tstamp_sec; s32 audio_tstamp_nsec; ...... }; Moreover in compat file, we renamed or introduced new structures to handle 32bit/64bit time_t in compatible mode. The 'struct snd_pcm_status32' and snd_pcm_status_user32() are used to handle 32bit time_t in compat mode. 'struct compat_snd_pcm_status64' and snd_pcm_status_user_compat64() are used to handle 64bit time_t. The implicit padding before timespec is made explicit to avoid incompatible structure layout between 32-bit and 64-bit x86 due to the different alignment requirements, and the snd_pcm_status structure is now hidden from the kernel to avoid relying on the timespec definitio definitionn Finally we can replace SNDRV_PCM_IOCTL_STATUS and SNDRV_PCM_IOCTL_STATUS_EXT with new commands and introduce new functions to fill new 'struct snd_pcm_status64' instead of using unsafe 'struct snd_pcm_status'. Then in future, the new commands can be matched when userspace changes 'timespec' to 64bit type to make a size change of 'struct snd_pcm_status'. When glibc changes time_t to 64-bit, any recompiled program will issue ioctl commands that the kernel does not understand without this patch. Signed-off-by: Baolin Wang <baolin.wang@linaro.org> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:

committed by
Arnd Bergmann

parent
a4e7dd35b9
commit
3ddee7f88a
@@ -44,6 +44,7 @@ struct snd_pcm_hardware {
|
||||
size_t fifo_size; /* fifo size in bytes */
|
||||
};
|
||||
|
||||
struct snd_pcm_status64;
|
||||
struct snd_pcm_substream;
|
||||
|
||||
struct snd_pcm_audio_tstamp_config; /* definitions further down */
|
||||
@@ -558,8 +559,8 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree);
|
||||
int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info);
|
||||
int snd_pcm_info_user(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_info __user *info);
|
||||
int snd_pcm_status(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_status *status);
|
||||
int snd_pcm_status64(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_status64 *status);
|
||||
int snd_pcm_start(struct snd_pcm_substream *substream);
|
||||
int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t status);
|
||||
int snd_pcm_drain_done(struct snd_pcm_substream *substream);
|
||||
@@ -1422,4 +1423,55 @@ static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format)
|
||||
#define pcm_dbg(pcm, fmt, args...) \
|
||||
dev_dbg((pcm)->card->dev, fmt, ##args)
|
||||
|
||||
struct snd_pcm_status64 {
|
||||
snd_pcm_state_t state; /* stream state */
|
||||
u8 rsvd[4];
|
||||
s64 trigger_tstamp_sec; /* time when stream was started/stopped/paused */
|
||||
s64 trigger_tstamp_nsec;
|
||||
s64 tstamp_sec; /* reference timestamp */
|
||||
s64 tstamp_nsec;
|
||||
snd_pcm_uframes_t appl_ptr; /* appl ptr */
|
||||
snd_pcm_uframes_t hw_ptr; /* hw ptr */
|
||||
snd_pcm_sframes_t delay; /* current delay in frames */
|
||||
snd_pcm_uframes_t avail; /* number of frames available */
|
||||
snd_pcm_uframes_t avail_max; /* max frames available on hw since last status */
|
||||
snd_pcm_uframes_t overrange; /* count of ADC (capture) overrange detections from last status */
|
||||
snd_pcm_state_t suspended_state; /* suspended stream state */
|
||||
__u32 audio_tstamp_data; /* needed for 64-bit alignment, used for configs/report to/from userspace */
|
||||
s64 audio_tstamp_sec; /* sample counter, wall clock, PHC or on-demand sync'ed */
|
||||
s64 audio_tstamp_nsec;
|
||||
s64 driver_tstamp_sec; /* useful in case reference system tstamp is reported with delay */
|
||||
s64 driver_tstamp_nsec;
|
||||
__u32 audio_tstamp_accuracy; /* in ns units, only valid if indicated in audio_tstamp_data */
|
||||
unsigned char reserved[52-4*sizeof(s64)]; /* must be filled with zero */
|
||||
};
|
||||
|
||||
#define SNDRV_PCM_IOCTL_STATUS64 _IOR('A', 0x20, struct snd_pcm_status64)
|
||||
#define SNDRV_PCM_IOCTL_STATUS_EXT64 _IOWR('A', 0x24, struct snd_pcm_status64)
|
||||
|
||||
struct snd_pcm_status32 {
|
||||
s32 state; /* stream state */
|
||||
s32 trigger_tstamp_sec; /* time when stream was started/stopped/paused */
|
||||
s32 trigger_tstamp_nsec;
|
||||
s32 tstamp_sec; /* reference timestamp */
|
||||
s32 tstamp_nsec;
|
||||
u32 appl_ptr; /* appl ptr */
|
||||
u32 hw_ptr; /* hw ptr */
|
||||
s32 delay; /* current delay in frames */
|
||||
u32 avail; /* number of frames available */
|
||||
u32 avail_max; /* max frames available on hw since last status */
|
||||
u32 overrange; /* count of ADC (capture) overrange detections from last status */
|
||||
s32 suspended_state; /* suspended stream state */
|
||||
u32 audio_tstamp_data; /* needed for 64-bit alignment, used for configs/report to/from userspace */
|
||||
s32 audio_tstamp_sec; /* sample counter, wall clock, PHC or on-demand sync'ed */
|
||||
s32 audio_tstamp_nsec;
|
||||
s32 driver_tstamp_sec; /* useful in case reference system tstamp is reported with delay */
|
||||
s32 driver_tstamp_nsec;
|
||||
u32 audio_tstamp_accuracy; /* in ns units, only valid if indicated in audio_tstamp_data */
|
||||
unsigned char reserved[52-4*sizeof(s32)]; /* must be filled with zero */
|
||||
};
|
||||
|
||||
#define SNDRV_PCM_IOCTL_STATUS32 _IOR('A', 0x20, struct snd_pcm_status32)
|
||||
#define SNDRV_PCM_IOCTL_STATUS_EXT32 _IOWR('A', 0x24, struct snd_pcm_status32)
|
||||
|
||||
#endif /* __SOUND_PCM_H */
|
||||
|
Reference in New Issue
Block a user