Merge tag 'char-misc-4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregk...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Nov 2018 20:43:17 +0000 (12:43 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Nov 2018 20:43:17 +0000 (12:43 -0800)
Pull char/misc fixes from Greg KH:
 "Here are a few small char/misc driver fixes for 4.20-rc5 that resolve
  a number of reported issues.

  The "largest" here is the thunderbolt patch, which resolves an issue
  with NVM upgrade, the smallest being some fsi driver fixes. There's
  also a hyperv bugfix, and the usual binder bugfixes.

  All of these have been in linux-next with no reported issues"

* tag 'char-misc-4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  misc: mic/scif: fix copy-paste error in scif_create_remote_lookup
  thunderbolt: Prevent root port runtime suspend during NVM upgrade
  Drivers: hv: vmbus: check the creation_status in vmbus_establish_gpadl()
  binder: fix race that allows malicious free of live buffer
  fsi: fsi-scom.c: Remove duplicate header
  fsi: master-ast-cf: select GENERIC_ALLOCATOR

drivers/android/binder.c
drivers/android/binder_alloc.c
drivers/android/binder_alloc.h
drivers/fsi/Kconfig
drivers/fsi/fsi-scom.c
drivers/hv/channel.c
drivers/misc/mic/scif/scif_rma.c
drivers/thunderbolt/switch.c

index cb30a524d16d8a9846caceba2a7aa2c9aba6e4ae..9f1000d2a40c791925430d30e316e3e45a000245 100644 (file)
@@ -2974,7 +2974,6 @@ static void binder_transaction(struct binder_proc *proc,
                t->buffer = NULL;
                goto err_binder_alloc_buf_failed;
        }
-       t->buffer->allow_user_free = 0;
        t->buffer->debug_id = t->debug_id;
        t->buffer->transaction = t;
        t->buffer->target_node = target_node;
