]>
Commit | Line | Data |
---|---|---|
8d82f256 GKH |
1 | From 8f71370f4b02730e8c27faf460af7a3586e24e1f Mon Sep 17 00:00:00 2001 |
2 | From: Guenter Roeck <linux@roeck-us.net> | |
3 | Date: Fri, 22 Mar 2019 15:39:48 -0700 | |
4 | Subject: ASoC: intel: Fix crash at suspend/resume after failed codec registration | |
5 | ||
6 | From: Guenter Roeck <linux@roeck-us.net> | |
7 | ||
8 | commit 8f71370f4b02730e8c27faf460af7a3586e24e1f upstream. | |
9 | ||
10 | If codec registration fails after the ASoC Intel SST driver has been probed, | |
11 | the kernel will Oops and crash at suspend/resume. | |
12 | ||
13 | general protection fault: 0000 [#1] PREEMPT SMP KASAN PTI | |
14 | CPU: 1 PID: 2811 Comm: cat Tainted: G W 4.19.30 #15 | |
15 | Hardware name: GOOGLE Clapper, BIOS Google_Clapper.5216.199.7 08/22/2014 | |
16 | RIP: 0010:snd_soc_suspend+0x5a/0xd21 | |
17 | Code: 03 80 3c 10 00 49 89 d7 74 0b 48 89 df e8 71 72 c4 fe 4c 89 | |
18 | fa 48 8b 03 48 89 45 d0 48 8d 98 a0 01 00 00 48 89 d8 48 c1 e8 03 | |
19 | <8a> 04 10 84 c0 0f 85 85 0c 00 00 80 3b 00 0f 84 6b 0c 00 00 48 8b | |
20 | RSP: 0018:ffff888035407750 EFLAGS: 00010202 | |
21 | RAX: 0000000000000034 RBX: 00000000000001a0 RCX: 0000000000000000 | |
22 | RDX: dffffc0000000000 RSI: 0000000000000008 RDI: ffff88805c417098 | |
23 | RBP: ffff8880354077b0 R08: dffffc0000000000 R09: ffffed100b975718 | |
24 | R10: 0000000000000001 R11: ffffffff949ea4a3 R12: 1ffff1100b975746 | |
25 | R13: dffffc0000000000 R14: ffff88805cba4588 R15: dffffc0000000000 | |
26 | FS: 0000794a78e91b80(0000) GS:ffff888068d00000(0000) knlGS:0000000000000000 | |
27 | CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 | |
28 | CR2: 00007bd5283ccf58 CR3: 000000004b7aa000 CR4: 00000000001006e0 | |
29 | Call Trace: | |
30 | ? dpm_complete+0x67b/0x67b | |
31 | ? i915_gem_suspend+0x14d/0x1ad | |
32 | sst_soc_prepare+0x91/0x1dd | |
33 | ? sst_be_hw_params+0x7e/0x7e | |
34 | dpm_prepare+0x39a/0x88b | |
35 | dpm_suspend_start+0x13/0x9d | |
36 | suspend_devices_and_enter+0x18f/0xbd7 | |
37 | ? arch_suspend_enable_irqs+0x11/0x11 | |
38 | ? printk+0xd9/0x12d | |
39 | ? lock_release+0x95f/0x95f | |
40 | ? log_buf_vmcoreinfo_setup+0x131/0x131 | |
41 | ? rcu_read_lock_sched_held+0x140/0x22a | |
42 | ? __bpf_trace_rcu_utilization+0xa/0xa | |
43 | ? __pm_pr_dbg+0x186/0x190 | |
44 | ? pm_notifier_call_chain+0x39/0x39 | |
45 | ? suspend_test+0x9d/0x9d | |
46 | pm_suspend+0x2f4/0x728 | |
47 | ? trace_suspend_resume+0x3da/0x3da | |
48 | ? lock_release+0x95f/0x95f | |
49 | ? kernfs_fop_write+0x19f/0x32d | |
50 | state_store+0xd8/0x147 | |
51 | ? sysfs_kf_read+0x155/0x155 | |
52 | kernfs_fop_write+0x23e/0x32d | |
53 | __vfs_write+0x108/0x608 | |
54 | ? vfs_read+0x2e9/0x2e9 | |
55 | ? rcu_read_lock_sched_held+0x140/0x22a | |
56 | ? __bpf_trace_rcu_utilization+0xa/0xa | |
57 | ? debug_smp_processor_id+0x10/0x10 | |
58 | ? selinux_file_permission+0x1c5/0x3c8 | |
59 | ? rcu_sync_lockdep_assert+0x6a/0xad | |
60 | ? __sb_start_write+0x129/0x2ac | |
61 | vfs_write+0x1aa/0x434 | |
62 | ksys_write+0xfe/0x1be | |
63 | ? __ia32_sys_read+0x82/0x82 | |
64 | do_syscall_64+0xcd/0x120 | |
65 | entry_SYSCALL_64_after_hwframe+0x49/0xbe | |
66 | ||
67 | In the observed situation, the problem is seen because the codec driver | |
68 | failed to probe due to a hardware problem. | |
69 | ||
70 | max98090 i2c-193C9890:00: Failed to read device revision: -1 | |
71 | max98090 i2c-193C9890:00: ASoC: failed to probe component -1 | |
72 | cht-bsw-max98090 cht-bsw-max98090: ASoC: failed to instantiate card -1 | |
73 | cht-bsw-max98090 cht-bsw-max98090: snd_soc_register_card failed -1 | |
74 | cht-bsw-max98090: probe of cht-bsw-max98090 failed with error -1 | |
75 | ||
76 | The problem is similar to the problem solved with commit 2fc995a87f2e | |
77 | ("ASoC: intel: Fix crash at suspend/resume without card registration"), | |
78 | but codec registration fails at a later point. At that time, the pointer | |
79 | checked with the above mentioned commit is already set, but it is not | |
80 | cleared if the device is subsequently removed. Adding a remove function | |
81 | to clear the pointer fixes the problem. | |
82 | ||
83 | Cc: stable@vger.kernel.org | |
84 | Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com> | |
85 | Cc: Curtis Malainey <cujomalainey@chromium.org> | |
86 | Signed-off-by: Guenter Roeck <linux@roeck-us.net> | |
87 | Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> | |
88 | Signed-off-by: Mark Brown <broonie@kernel.org> | |
89 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
90 | ||
91 | --- | |
92 | sound/soc/intel/atom/sst-mfld-platform-pcm.c | 8 ++++++++ | |
93 | 1 file changed, 8 insertions(+) | |
94 | ||
95 | --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c | |
96 | +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c | |
97 | @@ -711,9 +711,17 @@ static int sst_soc_probe(struct snd_soc_ | |
98 | return sst_dsp_init_v2_dpcm(component); | |
99 | } | |
100 | ||
101 | +static void sst_soc_remove(struct snd_soc_component *component) | |
102 | +{ | |
103 | + struct sst_data *drv = dev_get_drvdata(component->dev); | |
104 | + | |
105 | + drv->soc_card = NULL; | |
106 | +} | |
107 | + | |
108 | static const struct snd_soc_component_driver sst_soc_platform_drv = { | |
109 | .name = DRV_NAME, | |
110 | .probe = sst_soc_probe, | |
111 | + .remove = sst_soc_remove, | |
112 | .ops = &sst_platform_ops, | |
113 | .compr_ops = &sst_platform_compr_ops, | |
114 | .pcm_new = sst_pcm_new, |