Loading sound/core/pcm_compat.c +16 −0 Original line number Diff line number Diff line Loading @@ -480,6 +480,20 @@ static int snd_compressed_ioctl32(struct snd_pcm_substream *substream, pr_debug("%s called with cmd = %d\n", __func__, cmd); return err; } static int snd_user_ioctl32(struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { struct snd_pcm_runtime *runtime; int err = -ENOIOCTLCMD; if (PCM_RUNTIME_CHECK(substream)) return -ENXIO; runtime = substream->runtime; if (substream->ops->compat_ioctl) err = substream->ops->compat_ioctl(substream, cmd, arg); return err; } static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) { Loading Loading @@ -551,6 +565,8 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l default: if (_IOC_TYPE(cmd) == 'C') return snd_compressed_ioctl32(substream, cmd, argp); else if (_IOC_TYPE(cmd) == 'U') return snd_user_ioctl32(substream, cmd, argp); } return -ENOIOCTLCMD; Loading sound/soc/msm/qdsp6v2/msm-lsm-client.c +162 −2 Original line number Diff line number Diff line Loading @@ -311,6 +311,165 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, return rc; } #ifdef CONFIG_COMPAT struct snd_lsm_sound_model32 { compat_uptr_t data; u32 data_size; enum lsm_detection_mode detection_mode; u16 min_keyw_confidence; u16 min_user_confidence; bool detect_failure; }; struct snd_lsm_event_status32 { u16 status; u16 payload_size; u8 payload[0]; }; struct snd_lsm_sound_model_v2_32 { compat_uptr_t data; compat_uptr_t confidence_level; u32 data_size; enum lsm_detection_mode detection_mode; u8 num_confidence_levels; bool detect_failure; }; enum { SNDRV_LSM_REG_SND_MODEL32 = _IOW('U', 0x00, struct snd_lsm_sound_model32), SNDRV_LSM_EVENT_STATUS32 = _IOW('U', 0x02, struct snd_lsm_event_status32), SNDRV_LSM_REG_SND_MODEL_V2_32 = _IOW('U', 0x07, struct snd_lsm_sound_model_v2_32), }; static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { struct snd_pcm_runtime *runtime; int err = 0; u32 size = 0; if (PCM_RUNTIME_CHECK(substream)) return -ENXIO; runtime = substream->runtime; switch (cmd) { case SNDRV_LSM_REG_SND_MODEL32: { struct snd_lsm_sound_model32 snd_model32; struct snd_lsm_sound_model snd_model; if (copy_from_user(&snd_model32, arg, sizeof(struct snd_lsm_sound_model32))) { err = -EFAULT; pr_err("%s: copy user failed ioctl %s, size %zd\n", __func__, "SNDRV_LSM_REG_SND_MODEL32", sizeof(struct snd_lsm_sound_model32)); } else { snd_model.data = compat_ptr(snd_model32.data); snd_model.data_size = snd_model32.data_size; snd_model.detect_failure = snd_model32.detect_failure; snd_model.detection_mode = snd_model32.detection_mode; snd_model.min_keyw_confidence = snd_model32.min_keyw_confidence; snd_model.min_user_confidence = snd_model32.min_user_confidence; cmd = SNDRV_LSM_REG_SND_MODEL; err = msm_lsm_ioctl_shared(substream, cmd, &snd_model); if (err) pr_err("%s ioctl %s failed err %d\n", __func__, "SNDRV_LSM_REG_SND_MODEL32", err); } break; } case SNDRV_LSM_EVENT_STATUS32: { struct snd_lsm_event_status32 userarg32, *user32 = NULL; struct snd_lsm_event_status *user = NULL; if (copy_from_user(&userarg32, arg, sizeof(userarg32))) { pr_err("%s: err copyuser ioctl %s\n", __func__, "SNDRV_LSM_EVENT_STATUS32"); return -EFAULT; } size = sizeof(*user) + userarg32.payload_size; user = kmalloc(size, GFP_KERNEL); if (!user) { pr_err("%s: Allocation failed event status size %d\n", __func__, size); err = -EFAULT; } else { cmd = SNDRV_LSM_EVENT_STATUS; user->payload_size = userarg32.payload_size; err = msm_lsm_ioctl_shared(substream, cmd, user); } /* Update size with actual payload size */ size = sizeof(userarg32) + user->payload_size; if (!err && !access_ok(VERIFY_WRITE, arg, size)) { pr_err("%s: write verify failed size %d\n", __func__, size); err = -EFAULT; } if (!err) { user32 = kmalloc(size, GFP_KERNEL); if (!user32) { pr_err("%s: Allocation event user status size %d\n" , __func__, size); err = -EFAULT; } else { user32->status = user->status; user32->payload_size = user->payload_size; memcpy(user32->payload, user->payload, user32->payload_size); } } if (!err && (copy_to_user(arg, user32, size))) { pr_err("%s: failed to copy payload %d", __func__, size); err = -EFAULT; } kfree(user); kfree(user32); if (err) pr_err("%s: lsmevent failed %d", __func__, err); break; } case SNDRV_LSM_REG_SND_MODEL_V2_32: { struct snd_lsm_sound_model_v2_32 snd_modelv232; struct snd_lsm_sound_model_v2 snd_modelv2; if (copy_from_user(&snd_modelv232, arg, sizeof(snd_modelv232))) { err = -EFAULT; pr_err("%s: copy user failed, size %zd %s\n", __func__, sizeof(struct snd_lsm_sound_model_v2_32), "SNDRV_LSM_REG_SND_MODEL_V2_32"); } else { snd_modelv2.confidence_level = compat_ptr(snd_modelv232.confidence_level); snd_modelv2.data = compat_ptr(snd_modelv232.data); snd_modelv2.data_size = snd_modelv232.data_size; snd_modelv2.detect_failure = snd_modelv232.detect_failure; snd_modelv2.detection_mode = snd_modelv232.detection_mode; snd_modelv2.num_confidence_levels = snd_modelv232.num_confidence_levels; cmd = SNDRV_LSM_REG_SND_MODEL_V2; err = msm_lsm_ioctl_shared(substream, cmd, &snd_modelv2); if (err) pr_err("%s: ioctl %s failed\n", __func__, "SNDDRV_LSM_REG_SND_MODEL_V2_32"); } break; } default: err = msm_lsm_ioctl_shared(substream, cmd, arg); break; } return err; } #else #define msm_lsm_ioctl_compat NULL #endif static int msm_lsm_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) Loading Loading @@ -438,6 +597,8 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) __func__); return -ENOMEM; } spin_lock_init(&prtd->event_lock); init_waitqueue_head(&prtd->event_wait); prtd->substream = substream; prtd->lsm_client = q6lsm_client_alloc( (lsm_app_cb)lsm_event_handler, prtd); Loading Loading @@ -470,8 +631,6 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream) pr_debug("%s: Session ID %d\n", __func__, prtd->lsm_client->session); prtd->lsm_client->started = false; spin_lock_init(&prtd->event_lock); init_waitqueue_head(&prtd->event_wait); runtime->private_data = prtd; return 0; } Loading Loading @@ -501,6 +660,7 @@ static struct snd_pcm_ops msm_lsm_ops = { .close = msm_lsm_close, .ioctl = msm_lsm_ioctl, .prepare = msm_lsm_prepare, .compat_ioctl = msm_lsm_ioctl_compat, }; static int msm_asoc_lsm_new(struct snd_soc_pcm_runtime *rtd) Loading Loading
sound/core/pcm_compat.c +16 −0 Original line number Diff line number Diff line Loading @@ -480,6 +480,20 @@ static int snd_compressed_ioctl32(struct snd_pcm_substream *substream, pr_debug("%s called with cmd = %d\n", __func__, cmd); return err; } static int snd_user_ioctl32(struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { struct snd_pcm_runtime *runtime; int err = -ENOIOCTLCMD; if (PCM_RUNTIME_CHECK(substream)) return -ENXIO; runtime = substream->runtime; if (substream->ops->compat_ioctl) err = substream->ops->compat_ioctl(substream, cmd, arg); return err; } static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) { Loading Loading @@ -551,6 +565,8 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l default: if (_IOC_TYPE(cmd) == 'C') return snd_compressed_ioctl32(substream, cmd, argp); else if (_IOC_TYPE(cmd) == 'U') return snd_user_ioctl32(substream, cmd, argp); } return -ENOIOCTLCMD; Loading
sound/soc/msm/qdsp6v2/msm-lsm-client.c +162 −2 Original line number Diff line number Diff line Loading @@ -311,6 +311,165 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream, return rc; } #ifdef CONFIG_COMPAT struct snd_lsm_sound_model32 { compat_uptr_t data; u32 data_size; enum lsm_detection_mode detection_mode; u16 min_keyw_confidence; u16 min_user_confidence; bool detect_failure; }; struct snd_lsm_event_status32 { u16 status; u16 payload_size; u8 payload[0]; }; struct snd_lsm_sound_model_v2_32 { compat_uptr_t data; compat_uptr_t confidence_level; u32 data_size; enum lsm_detection_mode detection_mode; u8 num_confidence_levels; bool detect_failure; }; enum { SNDRV_LSM_REG_SND_MODEL32 = _IOW('U', 0x00, struct snd_lsm_sound_model32), SNDRV_LSM_EVENT_STATUS32 = _IOW('U', 0x02, struct snd_lsm_event_status32), SNDRV_LSM_REG_SND_MODEL_V2_32 = _IOW('U', 0x07, struct snd_lsm_sound_model_v2_32), }; static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { struct snd_pcm_runtime *runtime; int err = 0; u32 size = 0; if (PCM_RUNTIME_CHECK(substream)) return -ENXIO; runtime = substream->runtime; switch (cmd) { case SNDRV_LSM_REG_SND_MODEL32: { struct snd_lsm_sound_model32 snd_model32; struct snd_lsm_sound_model snd_model; if (copy_from_user(&snd_model32, arg, sizeof(struct snd_lsm_sound_model32))) { err = -EFAULT; pr_err("%s: copy user failed ioctl %s, size %zd\n", __func__, "SNDRV_LSM_REG_SND_MODEL32", sizeof(struct snd_lsm_sound_model32)); } else { snd_model.data = compat_ptr(snd_model32.data); snd_model.data_size = snd_model32.data_size; snd_model.detect_failure = snd_model32.detect_failure; snd_model.detection_mode = snd_model32.detection_mode; snd_model.min_keyw_confidence = snd_model32.min_keyw_confidence; snd_model.min_user_confidence = snd_model32.min_user_confidence; cmd = SNDRV_LSM_REG_SND_MODEL; err = msm_lsm_ioctl_shared(substream, cmd, &snd_model); if (err) pr_err("%s ioctl %s failed err %d\n", __func__, "SNDRV_LSM_REG_SND_MODEL32", err); } break; } case SNDRV_LSM_EVENT_STATUS32: { struct snd_lsm_event_status32 userarg32, *user32 = NULL; struct snd_lsm_event_status *user = NULL; if (copy_from_user(&userarg32, arg, sizeof(userarg32))) { pr_err("%s: err copyuser ioctl %s\n", __func__, "SNDRV_LSM_EVENT_STATUS32"); return -EFAULT; } size = sizeof(*user) + userarg32.payload_size; user = kmalloc(size, GFP_KERNEL); if (!user) { pr_err("%s: Allocation failed event status size %d\n", __func__, size); err = -EFAULT; } else { cmd = SNDRV_LSM_EVENT_STATUS; user->payload_size = userarg32.payload_size; err = msm_lsm_ioctl_shared(substream, cmd, user); } /* Update size with actual payload size */ size = sizeof(userarg32) + user->payload_size; if (!err && !access_ok(VERIFY_WRITE, arg, size)) { pr_err("%s: write verify failed size %d\n", __func__, size); err = -EFAULT; } if (!err) { user32 = kmalloc(size, GFP_KERNEL); if (!user32) { pr_err("%s: Allocation event user status size %d\n" , __func__, size); err = -EFAULT; } else { user32->status = user->status; user32->payload_size = user->payload_size; memcpy(user32->payload, user->payload, user32->payload_size); } } if (!err && (copy_to_user(arg, user32, size))) { pr_err("%s: failed to copy payload %d", __func__, size); err = -EFAULT; } kfree(user); kfree(user32); if (err) pr_err("%s: lsmevent failed %d", __func__, err); break; } case SNDRV_LSM_REG_SND_MODEL_V2_32: { struct snd_lsm_sound_model_v2_32 snd_modelv232; struct snd_lsm_sound_model_v2 snd_modelv2; if (copy_from_user(&snd_modelv232, arg, sizeof(snd_modelv232))) { err = -EFAULT; pr_err("%s: copy user failed, size %zd %s\n", __func__, sizeof(struct snd_lsm_sound_model_v2_32), "SNDRV_LSM_REG_SND_MODEL_V2_32"); } else { snd_modelv2.confidence_level = compat_ptr(snd_modelv232.confidence_level); snd_modelv2.data = compat_ptr(snd_modelv232.data); snd_modelv2.data_size = snd_modelv232.data_size; snd_modelv2.detect_failure = snd_modelv232.detect_failure; snd_modelv2.detection_mode = snd_modelv232.detection_mode; snd_modelv2.num_confidence_levels = snd_modelv232.num_confidence_levels; cmd = SNDRV_LSM_REG_SND_MODEL_V2; err = msm_lsm_ioctl_shared(substream, cmd, &snd_modelv2); if (err) pr_err("%s: ioctl %s failed\n", __func__, "SNDDRV_LSM_REG_SND_MODEL_V2_32"); } break; } default: err = msm_lsm_ioctl_shared(substream, cmd, arg); break; } return err; } #else #define msm_lsm_ioctl_compat NULL #endif static int msm_lsm_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) Loading Loading @@ -438,6 +597,8 @@ static int msm_lsm_open(struct snd_pcm_substream *substream) __func__); return -ENOMEM; } spin_lock_init(&prtd->event_lock); init_waitqueue_head(&prtd->event_wait); prtd->substream = substream; prtd->lsm_client = q6lsm_client_alloc( (lsm_app_cb)lsm_event_handler, prtd); Loading Loading @@ -470,8 +631,6 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream) pr_debug("%s: Session ID %d\n", __func__, prtd->lsm_client->session); prtd->lsm_client->started = false; spin_lock_init(&prtd->event_lock); init_waitqueue_head(&prtd->event_wait); runtime->private_data = prtd; return 0; } Loading Loading @@ -501,6 +660,7 @@ static struct snd_pcm_ops msm_lsm_ops = { .close = msm_lsm_close, .ioctl = msm_lsm_ioctl, .prepare = msm_lsm_prepare, .compat_ioctl = msm_lsm_ioctl_compat, }; static int msm_asoc_lsm_new(struct snd_soc_pcm_runtime *rtd) Loading