]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.14/crypto-axis-fix-for-recursive-locking-from-bottom-ha.patch
autosel patches for 4.14
[thirdparty/kernel/stable-queue.git] / queue-4.14 / crypto-axis-fix-for-recursive-locking-from-bottom-ha.patch
1 From bc39303df3ffddbcd03a1ae4ca88fa360b5c3e3a Mon Sep 17 00:00:00 2001
2 From: Lars Persson <lars.persson@axis.com>
3 Date: Wed, 23 Jan 2019 12:59:42 +0100
4 Subject: crypto: axis - fix for recursive locking from bottom half
5
6 [ Upstream commit c34a83820f59bb275e5f2d55cd5ea99c64f6ef23 ]
7
8 Clients may submit a new requests from the completion callback
9 context. The driver was not prepared to receive a request in this
10 state because it already held the request queue lock and a recursive
11 lock error is triggered.
12
13 Now all completions are queued up until we are ready to drop the queue
14 lock and then delivered.
15
16 The fault was triggered by TCP over an IPsec connection in the LTP
17 test suite:
18 LTP: starting tcp4_ipsec02 (tcp_ipsec.sh -p ah -m transport -s "100 1000 65535")
19 BUG: spinlock recursion on CPU#1, genload/943
20 lock: 0xbf3c3094, .magic: dead4ead, .owner: genload/943, .owner_cpu: 1
21 CPU: 1 PID: 943 Comm: genload Tainted: G O 4.9.62-axis5-devel #6
22 Hardware name: Axis ARTPEC-6 Platform
23 (unwind_backtrace) from [<8010d134>] (show_stack+0x18/0x1c)
24 (show_stack) from [<803a289c>] (dump_stack+0x84/0x98)
25 (dump_stack) from [<8016e164>] (do_raw_spin_lock+0x124/0x128)
26 (do_raw_spin_lock) from [<804de1a4>] (artpec6_crypto_submit+0x2c/0xa0)
27 (artpec6_crypto_submit) from [<804def38>] (artpec6_crypto_prepare_submit_hash+0xd0/0x54c)
28 (artpec6_crypto_prepare_submit_hash) from [<7f3165f0>] (ah_output+0x2a4/0x3dc [ah4])
29 (ah_output [ah4]) from [<805df9bc>] (xfrm_output_resume+0x178/0x4a4)
30 (xfrm_output_resume) from [<805d283c>] (xfrm4_output+0xac/0xbc)
31 (xfrm4_output) from [<80587928>] (ip_queue_xmit+0x140/0x3b4)
32 (ip_queue_xmit) from [<805a13b4>] (tcp_transmit_skb+0x4c4/0x95c)
33 (tcp_transmit_skb) from [<8059f218>] (tcp_rcv_state_process+0xdf4/0xdfc)
34 (tcp_rcv_state_process) from [<805a7530>] (tcp_v4_do_rcv+0x64/0x1ac)
35 (tcp_v4_do_rcv) from [<805a9724>] (tcp_v4_rcv+0xa34/0xb74)
36 (tcp_v4_rcv) from [<80581d34>] (ip_local_deliver_finish+0x78/0x2b0)
37 (ip_local_deliver_finish) from [<8058259c>] (ip_local_deliver+0xe4/0x104)
38 (ip_local_deliver) from [<805d23ec>] (xfrm4_transport_finish+0xf4/0x144)
39 (xfrm4_transport_finish) from [<805df564>] (xfrm_input+0x4f4/0x74c)
40 (xfrm_input) from [<804de420>] (artpec6_crypto_task+0x208/0x38c)
41 (artpec6_crypto_task) from [<801271b0>] (tasklet_action+0x60/0xec)
42 (tasklet_action) from [<801266d4>] (__do_softirq+0xcc/0x3a4)
43 (__do_softirq) from [<80126d20>] (irq_exit+0xf4/0x15c)
44 (irq_exit) from [<801741e8>] (__handle_domain_irq+0x68/0xbc)
45 (__handle_domain_irq) from [<801014f0>] (gic_handle_irq+0x50/0x94)
46 (gic_handle_irq) from [<80657370>] (__irq_usr+0x50/0x80)
47
48 Signed-off-by: Lars Persson <larper@axis.com>
49 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
50 Signed-off-by: Sasha Levin <sashal@kernel.org>
51 ---
52 drivers/crypto/axis/artpec6_crypto.c | 28 +++++++++++++++++++++++-----
53 1 file changed, 23 insertions(+), 5 deletions(-)
54
55 diff --git a/drivers/crypto/axis/artpec6_crypto.c b/drivers/crypto/axis/artpec6_crypto.c
56 index 6eb5cb92b986..9f82e14983f6 100644
57 --- a/drivers/crypto/axis/artpec6_crypto.c
58 +++ b/drivers/crypto/axis/artpec6_crypto.c
59 @@ -284,6 +284,7 @@ enum artpec6_crypto_hash_flags {
60
61 struct artpec6_crypto_req_common {
62 struct list_head list;
63 + struct list_head complete_in_progress;
64 struct artpec6_crypto_dma_descriptors *dma;
65 struct crypto_async_request *req;
66 void (*complete)(struct crypto_async_request *req);
67 @@ -2046,7 +2047,8 @@ static int artpec6_crypto_prepare_aead(struct aead_request *areq)
68 return artpec6_crypto_dma_map_descs(common);
69 }
70
71 -static void artpec6_crypto_process_queue(struct artpec6_crypto *ac)
72 +static void artpec6_crypto_process_queue(struct artpec6_crypto *ac,
73 + struct list_head *completions)
74 {
75 struct artpec6_crypto_req_common *req;
76
77 @@ -2057,7 +2059,7 @@ static void artpec6_crypto_process_queue(struct artpec6_crypto *ac)
78 list_move_tail(&req->list, &ac->pending);
79 artpec6_crypto_start_dma(req);
80
81 - req->req->complete(req->req, -EINPROGRESS);
82 + list_add_tail(&req->complete_in_progress, completions);
83 }
84
85 /*
86 @@ -2087,6 +2089,11 @@ static void artpec6_crypto_task(unsigned long data)
87 struct artpec6_crypto *ac = (struct artpec6_crypto *)data;
88 struct artpec6_crypto_req_common *req;
89 struct artpec6_crypto_req_common *n;
90 + struct list_head complete_done;
91 + struct list_head complete_in_progress;
92 +
93 + INIT_LIST_HEAD(&complete_done);
94 + INIT_LIST_HEAD(&complete_in_progress);
95
96 if (list_empty(&ac->pending)) {
97 pr_debug("Spurious IRQ\n");
98 @@ -2120,19 +2127,30 @@ static void artpec6_crypto_task(unsigned long data)
99
100 pr_debug("Completing request %p\n", req);
101
102 - list_del(&req->list);
103 + list_move_tail(&req->list, &complete_done);
104
105 artpec6_crypto_dma_unmap_all(req);
106 artpec6_crypto_copy_bounce_buffers(req);
107
108 ac->pending_count--;
109 artpec6_crypto_common_destroy(req);
110 - req->complete(req->req);
111 }
112
113 - artpec6_crypto_process_queue(ac);
114 + artpec6_crypto_process_queue(ac, &complete_in_progress);
115
116 spin_unlock_bh(&ac->queue_lock);
117 +
118 + /* Perform the completion callbacks without holding the queue lock
119 + * to allow new request submissions from the callbacks.
120 + */
121 + list_for_each_entry_safe(req, n, &complete_done, list) {
122 + req->complete(req->req);
123 + }
124 +
125 + list_for_each_entry_safe(req, n, &complete_in_progress,
126 + complete_in_progress) {
127 + req->req->complete(req->req, -EINPROGRESS);
128 + }
129 }
130
131 static void artpec6_crypto_complete_crypto(struct crypto_async_request *req)
132 --
133 2.19.1
134