Commit b6839ef2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'char-misc-4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

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
parents d7aca8a7 6484a677
...@@ -2974,7 +2974,6 @@ static void binder_transaction(struct binder_proc *proc, ...@@ -2974,7 +2974,6 @@ static void binder_transaction(struct binder_proc *proc,
t->buffer = NULL; t->buffer = NULL;
goto err_binder_alloc_buf_failed; goto err_binder_alloc_buf_failed;
} }
t->buffer->allow_user_free = 0;
t->buffer->debug_id = t->debug_id; t->buffer->debug_id = t->debug_id;
t->buffer->transaction = t; t->buffer->transaction = t;
t->buffer->target_node = target_node; t->buffer->target_node = target_node;
...@@ -3510,14 +3509,18 @@ static int binder_thread_write(struct binder_proc *proc, ...@@ -3510,14 +3509,18 @@ static int binder_thread_write(struct binder_proc *proc,
buffer = binder_alloc_prepare_to_free(&proc->alloc, buffer = binder_alloc_prepare_to_free(&proc->alloc,
data_ptr); data_ptr);
if (buffer == NULL) { if (IS_ERR_OR_NULL(buffer)) {
binder_user_error("%d:%d BC_FREE_BUFFER u%016llx no match\n", if (PTR_ERR(buffer) == -EPERM) {
proc->pid, thread->pid, (u64)data_ptr); binder_user_error(
break; "%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);
} }
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);
break; break;
} }
binder_debug(BINDER_DEBUG_FREE_BUFFER, binder_debug(BINDER_DEBUG_FREE_BUFFER,
......
...@@ -151,16 +151,12 @@ static struct binder_buffer *binder_alloc_prepare_to_free_locked( ...@@ -151,16 +151,12 @@ static struct binder_buffer *binder_alloc_prepare_to_free_locked(
else { else {
/* /*
* Guard against user threads attempting to * 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) { if (!buffer->allow_user_free)
binder_alloc_debug(BINDER_DEBUG_USER_ERROR, return ERR_PTR(-EPERM);
"%d:%d FREE_BUFFER u%016llx user freed buffer twice\n", buffer->allow_user_free = 0;
alloc->pid, current->pid,
(u64)user_ptr);
return NULL;
}
buffer->free_in_progress = 1;
return buffer; return buffer;
} }
} }
...@@ -500,7 +496,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked( ...@@ -500,7 +496,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked(
rb_erase(best_fit, &alloc->free_buffers); rb_erase(best_fit, &alloc->free_buffers);
buffer->free = 0; buffer->free = 0;
buffer->free_in_progress = 0; buffer->allow_user_free = 0;
binder_insert_allocated_buffer_locked(alloc, buffer); binder_insert_allocated_buffer_locked(alloc, buffer);
binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC,
"%d: binder_alloc_buf size %zd got %pK\n", "%d: binder_alloc_buf size %zd got %pK\n",
......
...@@ -50,8 +50,7 @@ struct binder_buffer { ...@@ -50,8 +50,7 @@ struct binder_buffer {
unsigned free:1; unsigned free:1;
unsigned allow_user_free:1; unsigned allow_user_free:1;
unsigned async_transaction:1; unsigned async_transaction:1;
unsigned free_in_progress:1; unsigned debug_id:29;
unsigned debug_id:28;
struct binder_transaction *transaction; struct binder_transaction *transaction;
......
...@@ -46,6 +46,7 @@ config FSI_MASTER_AST_CF ...@@ -46,6 +46,7 @@ config FSI_MASTER_AST_CF
tristate "FSI master based on Aspeed ColdFire coprocessor" tristate "FSI master based on Aspeed ColdFire coprocessor"
depends on GPIOLIB depends on GPIOLIB
depends on GPIO_ASPEED depends on GPIO_ASPEED
select GENERIC_ALLOCATOR
---help--- ---help---
This option enables a FSI master using the AST2400 and AST2500 GPIO This option enables a FSI master using the AST2400 and AST2500 GPIO
lines driven by the internal ColdFire coprocessor. This requires lines driven by the internal ColdFire coprocessor. This requires
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/list.h> #include <linux/list.h>
#include <uapi/linux/fsi.h> #include <uapi/linux/fsi.h>
......
...@@ -516,6 +516,14 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, ...@@ -516,6 +516,14 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
} }
wait_for_completion(&msginfo->waitevent); 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) { if (channel->rescind) {
ret = -ENODEV; ret = -ENODEV;
goto cleanup; goto cleanup;
......
...@@ -416,7 +416,7 @@ static int scif_create_remote_lookup(struct scif_dev *remote_dev, ...@@ -416,7 +416,7 @@ static int scif_create_remote_lookup(struct scif_dev *remote_dev,
if (err) if (err)
goto error_window; goto error_window;
err = scif_map_page(&window->num_pages_lookup.lookup[j], err = scif_map_page(&window->num_pages_lookup.lookup[j],
vmalloc_dma_phys ? vmalloc_num_pages ?
vmalloc_to_page(&window->num_pages[i]) : vmalloc_to_page(&window->num_pages[i]) :
virt_to_page(&window->num_pages[i]), virt_to_page(&window->num_pages[i]),
remote_dev); remote_dev);
......
...@@ -863,6 +863,30 @@ static ssize_t key_store(struct device *dev, struct device_attribute *attr, ...@@ -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 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, static ssize_t nvm_authenticate_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
...@@ -912,10 +936,18 @@ static ssize_t nvm_authenticate_store(struct device *dev, ...@@ -912,10 +936,18 @@ static ssize_t nvm_authenticate_store(struct device *dev,
sw->nvm->authenticating = true; 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); ret = nvm_authenticate_host(sw);
else if (ret)
nvm_authenticate_complete(sw);
} else {
ret = nvm_authenticate_device(sw); ret = nvm_authenticate_device(sw);
}
pm_runtime_mark_last_busy(&sw->dev); pm_runtime_mark_last_busy(&sw->dev);
pm_runtime_put_autosuspend(&sw->dev); pm_runtime_put_autosuspend(&sw->dev);
} }
...@@ -1334,6 +1366,10 @@ static int tb_switch_add_dma_port(struct tb_switch *sw) ...@@ -1334,6 +1366,10 @@ static int tb_switch_add_dma_port(struct tb_switch *sw)
if (ret <= 0) if (ret <= 0)
return ret; return ret;
/* Now we can allow root port to suspend again */
if (!tb_route(sw))
nvm_authenticate_complete(sw);
if (status) { if (status) {
tb_sw_info(sw, "switch flash authentication failed\n"); tb_sw_info(sw, "switch flash authentication failed\n");
tb_switch_set_uuid(sw); tb_switch_set_uuid(sw);
......
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