Char/Misc fixes for 4.20-rc5
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. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCXAFbOg8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+yn0wwCbB8w2/v6N0jMtEKk6teuai4ShRgMAnjz/Wau6 wKvvPMG3naIZ/2+2I6qy =Bcyr -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
b6839ef26e
@ -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,
|
|||||||
|
|
||||||
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,
|
||||||
if (!buffer->allow_user_free) {
|
(u64)data_ptr);
|
||||||
binder_user_error("%d:%d BC_FREE_BUFFER u%016llx matched unreturned buffer\n",
|
} else {
|
||||||
proc->pid, thread->pid, (u64)data_ptr);
|
binder_user_error(
|
||||||
|
"%d:%d BC_FREE_BUFFER u%016llx no match\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(
|
|||||||
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(
|
|||||||
|
|
||||||
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 {
|
|||||||
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
|
|||||||
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 @@
|
|||||||
#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,
|
|||||||
}
|
}
|
||||||
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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
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,
|
|||||||
|
|
||||||
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)
|
|||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user