Commit ff61b5e3 authored by Elena Reshetova's avatar Elena Reshetova Committed by David S. Miller

drivers, net, mlx4: convert mlx4_cq.refcount from atomic_t to refcount_t

atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable mlx4_cq.refcount is used as pure reference counter.
Convert it to refcount_t and fix up the operations.
Suggested-by: default avatarKees Cook <keescook@chromium.org>
Reviewed-by: default avatarDavid Windsor <dwindsor@gmail.com>
Reviewed-by: default avatarHans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: default avatarElena Reshetova <elena.reshetova@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c6d4e63e
...@@ -69,7 +69,7 @@ void mlx4_cq_tasklet_cb(unsigned long data) ...@@ -69,7 +69,7 @@ void mlx4_cq_tasklet_cb(unsigned long data)
list_for_each_entry_safe(mcq, temp, &ctx->process_list, tasklet_ctx.list) { list_for_each_entry_safe(mcq, temp, &ctx->process_list, tasklet_ctx.list) {
list_del_init(&mcq->tasklet_ctx.list); list_del_init(&mcq->tasklet_ctx.list);
mcq->tasklet_ctx.comp(mcq); mcq->tasklet_ctx.comp(mcq);
if (atomic_dec_and_test(&mcq->refcount)) if (refcount_dec_and_test(&mcq->refcount))
complete(&mcq->free); complete(&mcq->free);
if (time_after(jiffies, end)) if (time_after(jiffies, end))
break; break;
...@@ -92,7 +92,7 @@ static void mlx4_add_cq_to_tasklet(struct mlx4_cq *cq) ...@@ -92,7 +92,7 @@ static void mlx4_add_cq_to_tasklet(struct mlx4_cq *cq)
* still arrive. * still arrive.
*/ */
if (list_empty_careful(&cq->tasklet_ctx.list)) { if (list_empty_careful(&cq->tasklet_ctx.list)) {
atomic_inc(&cq->refcount); refcount_inc(&cq->refcount);
kick = list_empty(&tasklet_ctx->list); kick = list_empty(&tasklet_ctx->list);
list_add_tail(&cq->tasklet_ctx.list, &tasklet_ctx->list); list_add_tail(&cq->tasklet_ctx.list, &tasklet_ctx->list);
if (kick) if (kick)
...@@ -344,7 +344,7 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, ...@@ -344,7 +344,7 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
cq->cons_index = 0; cq->cons_index = 0;
cq->arm_sn = 1; cq->arm_sn = 1;
cq->uar = uar; cq->uar = uar;
atomic_set(&cq->refcount, 1); refcount_set(&cq->refcount, 1);
init_completion(&cq->free); init_completion(&cq->free);
cq->comp = mlx4_add_cq_to_tasklet; cq->comp = mlx4_add_cq_to_tasklet;
cq->tasklet_ctx.priv = cq->tasklet_ctx.priv =
...@@ -386,7 +386,7 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq) ...@@ -386,7 +386,7 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq)
priv->eq_table.eq[MLX4_EQ_ASYNC].irq) priv->eq_table.eq[MLX4_EQ_ASYNC].irq)
synchronize_irq(priv->eq_table.eq[MLX4_EQ_ASYNC].irq); synchronize_irq(priv->eq_table.eq[MLX4_EQ_ASYNC].irq);
if (atomic_dec_and_test(&cq->refcount)) if (refcount_dec_and_test(&cq->refcount))
complete(&cq->free); complete(&cq->free);
wait_for_completion(&cq->free); wait_for_completion(&cq->free);
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#include <linux/cpu_rmap.h> #include <linux/cpu_rmap.h>
#include <linux/crash_dump.h> #include <linux/crash_dump.h>
#include <linux/atomic.h> #include <linux/refcount.h>
#include <linux/timecounter.h> #include <linux/timecounter.h>
...@@ -751,7 +751,7 @@ struct mlx4_cq { ...@@ -751,7 +751,7 @@ struct mlx4_cq {
int cqn; int cqn;
unsigned vector; unsigned vector;
atomic_t refcount; refcount_t refcount;
struct completion free; struct completion free;
struct { struct {
struct list_head list; struct list_head list;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment