History

crypto: mv_cesa - add an expiry timer in case anything goes wrong

The timer triggers when 500ms have gone by after triggering the engine and no completion interrupt was received. The callback then tries to sanitise things as well as possible.

Phil Sutter committed 14 years ago

Commit 170dd561 parent b8840091 file · +31 −10Browse files

Unified · Split

drivers/crypto/mv_cesa.c+31−10
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424
2525 #define MV_CESA "MV-CESA:"
2626 #define MAX_HW_HASH_SIZE 0xFFFF
27+#define MV_CESA_EXPIRE 500 /* msec */
2728
2829 /*
2930 * STM:
@@ -87,6 +88,7 @@ struct crypto_priv { · 57 unmodified lines
8788 spinlock_t lock;
8889 struct crypto_queue queue;
8990 enum engine_status eng_st;
91+ struct timer_list completion_timer;
9092 struct crypto_async_request *cur_req;
9193 struct req_progress p;
9294 int max_req_size;
@@ -138,6 +140,29 @@ struct mv_req_hash_ctx { · 45 unmodified lines
138140 int count_add;
139141 };
140142
143+static void mv_completion_timer_callback(unsigned long unused)
144+{
145+ int active = readl(cpg->reg + SEC_ACCEL_CMD) & SEC_CMD_EN_SEC_ACCL0;
146+
147+ printk(KERN_ERR MV_CESA
148+ "completion timer expired (CESA %sactive), cleaning up.\n",
149+ active ? "" : "in");
150+
151+ del_timer(&cpg->completion_timer);
152+ writel(SEC_CMD_DISABLE_SEC, cpg->reg + SEC_ACCEL_CMD);
153+ while(readl(cpg->reg + SEC_ACCEL_CMD) & SEC_CMD_DISABLE_SEC)
154+ printk(KERN_INFO MV_CESA "%s: waiting for engine finishing\n", __func__);
155+ cpg->eng_st = ENGINE_W_DEQUEUE;
156+ wake_up_process(cpg->queue_th);
157+}
158+
159+static void mv_setup_timer(void)
160+{
161+ setup_timer(&cpg->completion_timer, &mv_completion_timer_callback, 0);
162+ mod_timer(&cpg->completion_timer,
163+ jiffies + msecs_to_jiffies(MV_CESA_EXPIRE));
164+}
165+
141166 static void compute_aes_dec_key(struct mv_ctx *ctx)
142167 {
143168 struct crypto_aes_ctx gen_aes_key;
@@ -273,12 +298,8 @@ static void mv_process_current_q(int first_block) · 129 unmodified lines
273298 sizeof(struct sec_accel_config));
274299
275300 /* GO */
301+ mv_setup_timer();
276302 writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD);
277−
278− /*
279− * XXX: add timer if the interrupt does not occur for some mystery
280− * reason
281− */
282303 }
283304
284305 static void mv_crypto_algo_completion(void)
@@ -357,12 +378,8 @@ static void mv_process_hash_current(int first_block) · 72 unmodified lines
357378 memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config));
358379
359380 /* GO */
381+ mv_setup_timer();
360382 writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD);
361−
362− /*
363− * XXX: add timer if the interrupt does not occur for some mystery
364− * reason
365− */
366383 }
367384
368385 static inline int mv_hash_import_sha1_ctx(const struct mv_req_hash_ctx *ctx,
@@ -888,6 +905,10 @@ irqreturn_t crypto_int(int irq, void *priv) · 519 unmodified lines
888905 if (!(val & SEC_INT_ACCEL0_DONE))
889906 return IRQ_NONE;
890907
908+ if (!del_timer(&cpg->completion_timer)) {
909+ printk(KERN_WARNING MV_CESA
910+ "got an interrupt but no pending timer?\n");
911+ }
891912 val &= ~SEC_INT_ACCEL0_DONE;
892913 writel(val, cpg->reg + FPGA_INT_STATUS);
893914 writel(val, cpg->reg + SEC_ACCEL_INT_STATUS);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t