Skip to content

Commit

Permalink
Merge tag 'char-misc-5.0-rc6' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/gregkh/char-misc

Pull char/misc fixes from Greg KH:
 "Here are some small char and misc driver fixes for 5.0-rc6.

  Nothing huge here, some more binderfs fixups found as people use it,
  and there is a "large" selftest added to validate the binderfs code,
  which makes up the majority of this pull request.

  There's also some small mei and mic fixes to resolve some reported
  issues.

  All of these have been in linux-next for over a week with no reported
  issues"

* tag 'char-misc-5.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  mic: vop: Fix crash on remove
  mic: vop: Fix use-after-free on remove
  binderfs: remove separate device_initcall()
  fpga: stratix10-soc: fix wrong of_node_put() in init function
  mic: vop: Fix broken virtqueues
  mei: free read cb on ctrl_wr list flush
  samples: mei: use /dev/mei0 instead of /dev/mei
  mei: me: add ice lake point device id.
  binderfs: respect limit on binder control creation
  binder: fix CONFIG_ANDROID_BINDER_DEVICES
  selftests: add binderfs selftests
  • Loading branch information
torvalds committed Feb 8, 2019
2 parents 8c8e62c + 4bf13fd commit 6809054
Show file tree
Hide file tree
Showing 14 changed files with 380 additions and 55 deletions.
37 changes: 22 additions & 15 deletions drivers/android/binder.c
Original file line number Diff line number Diff line change
Expand Up @@ -5854,9 +5854,10 @@ static int __init init_binder_device(const char *name)
static int __init binder_init(void)
{
int ret;
char *device_name, *device_names, *device_tmp;
char *device_name, *device_tmp;
struct binder_device *device;
struct hlist_node *tmp;
char *device_names = NULL;

ret = binder_alloc_shrinker_init();
if (ret)
Expand Down Expand Up @@ -5898,23 +5899,29 @@ static int __init binder_init(void)
&transaction_log_fops);
}

/*
* Copy the module_parameter string, because we don't want to
* tokenize it in-place.
*/
device_names = kstrdup(binder_devices_param, GFP_KERNEL);
if (!device_names) {
ret = -ENOMEM;
goto err_alloc_device_names_failed;
}
if (strcmp(binder_devices_param, "") != 0) {
/*
* Copy the module_parameter string, because we don't want to
* tokenize it in-place.
*/
device_names = kstrdup(binder_devices_param, GFP_KERNEL);
if (!device_names) {
ret = -ENOMEM;
goto err_alloc_device_names_failed;
}

device_tmp = device_names;
while ((device_name = strsep(&device_tmp, ","))) {
ret = init_binder_device(device_name);
if (ret)
goto err_init_binder_device_failed;
device_tmp = device_names;
while ((device_name = strsep(&device_tmp, ","))) {
ret = init_binder_device(device_name);
if (ret)
goto err_init_binder_device_failed;
}
}

ret = init_binderfs();
if (ret)
goto err_init_binder_device_failed;

return ret;

err_init_binder_device_failed:
Expand Down
9 changes: 9 additions & 0 deletions drivers/android/binder_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,13 @@ static inline bool is_binderfs_device(const struct inode *inode)
}
#endif

#ifdef CONFIG_ANDROID_BINDERFS
extern int __init init_binderfs(void);
#else
static inline int __init init_binderfs(void)
{
return 0;
}
#endif

#endif /* _LINUX_BINDER_INTERNAL_H */
14 changes: 10 additions & 4 deletions drivers/android/binderfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,11 @@ static int binderfs_binder_ctl_create(struct super_block *sb)
struct inode *inode = NULL;
struct dentry *root = sb->s_root;
struct binderfs_info *info = sb->s_fs_info;
#if defined(CONFIG_IPC_NS)
bool use_reserve = (info->ipc_ns == &init_ipc_ns);
#else
bool use_reserve = true;
#endif

device = kzalloc(sizeof(*device), GFP_KERNEL);
if (!device)
Expand All @@ -413,7 +418,10 @@ static int binderfs_binder_ctl_create(struct super_block *sb)