@@ -3510,14 +3509,18 @@ static int binder_thread_write(struct binder_proc *proc,
 
                        buffer = binder_alloc_prepare_to_free(&proc->alloc,
                                                              data_ptr);
-                       if (buffer == NULL) {
-                               binder_user_error("%d:%d BC_FREE_BUFFER u%016llx no match\n",
-                                       proc->pid, thread->pid, (u64)data_ptr);
-                               break;
-                       }
-                       if (!buffer->allow_user_free) {
-                               binder_user_error("%d:%d BC_FREE_BUFFER u%016llx matched unreturned buffer\n",
-                                       proc->pid, thread->pid, (u64)data_ptr);
+                       if (IS_ERR_OR_NULL(buffer)) {
+                               if (PTR_ERR(buffer) == -EPERM) {
+                                       binder_user_error(
+                                               "%d:%d BC_FREE_BUFFER u%016llx matched unreturned or currently freeing buffer\n",
+                                               proc->pid, thread->pid,
+                                               (u64)data_ptr);
+                               } else {
+                                       binder_user_error(
+                                               "%d:%d BC_FREE_BUFFER u%016llx no match\n",
+                                               proc->pid, thread->pid,
+                                               (u64)data_ptr);
+                               }
                                break;
                        }
                        binder_debug(BINDER_DEBUG_FREE_BUFFER,
index 64fd96eada31f42e5677a72de837fafa2987165b..030c98f35cca73aaf5168f559e259e658b5d05ad 100644 (file)
@@ -151,16 +151,12 @@ static struct binder_buffer *binder_alloc_prepare_to_free_locked(
                else {
                        /*
                         * Guard against user threads attempting to
-                        * free the buffer twice
+                        * free the buffer when in use by kernel or
+                        * after it's already been freed.
                         */
-                       if (buffer->free_in_progress) {
-                               binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
-                                                  "%d:%d FREE_BUFFER u%016llx user freed buffer twice\n",
-                                                  alloc->pid, current->pid,
-                                                  (u64)user_ptr);
-                               return NULL;
-                       }
-                       buffer->free_in_progress = 1;
+                       if (!buffer->allow_user_free)
+                               return ERR_PTR(-EPERM);
+                       buffer->allow_user_free = 0;
                        return buffer;
                }
        }
@@ -500,7 +496,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked(
 
        rb_erase(best_fit, &alloc->free_buffers);
        buffer->free = 0;
-       buffer->free_in_progress = 0;
+       buffer->allow_user_free = 0;
        binder_insert_allocated_buffer_locked(alloc, buffer);
        binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC,
                     "%d: binder_alloc_buf size %zd got %pK\n",
index 9ef64e56385667a53abeab2f41f67b198a8ce86e..fb3238c74c8a8671282cf9a428febaf182880821 100644 (file)
@@ -50,8 +50,7 @@ struct binder_buffer {
        unsigned free:1;
        unsigned allow_user_free:1;
        unsigned async_transaction:1;
-       unsigned free_in_progress:1;
-       unsigned debug_id:28;
+       unsigned debug_id:29;
 
        struct binder_transaction *transaction;
 
index af3a20dd5aa4a504524c0bd36f932ed328903c2c..99c99a5d57fe26d573310f7f30b50e7bf11cecf7 100644 (file)
@@ -46,6 +46,7 @@ config FSI_MASTER_AST_CF
        tristate "FSI master based on Aspeed ColdFire coprocessor"
        depends on GPIOLIB
        depends on GPIO_ASPEED
+       select GENERIC_ALLOCATOR
        ---help---
        This option enables a FSI master using the AST2400 and AST2500 GPIO
        lines driven by the internal ColdFire coprocessor. This requires
index df94021dd9d12bc32b18873076151d3fccbae5c7..81dc01ac2351fcac14e3d5be1978a4876e751375 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/fs.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
-#include <linux/cdev.h>
 #include <linux/list.h>
 
 #include <uapi/linux/fsi.h>
index de8193f3b8381a38b40f9fe59b9daf7314cbcf47..fe00b12e44178a4b9f3f4f5bfd7b447457c417d5 100644 (file)
@@ -516,6 +516,14 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
        }
        wait_for_completion(&msginfo->waitevent);
 
+       if (msginfo->response.gpadl_created.creation_status != 0) {
+               pr_err("Failed to establish GPADL: err = 0x%x\n",
+                      msginfo->response.gpadl_created.creation_status);
+
+               ret = -EDQUOT;
+               goto cleanup;
+       }
+
        if (channel->rescind) {
                ret = -ENODEV;
                goto cleanup;
index c824329f7012adfc765e4b1872185f5b148fd445..0e4193cb08cf1ac9d3f095810c082e5c3298775b 100644 (file)
@@ -416,7 +416,7 @@ static int scif_create_remote_lookup(struct scif_dev *remote_dev,
                if (err)
                        goto error_window;
                err = scif_map_page(&window->num_pages_lookup.lookup[j],
-                                   vmalloc_dma_phys ?
+                                   vmalloc_num_pages ?
                                    vmalloc_to_page(&window->num_pages[i]) :
                                    virt_to_page(&window->num_pages[i]),
                                    remote_dev);
index 52ff854f0d6c10898d060b78a0b8c13212f8c192..cd96994dc0947137672d4b82a3d017e1cd1c8520 100644 (file)
@@ -863,6 +863,30 @@ static ssize_t key_store(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR(key, 0600, key_show, key_store);
 
+static void nvm_authenticate_start(struct tb_switch *sw)
+{
+       struct pci_dev *root_port;
+
+       /*
+        * During host router NVM upgrade we should not allow root port to
+        * go into D3cold because some root ports cannot trigger PME
+        * itself. To be on the safe side keep the root port in D0 during
+        * the whole upgrade process.
+        */
+       root_port = pci_find_pcie_root_port(sw->tb->nhi->pdev);
+       if (root_port)
+               pm_runtime_get_noresume(&root_port->dev);
+}
+
+static void nvm_authenticate_complete(struct tb_switch *sw)
+{
+       struct pci_dev *root_port;
+
+       root_port = pci_find_pcie_root_port(sw->tb->nhi->pdev);
+       if (root_port)
+               pm_runtime_put(&root_port->dev);
+}
+
 static ssize_t nvm_authenticate_show(struct device *dev,
        struct device_attribute *attr, char *buf)
 {
@@ -912,10 +936,18 @@ static ssize_t nvm_authenticate_store(struct device *dev,
 
                sw->nvm->authenticating = true;
 
-               if (!tb_route(sw))
+               if (!tb_route(sw)) {
+                       /*
+                        * Keep root port from suspending as long as the
+                        * NVM upgrade process is running.
+                        */
+                       nvm_authenticate_start(sw);
                        ret = nvm_authenticate_host(sw);
-               else
+                       if (ret)
+                               nvm_authenticate_complete(sw);
+               } else {
                        ret = nvm_authenticate_device(sw);
+               }
                pm_runtime_mark_last_busy(&sw->dev);
                pm_runtime_put_autosuspend(&sw->dev);
        }
@@ -1334,6 +1366,10 @@ static int tb_switch_add_dma_port(struct tb_switch *sw)
        if (ret <= 0)
                return ret;
 
+       /* Now we can allow root port to suspend again */
+       if (!tb_route(sw))
+               nvm_authenticate_complete(sw);
+
        if (status) {
                tb_sw_info(sw, "switch flash authentication failed\n");
                tb_switch_set_uuid(sw);