]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/infiniband/core/uverbs_main.c
RDMA/uverbs: Atomically flush and mark closed the comp event queue
[mirror_ubuntu-bionic-kernel.git] / drivers / infiniband / core / uverbs_main.c
index 381fd9c096ae23dd3e7b7e7ec52c75b57cbe6fc8..d5a8b2f93c122eb80ca2f18dadd73f90d83c9af6 100644 (file)
@@ -425,6 +425,7 @@ static int ib_uverbs_comp_event_close(struct inode *inode, struct file *filp)
                        list_del(&entry->obj_list);
                kfree(entry);
        }
+       file->ev_queue.is_closed = 1;
        spin_unlock_irq(&file->ev_queue.lock);
 
        uverbs_close_fd(filp);
@@ -648,12 +649,21 @@ static int verify_command_mask(struct ib_device *ib_dev, __u32 command)
        return -1;
 }
 
+static bool verify_command_idx(u32 command, bool extended)
+{
+       if (extended)
+               return command < ARRAY_SIZE(uverbs_ex_cmd_table);
+
+       return command < ARRAY_SIZE(uverbs_cmd_table);
+}
+
 static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
                             size_t count, loff_t *pos)
 {
        struct ib_uverbs_file *file = filp->private_data;
        struct ib_device *ib_dev;
        struct ib_uverbs_cmd_hdr hdr;
+       bool extended_command;
        __u32 command;
        __u32 flags;
        int srcu_key;
@@ -686,6 +696,15 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
        }
 
        command = hdr.command & IB_USER_VERBS_CMD_COMMAND_MASK;
+       flags = (hdr.command &
+                IB_USER_VERBS_CMD_FLAGS_MASK) >> IB_USER_VERBS_CMD_FLAGS_SHIFT;
+
+       extended_command = flags & IB_USER_VERBS_CMD_FLAG_EXTENDED;
+       if (!verify_command_idx(command, extended_command)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
        if (verify_command_mask(ib_dev, command)) {
                ret = -EOPNOTSUPP;
                goto out;
@@ -697,12 +716,8 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
                goto out;
        }
 
-       flags = (hdr.command &
-                IB_USER_VERBS_CMD_FLAGS_MASK) >> IB_USER_VERBS_CMD_FLAGS_SHIFT;
-
        if (!flags) {
-               if (command >= ARRAY_SIZE(uverbs_cmd_table) ||
-                   !uverbs_cmd_table[command]) {
+               if (!uverbs_cmd_table[command]) {
                        ret = -EINVAL;
                        goto out;
                }
@@ -723,8 +738,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
                struct ib_udata uhw;
                size_t written_count = count;
 
-               if (command >= ARRAY_SIZE(uverbs_ex_cmd_table) ||
-                   !uverbs_ex_cmd_table[command]) {
+               if (!uverbs_ex_cmd_table[command]) {
                        ret = -ENOSYS;
                        goto out;
                }