/* Reserve a new minor number for the new device. */
mutex_lock(&binderfs_minors_mutex);
minor = ida_alloc_max(&binderfs_minors, BINDERFS_MAX_MINOR, GFP_KERNEL);
minor = ida_alloc_max(&binderfs_minors,
use_reserve ? BINDERFS_MAX_MINOR :
BINDERFS_MAX_MINOR_CAPPED,
GFP_KERNEL);
mutex_unlock(&binderfs_minors_mutex);
if (minor < 0) {
ret = minor;
Expand Down Expand Up @@ -542,7 +550,7 @@ static struct file_system_type binder_fs_type = {
.fs_flags = FS_USERNS_MOUNT,
};

static int __init init_binderfs(void)
int __init init_binderfs(void)
{
int ret;

Expand All @@ -560,5 +568,3 @@ static int __init init_binderfs(void)

return ret;
}

device_initcall(init_binderfs);
5 changes: 1 addition & 4 deletions drivers/fpga/stratix10-soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,14 +508,11 @@ static int __init s10_init(void)
return -ENODEV;

np = of_find_matching_node(fw_np, s10_of_match);
if (!np) {
of_node_put(fw_np);
if (!np)
return -ENODEV;
}

of_node_put(np);
ret = of_platform_populate(fw_np, s10_of_match, NULL, NULL);
of_node_put(fw_np);
if (ret)
return ret;

Expand Down
5 changes: 4 additions & 1 deletion drivers/misc/mei/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,11 @@ static void mei_io_list_flush_cl(struct list_head *head,
struct mei_cl_cb *cb, *next;

list_for_each_entry_safe(cb, next, head, list) {
if (cl == cb->cl)
if (cl == cb->cl) {
list_del_init(&cb->list);
if (cb->fop_type == MEI_FOP_READ)
mei_io_cb_free(cb);
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/misc/mei/hw-me-regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@
#define MEI_DEV_ID_CNP_H 0xA360 /* Cannon Point H */
#define MEI_DEV_ID_CNP_H_4 0xA364 /* Cannon Point H 4 (iTouch) */

#define MEI_DEV_ID_ICP_LP 0x34E0 /* Ice Lake Point LP */

/*
* MEI HW Section
*/
Expand Down
2 changes: 2 additions & 0 deletions drivers/misc/mei/pci-me.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
{MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H, MEI_ME_PCH12_CFG)},
{MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H_4, MEI_ME_PCH8_CFG)},

{MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)},

/* required last entry */
{0, }
};
Expand Down
73 changes: 43 additions & 30 deletions drivers/misc/mic/vop/vop_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
* @dc: Virtio device control
* @vpdev: VOP device which is the parent for this virtio device
* @vr: Buffer for accessing the VRING
* @used: Buffer for used
* @used_virt: Virtual address of used ring
* @used: DMA address of used ring
* @used_size: Size of the used buffer
* @reset_done: Track whether VOP reset is complete
* @virtio_cookie: Cookie returned upon requesting a interrupt
Expand All @@ -61,6 +62,7 @@ struct _vop_vdev {
struct mic_device_ctrl __iomem *dc;
struct vop_device *vpdev;
void __iomem *vr[VOP_MAX_VRINGS];
void *used_virt[VOP_MAX_VRINGS];
dma_addr_t used[VOP_MAX_VRINGS];
int used_size[VOP_MAX_VRINGS];
struct completion reset_done;
Expand Down Expand Up @@ -260,12 +262,12 @@ static bool vop_notify(struct virtqueue *vq)
static void vop_del_vq(struct virtqueue *vq, int n)
{
struct _vop_vdev *vdev = to_vopvdev(vq->vdev);
struct vring *vr = (struct vring *)(vq + 1);
struct vop_device *vpdev = vdev->vpdev;

dma_unmap_single(&vpdev->dev, vdev->used[n],
vdev->used_size[n], DMA_BIDIRECTIONAL);
free_pages((unsigned long)vr->used, get_order(vdev->used_size[n]));
free_pages((unsigned long)vdev->used_virt[n],
get_order(vdev->used_size[n]));
vring_del_virtqueue(vq);
vpdev->hw_ops->iounmap(vpdev, vdev->vr[n]);
vdev->vr[n] = NULL;
Expand All @@ -283,6 +285,26 @@ static void vop_del_vqs(struct virtio_device *dev)
vop_del_vq(vq, idx++);
}

static struct virtqueue *vop_new_virtqueue(unsigned int index,
unsigned int num,
struct virtio_device *vdev,
bool context,
void *pages,
bool (*notify)(struct virtqueue *vq),
void (*callback)(struct virtqueue *vq),
const char *name,
void *used)
{
bool weak_barriers = false;
struct vring vring;

vring_init(&vring, num, pages, MIC_VIRTIO_RING_ALIGN);
vring.used = used;

return __vring_new_virtqueue(index, vring, vdev, weak_barriers, context,
notify, callback, name);
}

/*
* This routine will assign vring's allocated in host/io memory. Code in
* virtio_ring.c however continues to access this io memory as if it were local
Expand All @@ -302,7 +324,6 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev,
struct _mic_vring_info __iomem *info;
void *used;
int vr_size, _vr_size, err, magic;
struct vring *vr;
u8 type = ioread8(&vdev->desc->type);

if (index >= ioread8(&vdev->desc->num_vq))
Expand All @@ -322,17 +343,7 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev,
return ERR_PTR(-ENOMEM);
vdev->vr[index] = va;
memset_io(va, 0x0, _vr_size);
vq = vring_new_virtqueue(
index,
le16_to_cpu(config.num), MIC_VIRTIO_RING_ALIGN,
dev,
false,
ctx,
(void __force *)va, vop_notify, callback, name);
if (!vq) {
err = -ENOMEM;
goto unmap;
}

info = va + _vr_size;
magic = ioread32(&info->magic);

Expand All @@ -341,45 +352,45 @@ static struct virtqueue *vop_find_vq(struct virtio_device *dev,
goto unmap;
}

/* Allocate and reassign used ring now */
vdev->used_size[index] = PAGE_ALIGN(sizeof(__u16) * 3 +
sizeof(struct vring_used_elem) *
le16_to_cpu(config.num));
used = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
get_order(vdev->used_size[index]));
vdev->used_virt[index] = used;
if (!used) {
err = -ENOMEM;
dev_err(_vop_dev(vdev), "%s %d err %d\n",
__func__, __LINE__, err);
goto del_vq;
goto unmap;
}

