aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-kernel/cryptodev/files/0005-Asynchronous-interface-changes-in-cryptodev.patch
blob: 8827fb0f27727cddf1e2bc0ccba7c2b5278d3fe9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
From 7594d5375d998eb25241750b623661ff021697d3 Mon Sep 17 00:00:00 2001
From: Yashpal Dutta <yashpal.dutta@freescale.com>
Date: Fri, 7 Mar 2014 07:24:00 +0545
Subject: [PATCH 05/15] Asynchronous interface changes in cryptodev

Upstream-status: Pending

Signed-off-by: Yashpal Dutta <yashpal.dutta@freescale.com>
---
 cryptlib.h         |  7 ++++-
 crypto/cryptodev.h | 10 ++++++-
 cryptodev_int.h    | 10 ++++++-
 ioctl.c            | 76 +++++++++++++++++++++++++++++++++++++-----------------
 4 files changed, 76 insertions(+), 27 deletions(-)

diff --git a/cryptlib.h b/cryptlib.h
index 56d325a..7ffa54c 100644
--- a/cryptlib.h
+++ b/cryptlib.h
@@ -113,7 +113,12 @@ struct cryptodev_pkc {
 	struct pkc_request req; /* PKC request structure allocated
 				 from CryptoAPI */
 	enum offload_type type; /* Synchronous Vs Asynchronous request */
-	void *cookie; /*Additional opaque cookie to be used in future */
+	/*
+	 * cookie used for transfering tranparent information from async
+	 * submission to async fetch. Currently some dynamic allocated
+	 * buffers are maintained which will be freed later during fetch
+	 */
+	void *cookie;
 	struct crypt_priv *priv;
 };
 
diff --git a/crypto/cryptodev.h b/crypto/cryptodev.h
index 96675fe..4436fbf 100644
--- a/crypto/cryptodev.h
+++ b/crypto/cryptodev.h
@@ -254,6 +254,14 @@ struct crypt_kop {
 	void *cookie;
 };
 
+#define MAX_COOKIES 4
+
+struct pkc_cookie_list_s {
+	int cookie_available;
+	void *cookie[MAX_COOKIES];
+	int status[MAX_COOKIES];
+};
+
 enum cryptodev_crk_op_t {
 	CRK_MOD_EXP = 0,
 	CRK_MOD_EXP_CRT = 1,
@@ -298,5 +306,5 @@ enum cryptodev_crk_op_t {
 #define CIOCASYNCFETCH    _IOR('c', 111, struct crypt_op)
 /* additional ioctls for asynchronous  operation for asymmetric ciphers*/
 #define CIOCASYMASYNCRYPT    _IOW('c', 112, struct crypt_kop)
-#define CIOCASYMASYNFETCH    _IOR('c', 113, struct crypt_kop)
+#define CIOCASYMFETCHCOOKIE    _IOR('c', 113, struct pkc_cookie_list_s)
 #endif /* L_CRYPTODEV_H */
diff --git a/cryptodev_int.h b/cryptodev_int.h
index cf54dac..5347cae 100644
--- a/cryptodev_int.h
+++ b/cryptodev_int.h
@@ -93,6 +93,12 @@ struct compat_crypt_kop {
 	compat_uptr_t cookie;
 };
 
+struct compat_pkc_cookie_list_s {
+	int cookie_available;
+	compat_uptr_t cookie[MAX_COOKIES];
+	int status[MAX_COOKIES];
+};
+
  /* input of CIOCAUTHCRYPT */
 struct compat_crypt_auth_op {
 	uint32_t	ses;		/* session identifier */
@@ -126,11 +132,13 @@ struct compat_crypt_auth_op {
 /* compat ioctls, defined for the above structs */
 #define COMPAT_CIOCGSESSION    _IOWR('c', 102, struct compat_session_op)
 #define COMPAT_CIOCCRYPT       _IOWR('c', 104, struct compat_crypt_op)
+#define COMPAT_CIOCKEY    _IOW('c', 105, struct compat_crypt_kop)
 #define COMPAT_CIOCASYNCCRYPT  _IOW('c', 107, struct compat_crypt_op)
 #define COMPAT_CIOCASYNCFETCH  _IOR('c', 108, struct compat_crypt_op)
 #define COMPAT_CIOCAUTHCRYPT   _IOWR('c', 109, struct compat_crypt_auth_op)
 #define COMPAT_CIOCASYMASYNCRYPT    _IOW('c', 110, struct compat_crypt_kop)
-#define COMPAT_CIOCASYMASYNFETCH    _IOR('c', 111, struct compat_crypt_kop)
+#define COMPAT_CIOCASYMFETCHCOOKIE    _IOR('c', 111, \
+				struct compat_pkc_cookie_list_s)
 
 #endif /* CONFIG_COMPAT */
 
diff --git a/ioctl.c b/ioctl.c
index 9431025..e2f407f 100644
--- a/ioctl.c
+++ b/ioctl.c
@@ -105,8 +105,6 @@ void cryptodev_complete_asym(struct crypto_async_request *req, int err)
 	crypto_free_pkc(pkc->s);
 	res->err = err;
 	if (pkc->type == SYNCHRONOUS) {
-		if (err == -EINPROGRESS)
-			return;
 		complete(&res->completion);
 	} else {
 		struct crypt_priv *pcr = pkc->priv;
@@ -1051,26 +1049,41 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_)
 			ret = 0;
 	}
 	return ret;
-	case CIOCASYMASYNFETCH:
+	case CIOCASYMFETCHCOOKIE:
 	{
 		struct cryptodev_pkc *pkc;
 		unsigned long flags;
+		int i;
+		struct pkc_cookie_list_s cookie_list;
 
 		spin_lock_irqsave(&pcr->completion_lock, flags);
-		if (list_empty(&pcr->asym_completed_list)) {
-			spin_unlock_irqrestore(&pcr->completion_lock, flags);
-			return -ENOMEM;
+		cookie_list.cookie_available = 0;
+		for (i = 0; i < MAX_COOKIES; i++) {
+			if (!list_empty(&pcr->asym_completed_list)) {
+				/* Run a loop in the list for upto  elements
+				 and copy their response back */
+				pkc =
+				 list_first_entry(&pcr->asym_completed_list,
+						struct cryptodev_pkc, list);
+				list_del(&pkc->list);
+				ret = crypto_async_fetch_asym(pkc);
+				if (!ret) {
+					cookie_list.cookie_available++;
+					cookie_list.cookie[i] =
+						pkc->kop.kop.cookie;
+					cookie_list.status[i] = pkc->result.err;
+				}
+				kfree(pkc);
+			} else {
+				break;
+			}
 		}
-		pkc = list_first_entry(&pcr->asym_completed_list,
-			struct cryptodev_pkc, list);
-		list_del(&pkc->list);
 		spin_unlock_irqrestore(&pcr->completion_lock, flags);
-		ret = crypto_async_fetch_asym(pkc);
 
 		/* Reflect the updated request to user-space */
-		if (!ret)
-			kop_to_user(&pkc->kop, arg);
-		kfree(pkc);
+		if (cookie_list.cookie_available)
+			copy_to_user(arg, &cookie_list,
+				     sizeof(struct pkc_cookie_list_s));
 	}
 	return ret;
 	default:
@@ -1345,26 +1358,41 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg_)
 			ret = 0;
 	}
 	return ret;
-	case COMPAT_CIOCASYMASYNFETCH:
+	case COMPAT_CIOCASYMFETCHCOOKIE:
 	{
 		struct cryptodev_pkc *pkc;
 		unsigned long flags;
+		int i = 0;
+		struct compat_pkc_cookie_list_s cookie_list;
 
 		spin_lock_irqsave(&pcr->completion_lock, flags);
-		if (list_empty(&pcr->asym_completed_list)) {
-			spin_unlock_irqrestore(&pcr->completion_lock, flags);
-			return -ENOMEM;
+		cookie_list.cookie_available = 0;
+
+		for (i = 0; i < MAX_COOKIES; i++) {
+			if (!list_empty(&pcr->asym_completed_list)) {
+				/* Run a loop in the list for upto  elements
+				 and copy their response back */
+				pkc =
+				 list_first_entry(&pcr->asym_completed_list,
+						struct cryptodev_pkc, list);
+				list_del(&pkc->list);
+				ret = crypto_async_fetch_asym(pkc);
+				if (!ret) {
+					cookie_list.cookie_available++;
+					cookie_list.cookie[i] =
+						 pkc->kop.kop.cookie;
+				}
+				kfree(pkc);
+			} else {
+				break;
+			}
 		}
-		pkc = list_first_entry(&pcr->asym_completed_list,
-			 struct cryptodev_pkc, list);
-		list_del(&pkc->list);
 		spin_unlock_irqrestore(&pcr->completion_lock, flags);
-		ret = crypto_async_fetch_asym(pkc);
 
 		/* Reflect the updated request to user-space */
-		if (!ret)
-			compat_kop_to_user(&pkc->kop, arg);
-		kfree(pkc);
+		if (cookie_list.cookie_available)
+			copy_to_user(arg, &cookie_list,
+				     sizeof(struct compat_pkc_cookie_list_s));
 	}
 	return ret;
 	default:
-- 
2.3.5