mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-06 04:19:23 -04:00
ALSA: control: Fix power_ref lock order for compat code, too
In the previous change for swapping the power_ref and controls_rwsem
lock order, the code path for the compat layer was forgotten.
This patch covers the remaining code.
Fixes: fcc62b1910 ("ALSA: control: Take power_ref lock primarily")
Link: https://patch.msgid.link/20240808163128.20383-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
@@ -79,6 +79,7 @@ struct snd_ctl_elem_info32 {
|
||||
static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
|
||||
struct snd_ctl_elem_info32 __user *data32)
|
||||
{
|
||||
struct snd_card *card = ctl->card;
|
||||
struct snd_ctl_elem_info *data __free(kfree) = NULL;
|
||||
int err;
|
||||
|
||||
@@ -95,7 +96,11 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
|
||||
if (get_user(data->value.enumerated.item, &data32->value.enumerated.item))
|
||||
return -EFAULT;
|
||||
|
||||
err = snd_power_ref_and_wait(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = snd_ctl_elem_info(ctl, data);
|
||||
snd_power_unref(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
/* restore info to 32bit */
|
||||
@@ -175,10 +180,7 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
|
||||
if (info == NULL)
|
||||
return -ENOMEM;
|
||||
info->id = *id;
|
||||
err = snd_power_ref_and_wait(card);
|
||||
if (!err)
|
||||
err = kctl->info(kctl, info);
|
||||
snd_power_unref(card);
|
||||
err = kctl->info(kctl, info);
|
||||
if (err >= 0) {
|
||||
err = info->type;
|
||||
*countp = info->count;
|
||||
@@ -275,8 +277,8 @@ static int copy_ctl_value_to_user(void __user *userdata,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ctl_elem_read_user(struct snd_card *card,
|
||||
void __user *userdata, void __user *valuep)
|
||||
static int __ctl_elem_read_user(struct snd_card *card,
|
||||
void __user *userdata, void __user *valuep)
|
||||
{
|
||||
struct snd_ctl_elem_value *data __free(kfree) = NULL;
|
||||
int err, type, count;
|
||||
@@ -296,8 +298,21 @@ static int ctl_elem_read_user(struct snd_card *card,
|
||||
return copy_ctl_value_to_user(userdata, valuep, data, type, count);
|
||||
}
|
||||
|
||||
static int ctl_elem_write_user(struct snd_ctl_file *file,
|
||||
void __user *userdata, void __user *valuep)
|
||||
static int ctl_elem_read_user(struct snd_card *card,
|
||||
void __user *userdata, void __user *valuep)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = snd_power_ref_and_wait(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = __ctl_elem_read_user(card, userdata, valuep);
|
||||
snd_power_unref(card);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __ctl_elem_write_user(struct snd_ctl_file *file,
|
||||
void __user *userdata, void __user *valuep)
|
||||
{
|
||||
struct snd_ctl_elem_value *data __free(kfree) = NULL;
|
||||
struct snd_card *card = file->card;
|
||||
@@ -318,6 +333,20 @@ static int ctl_elem_write_user(struct snd_ctl_file *file,
|
||||
return copy_ctl_value_to_user(userdata, valuep, data, type, count);
|
||||
}
|
||||
|
||||
static int ctl_elem_write_user(struct snd_ctl_file *file,
|
||||
void __user *userdata, void __user *valuep)
|
||||
{
|
||||
struct snd_card *card = file->card;
|
||||
int err;
|
||||
|
||||
err = snd_power_ref_and_wait(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = __ctl_elem_write_user(file, userdata, valuep);
|
||||
snd_power_unref(card);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int snd_ctl_elem_read_user_compat(struct snd_card *card,
|
||||
struct snd_ctl_elem_value32 __user *data32)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user