icp_common.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. /*************************************************************************
  2. *
  3. * This file is provided under a dual BSD/GPLv2 license. When using or
  4. * redistributing this file, you may do so under either license.
  5. *
  6. * GPL LICENSE SUMMARY
  7. *
  8. * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of version 2 of the GNU General Public License as
  12. * published by the Free Software Foundation.
  13. *
  14. * This program is distributed in the hope that it will be useful, but
  15. * WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  22. * The full GNU General Public License is included in this distribution
  23. * in the file called LICENSE.GPL.
  24. *
  25. * Contact Information:
  26. * Intel Corporation
  27. *
  28. * BSD LICENSE
  29. *
  30. * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  31. * All rights reserved.
  32. *
  33. * Redistribution and use in source and binary forms, with or without
  34. * modification, are permitted provided that the following conditions
  35. * are met:
  36. *
  37. * * Redistributions of source code must retain the above copyright
  38. * notice, this list of conditions and the following disclaimer.
  39. * * Redistributions in binary form must reproduce the above copyright
  40. * notice, this list of conditions and the following disclaimer in
  41. * the documentation and/or other materials provided with the
  42. * distribution.
  43. * * Neither the name of Intel Corporation nor the names of its
  44. * contributors may be used to endorse or promote products derived
  45. * from this software without specific prior written permission.
  46. *
  47. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  48. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  49. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  50. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  51. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  52. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  53. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  54. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  55. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  56. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  57. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  58. *
  59. *
  60. * version: Security.L.1.0.2-229
  61. *
  62. ***************************************************************************/
  63. /*
  64. * An OCF module that uses Intel® QuickAssist Integrated Accelerator to do the
  65. * crypto.
  66. *
  67. * This driver requires the ICP Access Library that is available from Intel in
  68. * order to operate.
  69. */
  70. #include "icp_ocf.h"
  71. #define ICP_OCF_COMP_NAME "ICP_OCF"
  72. #define ICP_OCF_VER_MAIN (2)
  73. #define ICP_OCF_VER_MJR (1)
  74. #define ICP_OCF_VER_MNR (0)
  75. #define MAX_DEREG_RETRIES (100)
  76. #define DEFAULT_DEREG_RETRIES (10)
  77. #define DEFAULT_DEREG_DELAY_IN_JIFFIES (10)
  78. /* This defines the maximum number of sessions possible between OCF
  79. and the OCF EP80579 Driver. If set to zero, there is no limit. */
  80. #define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT (0)
  81. #define NUM_SUPPORTED_CAPABILITIES (21)
  82. /*Slab zone names*/
  83. #define ICP_SESSION_DATA_NAME "icp_ocf.SesDat"
  84. #define ICP_OP_DATA_NAME "icp_ocf.OpDat"
  85. #define ICP_DH_NAME "icp_ocf.DH"
  86. #define ICP_MODEXP_NAME "icp_ocf.ModExp"
  87. #define ICP_RSA_DECRYPT_NAME "icp_ocf.RSAdec"
  88. #define ICP_RSA_PKEY_NAME "icp_ocf.RSApk"
  89. #define ICP_DSA_SIGN_NAME "icp_ocf.DSAsg"
  90. #define ICP_DSA_VER_NAME "icp_ocf.DSAver"
  91. #define ICP_RAND_VAL_NAME "icp_ocf.DSArnd"
  92. #define ICP_FLAT_BUFF_NAME "icp_ocf.FB"
  93. /*Slabs zones*/
  94. icp_kmem_cache drvSessionData_zone = NULL;
  95. icp_kmem_cache drvOpData_zone = NULL;
  96. icp_kmem_cache drvDH_zone = NULL;
  97. icp_kmem_cache drvLnModExp_zone = NULL;
  98. icp_kmem_cache drvRSADecrypt_zone = NULL;
  99. icp_kmem_cache drvRSAPrivateKey_zone = NULL;
  100. icp_kmem_cache drvDSARSSign_zone = NULL;
  101. icp_kmem_cache drvDSARSSignKValue_zone = NULL;
  102. icp_kmem_cache drvDSAVerify_zone = NULL;
  103. /*Slab zones for flatbuffers and bufferlist*/
  104. icp_kmem_cache drvFlatBuffer_zone = NULL;
  105. static inline int icp_cache_null_check(void)
  106. {
  107. return (drvSessionData_zone && drvOpData_zone
  108. && drvDH_zone && drvLnModExp_zone && drvRSADecrypt_zone
  109. && drvRSAPrivateKey_zone && drvDSARSSign_zone
  110. && drvDSARSSign_zone && drvDSARSSignKValue_zone
  111. && drvDSAVerify_zone && drvFlatBuffer_zone);
  112. }
  113. /*Function to free all allocated slab caches before exiting the module*/
  114. static void icp_ocfDrvFreeCaches(void);
  115. int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  116. /* Module parameter - gives the number of times LAC deregistration shall be
  117. re-tried */
  118. int num_dereg_retries = DEFAULT_DEREG_RETRIES;
  119. /* Module parameter - gives the delay time in jiffies before a LAC session
  120. shall be attempted to be deregistered again */
  121. int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES;
  122. /* Module parameter - gives the maximum number of sessions possible between
  123. OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
  124. int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT;
  125. /* This is set when the module is removed from the system, no further
  126. processing can take place if this is set */
  127. icp_atomic_t icp_ocfDrvIsExiting = ICP_ATOMIC_INIT(0);
  128. /* This is used to show how many lac sessions were not deregistered*/
  129. icp_atomic_t lac_session_failed_dereg_count = ICP_ATOMIC_INIT(0);
  130. /* This is used to track the number of registered sessions between OCF and
  131. * and the OCF EP80579 driver, when max_session is set to value other than
  132. * zero. This ensures that the max_session set for the OCF and the driver
  133. * is equal to the LAC registered sessions */
  134. icp_atomic_t num_ocf_to_drv_registered_sessions = ICP_ATOMIC_INIT(0);
  135. /* Head of linked list used to store session data */
  136. icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
  137. icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
  138. icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
  139. /*Below pointer is only used in linux, FreeBSD uses the name to
  140. create its own variable name*/
  141. icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ = NULL;
  142. ICP_WORKQUEUE_DEFINE_THREAD(icp_ocfDrvFreeLacSessionWorkQ);
  143. struct icp_drvBuffListInfo defBuffListInfo;
  144. /* Name : icp_ocfDrvInit
  145. *
  146. * Description : This function will register all the symmetric and asymmetric
  147. * functionality that will be accelerated by the hardware. It will also
  148. * get a unique driver ID from the OCF and initialise all slab caches
  149. */
  150. ICP_MODULE_INIT_FUNC(icp_ocfDrvInit)
  151. {
  152. int ocfStatus = 0;
  153. IPRINTK("=== %s ver %d.%d.%d ===\n", ICP_OCF_COMP_NAME,
  154. ICP_OCF_VER_MAIN, ICP_OCF_VER_MJR, ICP_OCF_VER_MNR);
  155. if (MAX_DEREG_RETRIES < num_dereg_retries) {
  156. EPRINTK("Session deregistration retry count set to greater "
  157. "than %d", MAX_DEREG_RETRIES);
  158. icp_module_return_code(EINVAL);
  159. }
  160. /* Initialize and Start the Cryptographic component */
  161. if (CPA_STATUS_SUCCESS !=
  162. cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) {
  163. EPRINTK("Failed to initialize and start the instance "
  164. "of the Cryptographic component.\n");
  165. return icp_module_return_code(EINVAL);
  166. }
  167. icp_spin_lock_init(&icp_ocfDrvSymSessInfoListSpinlock);
  168. /* Set the default size of BufferList to allocate */
  169. memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo));
  170. if (ICP_OCF_DRV_STATUS_SUCCESS !=
  171. icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS,
  172. &defBuffListInfo)) {
  173. EPRINTK("Failed to get bufferlist memory info.\n");
  174. return icp_module_return_code(ENOMEM);
  175. }
  176. /*Register OCF EP80579 Driver with OCF */
  177. icp_ocfDrvDriverId = ICP_CRYPTO_GET_DRIVERID();
  178. if (icp_ocfDrvDriverId < 0) {
  179. EPRINTK("%s : ICP driver failed to register with OCF!\n",
  180. __FUNCTION__);
  181. return icp_module_return_code(ENODEV);
  182. }
  183. /*Create all the slab caches used by the OCF EP80579 Driver */
  184. drvSessionData_zone =
  185. ICP_CACHE_CREATE(ICP_SESSION_DATA_NAME, struct icp_drvSessionData);
  186. /*
  187. * Allocation of the OpData includes the allocation space for meta data.
  188. * The memory after the opData structure is reserved for this meta data.
  189. */
  190. drvOpData_zone =
  191. icp_kmem_cache_create(ICP_OP_DATA_NAME,
  192. sizeof(struct icp_drvOpData) +
  193. defBuffListInfo.metaSize,
  194. ICP_KERNEL_CACHE_ALIGN,
  195. ICP_KERNEL_CACHE_NOINIT);
  196. drvDH_zone = ICP_CACHE_CREATE(ICP_DH_NAME, CpaCyDhPhase1KeyGenOpData);
  197. drvLnModExp_zone =
  198. ICP_CACHE_CREATE(ICP_MODEXP_NAME, CpaCyLnModExpOpData);
  199. drvRSADecrypt_zone =
  200. ICP_CACHE_CREATE(ICP_RSA_DECRYPT_NAME, CpaCyRsaDecryptOpData);
  201. drvRSAPrivateKey_zone =
  202. ICP_CACHE_CREATE(ICP_RSA_PKEY_NAME, CpaCyRsaPrivateKey);
  203. drvDSARSSign_zone =
  204. ICP_CACHE_CREATE(ICP_DSA_SIGN_NAME, CpaCyDsaRSSignOpData);
  205. /*too awkward to use a macro here */
  206. drvDSARSSignKValue_zone =
  207. ICP_CACHE_CREATE(ICP_RAND_VAL_NAME,
  208. DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES);
  209. drvDSAVerify_zone =
  210. ICP_CACHE_CREATE(ICP_DSA_VER_NAME, CpaCyDsaVerifyOpData);
  211. drvFlatBuffer_zone =
  212. ICP_CACHE_CREATE(ICP_FLAT_BUFF_NAME, CpaFlatBuffer);
  213. if (0 == icp_cache_null_check()) {
  214. icp_ocfDrvFreeCaches();
  215. EPRINTK("%s() line %d: Not enough memory!\n",
  216. __FUNCTION__, __LINE__);
  217. return ENOMEM;
  218. }
  219. /* Register the ICP symmetric crypto support. */
  220. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_NULL_CBC, ocfStatus);
  221. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_DES_CBC, ocfStatus);
  222. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_3DES_CBC, ocfStatus);
  223. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_AES_CBC, ocfStatus);
  224. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_ARC4, ocfStatus);
  225. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5, ocfStatus);
  226. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5_HMAC, ocfStatus);
  227. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1, ocfStatus);
  228. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1_HMAC, ocfStatus);
  229. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256, ocfStatus);
  230. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256_HMAC,
  231. ocfStatus);
  232. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384, ocfStatus);
  233. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384_HMAC,
  234. ocfStatus);
  235. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512, ocfStatus);
  236. ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512_HMAC,
  237. ocfStatus);
  238. /* Register the ICP asymmetric algorithm support */
  239. ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DH_COMPUTE_KEY,
  240. ocfStatus);
  241. ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP, ocfStatus);
  242. ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP_CRT, ocfStatus);
  243. ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_SIGN, ocfStatus);
  244. ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_VERIFY, ocfStatus);
  245. /* Register the ICP random number generator support */
  246. ICP_REG_RAND_WITH_OCF(icp_ocfDrvDriverId,
  247. icp_ocfDrvReadRandom, NULL, ocfStatus);
  248. if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) {
  249. DPRINTK("%s: Failed to register any device capabilities\n",
  250. __FUNCTION__);
  251. icp_ocfDrvFreeCaches();
  252. icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  253. return icp_module_return_code(ECANCELED);
  254. }
  255. DPRINTK("%s: Registered %d of %d device capabilities\n",
  256. __FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES);
  257. /*Session data linked list used during module exit */
  258. ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);
  259. ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);
  260. ICP_WORKQUEUE_CREATE(icp_ocfDrvFreeLacSessionWorkQ, "icpwq");
  261. if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
  262. EPRINTK("%s: Failed to create single "
  263. "thread workqueue\n", __FUNCTION__);
  264. icp_ocfDrvFreeCaches();
  265. icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  266. return icp_module_return_code(ENOMEM);
  267. }
  268. return icp_module_return_code(0);
  269. }
  270. /* Name : icp_ocfDrvExit
  271. *
  272. * Description : This function will deregister all the symmetric sessions
  273. * registered with the LAC component. It will also deregister all symmetric
  274. * and asymmetric functionality that can be accelerated by the hardware via OCF
  275. * and random number generation if it is enabled.
  276. */
  277. ICP_MODULE_EXIT_FUNC(icp_ocfDrvExit)
  278. {
  279. CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  280. struct icp_drvSessionData *sessionData = NULL;
  281. struct icp_drvSessionData *tempSessionData = NULL;
  282. int i, remaining_delay_time_in_jiffies = 0;
  283. /* For FreeBSD the invariant macro below makes function to return */
  284. /* with EBUSY value in the case of any session which has been regi- */
  285. /* stered with LAC not being deregistered. */
  286. /* The Linux implementation is empty since it is purely to compensate */
  287. /* for a limitation of the FreeBSD 7.1 Opencrypto framework. */
  288. ICP_MODULE_EXIT_INV();
  289. /* There is a possibility of a process or new session command being */
  290. /* sent before this variable is incremented. The aim of this variable */
  291. /* is to stop a loop of calls creating a deadlock situation which */
  292. /* would prevent the driver from exiting. */
  293. icp_atomic_set(&icp_ocfDrvIsExiting, 1);
  294. /*Existing sessions will be routed to another driver after these calls */
  295. crypto_unregister_all(icp_ocfDrvDriverId);
  296. crypto_runregister_all(icp_ocfDrvDriverId);
  297. if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
  298. DPRINTK("%s: workqueue already "
  299. "destroyed, therefore module exit "
  300. " function already called. Exiting.\n", __FUNCTION__);
  301. return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
  302. }
  303. /*If any sessions are waiting to be deregistered, do that. This also
  304. flushes the work queue */
  305. ICP_WORKQUEUE_DESTROY(icp_ocfDrvFreeLacSessionWorkQ);
  306. /*ENTER CRITICAL SECTION */
  307. icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  308. ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
  309. &icp_ocfDrvGlobalSymListHead, listNode) {
  310. for (i = 0; i < num_dereg_retries; i++) {
  311. /*No harm if bad input - LAC will handle error cases */
  312. if (ICP_SESSION_RUNNING == tempSessionData->inUse) {
  313. lacStatus =
  314. cpaCySymRemoveSession
  315. (CPA_INSTANCE_HANDLE_SINGLE,
  316. tempSessionData->sessHandle);
  317. if (CPA_STATUS_SUCCESS == lacStatus) {
  318. /* Succesfully deregistered */
  319. break;
  320. } else if (CPA_STATUS_RETRY != lacStatus) {
  321. icp_atomic_inc
  322. (&lac_session_failed_dereg_count);
  323. break;
  324. }
  325. /*schedule_timout returns the time left for completion if
  326. * this task is set to TASK_INTERRUPTIBLE */
  327. remaining_delay_time_in_jiffies =
  328. dereg_retry_delay_in_jiffies;
  329. while (0 > remaining_delay_time_in_jiffies) {
  330. remaining_delay_time_in_jiffies =
  331. icp_schedule_timeout
  332. (&icp_ocfDrvSymSessInfoListSpinlock,
  333. remaining_delay_time_in_jiffies);
  334. }
  335. DPRINTK
  336. ("%s(): Retry %d to deregistrate the session\n",
  337. __FUNCTION__, i);
  338. }
  339. }
  340. /*remove from current list */
  341. ICP_LIST_DEL(tempSessionData, listNode);
  342. /*add to free mem linked list */
  343. ICP_LIST_ADD(tempSessionData,
  344. &icp_ocfDrvGlobalSymListHead_FreeMemList,
  345. listNode);
  346. }
  347. /*EXIT CRITICAL SECTION */
  348. icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  349. /*set back to initial values */
  350. sessionData = NULL;
  351. /*still have a reference in our list! */
  352. tempSessionData = NULL;
  353. /*free memory */
  354. ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
  355. &icp_ocfDrvGlobalSymListHead_FreeMemList,
  356. listNode) {
  357. ICP_LIST_DEL(tempSessionData, listNode);
  358. /* Free allocated CpaCySymSessionCtx */
  359. if (NULL != tempSessionData->sessHandle) {
  360. icp_kfree(tempSessionData->sessHandle);
  361. }
  362. memset(tempSessionData, 0, sizeof(struct icp_drvSessionData));
  363. ICP_CACHE_FREE(drvSessionData_zone, tempSessionData);
  364. }
  365. if (0 != icp_atomic_read(&lac_session_failed_dereg_count)) {
  366. DPRINTK("%s(): %d LAC sessions were not deregistered "
  367. "correctly. This is not a clean exit! \n",
  368. __FUNCTION__,
  369. icp_atomic_read(&lac_session_failed_dereg_count));
  370. }
  371. icp_ocfDrvFreeCaches();
  372. icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  373. icp_spin_lock_destroy(&icp_ocfDrvSymSessInfoListSpinlock);
  374. /* Shutdown the Cryptographic component */
  375. lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE);
  376. if (CPA_STATUS_SUCCESS != lacStatus) {
  377. DPRINTK("%s(): Failed to stop instance of the "
  378. "Cryptographic component.(status == %d)\n",
  379. __FUNCTION__, lacStatus);
  380. }
  381. return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
  382. }
  383. /* Name : icp_ocfDrvFreeCaches
  384. *
  385. * Description : This function deregisters all slab caches
  386. */
  387. static void icp_ocfDrvFreeCaches(void)
  388. {
  389. icp_atomic_set(&icp_ocfDrvIsExiting, 1);
  390. /*Sym Zones */
  391. ICP_CACHE_DESTROY(drvSessionData_zone);
  392. ICP_CACHE_DESTROY(drvOpData_zone);
  393. /*Asym zones */
  394. ICP_CACHE_DESTROY(drvDH_zone);
  395. ICP_CACHE_DESTROY(drvLnModExp_zone);
  396. ICP_CACHE_DESTROY(drvRSADecrypt_zone);
  397. ICP_CACHE_DESTROY(drvRSAPrivateKey_zone);
  398. ICP_CACHE_DESTROY(drvDSARSSignKValue_zone);
  399. ICP_CACHE_DESTROY(drvDSARSSign_zone);
  400. ICP_CACHE_DESTROY(drvDSAVerify_zone);
  401. /*FlatBuffer and BufferList Zones */
  402. ICP_CACHE_DESTROY(drvFlatBuffer_zone);
  403. }
  404. /* Name : icp_ocfDrvDeregRetry
  405. *
  406. * Description : This function will try to farm the session deregistration
  407. * off to a work queue. If it fails, nothing more can be done and it
  408. * returns an error
  409. */
  410. int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
  411. {
  412. struct icp_ocfDrvFreeLacSession *workstore = NULL;
  413. DPRINTK("%s(): Retry - Deregistering session (%p)\n",
  414. __FUNCTION__, sessionToDeregister);
  415. /*make sure the session is not available to be allocated during this
  416. process */
  417. icp_atomic_inc(&lac_session_failed_dereg_count);
  418. /*Farm off to work queue */
  419. workstore =
  420. icp_kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), ICP_M_NOWAIT);
  421. if (NULL == workstore) {
  422. DPRINTK("%s(): unable to free session - no memory available "
  423. "for work queue\n", __FUNCTION__);
  424. return ENOMEM;
  425. }
  426. workstore->sessionToDeregister = sessionToDeregister;
  427. icp_init_work(&(workstore->work),
  428. icp_ocfDrvDeferedFreeLacSessionTaskFn, workstore);
  429. ICP_WORKQUEUE_ENQUEUE(icp_ocfDrvFreeLacSessionWorkQ,
  430. &(workstore->work));
  431. return ICP_OCF_DRV_STATUS_SUCCESS;
  432. }
  433. /* Name : icp_ocfDrvDeferedFreeLacSessionProcess
  434. *
  435. * Description : This function will retry (module input parameter)
  436. * 'num_dereg_retries' times to deregister any symmetric session that recieves a
  437. * CPA_STATUS_RETRY message from the LAC component. This function is run in
  438. * Thread context because it is called from a worker thread
  439. */
  440. void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
  441. {
  442. struct icp_ocfDrvFreeLacSession *workstore = NULL;
  443. CpaCySymSessionCtx sessionToDeregister = NULL;
  444. int i = 0;
  445. int remaining_delay_time_in_jiffies = 0;
  446. CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  447. workstore = (struct icp_ocfDrvFreeLacSession *)arg;
  448. if (NULL == workstore) {
  449. DPRINTK("%s() function called with null parameter \n",
  450. __FUNCTION__);
  451. return;
  452. }
  453. sessionToDeregister = workstore->sessionToDeregister;
  454. icp_kfree(workstore);
  455. /*if exiting, give deregistration one more blast only */
  456. if (icp_atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {
  457. lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  458. sessionToDeregister);
  459. if (lacStatus != CPA_STATUS_SUCCESS) {
  460. DPRINTK("%s() Failed to Dereg LAC session %p "
  461. "during module exit\n", __FUNCTION__,
  462. sessionToDeregister);
  463. return;
  464. }
  465. icp_atomic_dec(&lac_session_failed_dereg_count);
  466. return;
  467. }
  468. for (i = 0; i <= num_dereg_retries; i++) {
  469. lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  470. sessionToDeregister);
  471. if (lacStatus == CPA_STATUS_SUCCESS) {
  472. icp_atomic_dec(&lac_session_failed_dereg_count);
  473. return;
  474. }
  475. if (lacStatus != CPA_STATUS_RETRY) {
  476. DPRINTK("%s() Failed to deregister session - lacStatus "
  477. " = %d", __FUNCTION__, lacStatus);
  478. break;
  479. }
  480. /*schedule_timout returns the time left for completion if this
  481. task is set to TASK_INTERRUPTIBLE */
  482. remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies;
  483. while (0 < remaining_delay_time_in_jiffies) {
  484. remaining_delay_time_in_jiffies =
  485. icp_schedule_timeout(NULL,
  486. remaining_delay_time_in_jiffies);
  487. }
  488. }
  489. DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__);
  490. DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__,
  491. icp_atomic_read(&lac_session_failed_dereg_count));
  492. }
  493. /* Name : icp_ocfDrvPtrAndLenToFlatBuffer
  494. *
  495. * Description : This function converts a "pointer and length" buffer
  496. * structure to Fredericksburg Flat Buffer (CpaFlatBuffer) format.
  497. *
  498. * This function assumes that the data passed in are valid.
  499. */
  500. inline void
  501. icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
  502. CpaFlatBuffer * pFlatBuffer)
  503. {
  504. pFlatBuffer->pData = pData;
  505. pFlatBuffer->dataLenInBytes = len;
  506. }
  507. /* Name : icp_ocfDrvPtrAndLenToBufferList
  508. *
  509. * Description : This function converts a "pointer and length" buffer
  510. * structure to Fredericksburg Scatter/Gather Buffer (CpaBufferList) format.
  511. *
  512. * This function assumes that the data passed in are valid.
  513. */
  514. inline void
  515. icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
  516. CpaBufferList * pBufferList)
  517. {
  518. pBufferList->numBuffers = 1;
  519. pBufferList->pBuffers->pData = pDataIn;
  520. pBufferList->pBuffers->dataLenInBytes = length;
  521. }
  522. /* Name : icp_ocfDrvBufferListToPtrAndLen
  523. *
  524. * Description : This function converts Fredericksburg Scatter/Gather Buffer
  525. * (CpaBufferList) format to a "pointer and length" buffer structure.
  526. *
  527. * This function assumes that the data passed in are valid.
  528. */
  529. inline void
  530. icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
  531. void **ppDataOut, uint32_t * pLength)
  532. {
  533. *ppDataOut = pBufferList->pBuffers->pData;
  534. *pLength = pBufferList->pBuffers->dataLenInBytes;
  535. }
  536. /* Name : icp_ocfDrvBufferListMemInfo
  537. *
  538. * Description : This function will set the number of flat buffers in
  539. * bufferlist, the size of memory to allocate for the pPrivateMetaData
  540. * member of the CpaBufferList.
  541. */
  542. int
  543. icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
  544. struct icp_drvBuffListInfo *buffListInfo)
  545. {
  546. buffListInfo->numBuffers = numBuffers;
  547. if (CPA_STATUS_SUCCESS !=
  548. cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  549. buffListInfo->numBuffers,
  550. &(buffListInfo->metaSize))) {
  551. EPRINTK("%s() Failed to get buffer list meta size.\n",
  552. __FUNCTION__);
  553. return ICP_OCF_DRV_STATUS_FAIL;
  554. }
  555. return ICP_OCF_DRV_STATUS_SUCCESS;
  556. }
  557. /* Name : icp_ocfDrvFreeFlatBuffer
  558. *
  559. * Description : This function will deallocate flat buffer.
  560. */
  561. inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)
  562. {
  563. if (pFlatBuffer != NULL) {
  564. memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer));
  565. ICP_CACHE_FREE(drvFlatBuffer_zone, pFlatBuffer);
  566. }
  567. }
  568. /* Name : icp_ocfDrvAllocMetaData
  569. *
  570. * Description : This function will allocate memory for the
  571. * pPrivateMetaData member of CpaBufferList.
  572. */
  573. inline int
  574. icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
  575. struct icp_drvOpData *pOpData)
  576. {
  577. Cpa32U metaSize = 0;
  578. if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  579. uint8_t *pOpDataStartAddr = (uint8_t *) pOpData;
  580. if (0 == defBuffListInfo.metaSize) {
  581. pBufferList->pPrivateMetaData = NULL;
  582. return ICP_OCF_DRV_STATUS_SUCCESS;
  583. }
  584. /*
  585. * The meta data allocation has been included as part of the
  586. * op data. It has been pre-allocated in memory just after the
  587. * icp_drvOpData structure.
  588. */
  589. pBufferList->pPrivateMetaData = (void *)(pOpDataStartAddr +
  590. sizeof(struct
  591. icp_drvOpData));
  592. } else {
  593. if (CPA_STATUS_SUCCESS !=
  594. cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  595. pBufferList->numBuffers,
  596. &metaSize)) {
  597. EPRINTK("%s() Failed to get buffer list meta size.\n",
  598. __FUNCTION__);
  599. return ICP_OCF_DRV_STATUS_FAIL;
  600. }
  601. if (0 == metaSize) {
  602. pBufferList->pPrivateMetaData = NULL;
  603. return ICP_OCF_DRV_STATUS_SUCCESS;
  604. }
  605. pBufferList->pPrivateMetaData =
  606. icp_kmalloc(metaSize, ICP_M_NOWAIT);
  607. }
  608. if (NULL == pBufferList->pPrivateMetaData) {
  609. EPRINTK("%s() Failed to allocate pPrivateMetaData.\n",
  610. __FUNCTION__);
  611. return ICP_OCF_DRV_STATUS_FAIL;
  612. }
  613. return ICP_OCF_DRV_STATUS_SUCCESS;
  614. }
  615. /* Name : icp_ocfDrvFreeMetaData
  616. *
  617. * Description : This function will deallocate pPrivateMetaData memory.
  618. */
  619. inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList)
  620. {
  621. if (NULL == pBufferList->pPrivateMetaData) {
  622. return;
  623. }
  624. /*
  625. * Only free the meta data if the BufferList has more than
  626. * ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS number of buffers.
  627. * Otherwise, the meta data shall be freed when the icp_drvOpData is
  628. * freed.
  629. */
  630. if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers) {
  631. icp_kfree(pBufferList->pPrivateMetaData);
  632. }
  633. }
  634. /* Module declaration, init and exit functions */
  635. ICP_DECLARE_MODULE(icp_ocf, icp_ocfDrvInit, icp_ocfDrvExit);
  636. ICP_MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");
  637. ICP_MODULE_VERSION(icp_ocf, ICP_OCF_VER_MJR);
  638. ICP_MODULE_LICENSE("Dual BSD/GPL");
  639. ICP_MODULE_AUTHOR("Intel");
  640. /* Module parameters */
  641. ICP_MODULE_PARAM_INT(icp_ocf, num_dereg_retries,
  642. "Number of times to retry LAC Sym Session Deregistration. "
  643. "Default 10, Max 100");
  644. ICP_MODULE_PARAM_INT(icp_ocf, dereg_retry_delay_in_jiffies, "Delay in jiffies "
  645. "(added to a schedule() function call) before a LAC Sym "
  646. "Session Dereg is retried. Default 10");
  647. ICP_MODULE_PARAM_INT(icp_ocf, max_sessions,
  648. "This sets the maximum number of sessions "
  649. "between OCF and this driver. If this value is set to zero,"
  650. "max session count checking is disabled. Default is zero(0)");
  651. /* Module dependencies */
  652. #define MODULE_MIN_VER 1
  653. #define CRYPTO_MAX_VER 3
  654. #define LAC_MAX_VER 2
  655. ICP_MODULE_DEPEND(icp_ocf, crypto, MODULE_MIN_VER, MODULE_MIN_VER,
  656. CRYPTO_MAX_VER);
  657. ICP_MODULE_DEPEND(icp_ocf, cryptodev, MODULE_MIN_VER, MODULE_MIN_VER,
  658. CRYPTO_MAX_VER);
  659. ICP_MODULE_DEPEND(icp_ocf, icp_crypto, MODULE_MIN_VER, MODULE_MIN_VER,
  660. LAC_MAX_VER);