vq = vop_new_virtqueue(index, le16_to_cpu(config.num), dev, ctx,
(void __force *)va, vop_notify, callback,
name, used);
if (!vq) {
err = -ENOMEM;
goto free_used;
}

vdev->used[index] = dma_map_single(&vpdev->dev, used,
vdev->used_size[index],
DMA_BIDIRECTIONAL);
if (dma_mapping_error(&vpdev->dev, vdev->used[index])) {
err = -ENOMEM;
dev_err(_vop_dev(vdev), "%s %d err %d\n",
__func__, __LINE__, err);
goto free_used;
goto del_vq;
}
writeq(vdev->used[index], &vqconfig->used_address);
/*
* To reassign the used ring here we are directly accessing
* struct vring_virtqueue which is a private data structure
* in virtio_ring.c. At the minimum, a BUILD_BUG_ON() in
* vring_new_virtqueue() would ensure that
* (&vq->vring == (struct vring *) (&vq->vq + 1));
*/
vr = (struct vring *)(vq + 1);
vr->used = used;

vq->priv = vdev;
return vq;
del_vq:
vring_del_virtqueue(vq);
free_used:
free_pages((unsigned long)used,
get_order(vdev->used_size[index]));
del_vq:
vring_del_virtqueue(vq);
unmap:
vpdev->hw_ops->iounmap(vpdev, vdev->vr[index]);
return ERR_PTR(err);
Expand Down Expand Up @@ -581,6 +592,8 @@ static int _vop_remove_device(struct mic_device_desc __iomem *d,
int ret = -1;

if (ioread8(&dc->config_change) == MIC_VIRTIO_PARAM_DEV_REMOVE) {
struct device *dev = get_device(&vdev->vdev.dev);

dev_dbg(&vpdev->dev,
"%s %d config_change %d type %d vdev %p\n",
__func__, __LINE__,
Expand All @@ -592,7 +605,7 @@ static int _vop_remove_device(struct mic_device_desc __iomem *d,
iowrite8(-1, &dc->h2c_vdev_db);
if (status & VIRTIO_CONFIG_S_DRIVER_OK)
wait_for_completion(&vdev->reset_done);
put_device(&vdev->vdev.dev);
put_device(dev);
iowrite8(1, &dc->guest_ack);
dev_dbg(&vpdev->dev, "%s %d guest_ack %d\n",
__func__, __LINE__, ioread8(&dc->guest_ack));
Expand Down
2 changes: 1 addition & 1 deletion samples/mei/mei-amt-version.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ static bool mei_init(struct mei *me, const uuid_le *guid,

me->verbose = verbose;

me->fd = open("/dev/mei", O_RDWR);
me->fd = open("/dev/mei0", O_RDWR);
if (me->fd == -1) {
mei_err(me, "Cannot establish a handle to the Intel MEI driver\n");
goto err;
Expand Down
1 change: 1 addition & 0 deletions tools/testing/selftests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ TARGETS += drivers/dma-buf
TARGETS += efivarfs
TARGETS += exec
TARGETS += filesystems
TARGETS += filesystems/binderfs
TARGETS += firmware
TARGETS += ftrace
TARGETS += futex
Expand Down
1 change: 1 addition & 0 deletions tools/testing/selftests/filesystems/binderfs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
binderfs_test
6 changes: 6 additions & 0 deletions tools/testing/selftests/filesystems/binderfs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0

CFLAGS += -I../../../../../usr/include/
TEST_GEN_PROGS := binderfs_test

include ../../lib.mk
Loading

0 comments on commit 6809054

Please sign in to comment.