static int pin_array_locked(struct nvmap_client *client, struct nvmap_handle **h, int count) { int pinned; int i; int err = 0; /* Flush deferred cache maintenance if needed */ for (pinned = 0; pinned < count; pinned++) if (nvmap_find_cache_maint_op(client->dev, h[pinned])) nvmap_cache_maint_ops_flush(client->dev, h[pinned]); nvmap_mru_lock(client->share); for (pinned = 0; pinned < count; pinned++) { err = pin_locked(client, h[pinned]); if (err) break; } nvmap_mru_unlock(client->share); if (err) { /* unpin pinned handles */ for (i = 0; i < pinned; i++) { /* inc ref counter, because * handle_unpin decrements it */ nvmap_handle_get(h[i]); /* unpin handles and free vm */ handle_unpin(client, h[i], true); } } if (err && tegra_iovmm_get_max_free(client->share->iovmm) >= client->iovm_limit) { /* First attempt to pin in empty iovmm * may still fail because of fragmentation caused by * placing handles in MRU areas. After such failure * all MRU gets cleaned and iovm space is freed. * * We have to do pinning again here since there might be is * no more incoming pin_wait wakeup calls from unpin * operations */ nvmap_mru_lock(client->share); for (pinned = 0; pinned < count; pinned++) { err = pin_locked(client, h[pinned]); if (err) break; } nvmap_mru_unlock(client->share); if (err) { pr_err("Pinning in empty iovmm failed!!!\n"); BUG_ON(1); } } return err; }
static int wait_pin_locked(struct nvmap_client *client, struct nvmap_handle *h) { int ret = 0; ret = pin_locked(client, h); if (ret) { ret = wait_event_interruptible(client->share->pin_wait, !pin_locked(client, h)); } return ret ? -EINTR : 0; }
CK_RV SC_SetPIN(ST_SESSION_HANDLE sSession, CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_locked(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_LOCKED; goto done; } rc = token_specific.t_set_pin(sSession, pOldPin, ulOldLen, pNewPin, ulNewLen); done: if (debugfile) { stlogit2(debugfile, "% - 25s: session = %08x\n", "C_SetPin", rc, hSession); } return (rc); }
CK_RV SC_InitPIN( ST_SESSION_HANDLE sSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { SESSION * sess = NULL; CK_RV rc = CKR_OK; CK_FLAGS * flags = NULL; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pPin) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_locked(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { rc = CKR_PIN_LOCKED; goto done; } if (sess->session_info.state != CKS_RW_SO_FUNCTIONS) { rc = CKR_USER_NOT_LOGGED_IN; goto done; } rc = token_specific.t_init_pin(sess->hContext, pPin, ulPinLen); if (rc == CKR_OK) { flags = &nv_token_data->token_info.flags; *flags &= ~(CKF_USER_PIN_LOCKED | CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_COUNT_LOW); rc = save_token_data(nv_token_data); if (rc != CKR_OK) { goto done; } } done: if (debugfile) { stlogit2(debugfile, "% - 25s: session = %08x\n", "C_InitPin", rc, hSession); } return (rc); }