diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-03-13 12:38:44 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-03-13 12:38:44 -0800 |
commit | 88fe49249c99de14e543c632a46248d85411ab9e (patch) | |
tree | 35b7986bece31193db263cb2201cb266a9bdf33c /drivers | |
parent | be61af330e09cfdde29fa5516b2ee015ebdc8bea (diff) | |
parent | 65527a51c66f4edfa28602643d7dd4fa366eb826 (diff) |
Merge tag 'char-misc-5.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver fixes from Greg KH:
"Here are some small misc/char driver fixes to resolve some reported
problems:
- habanalabs driver fixes
- Acrn build fixes (reported many times)
- pvpanic module table export fix
All of these have been in linux-next for a while with no reported
issues"
* tag 'char-misc-5.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
misc/pvpanic: Export module FDT device table
misc: fastrpc: restrict user apps from sending kernel RPC messages
virt: acrn: Correct type casting of argument of copy_from_user()
virt: acrn: Use EPOLLIN instead of POLLIN
virt: acrn: Use vfs_poll() instead of f_op->poll()
virt: acrn: Make remove_cpu sysfs invisible with !CONFIG_HOTPLUG_CPU
cpu/hotplug: Fix build error of using {add,remove}_cpu() with !CONFIG_SMP
habanalabs: fix debugfs address translation
habanalabs: Disable file operations after device is removed
habanalabs: Call put_pid() when releasing control device
drivers: habanalabs: remove unused dentry pointer for debugfs files
habanalabs: mark hl_eq_inc_ptr() as static
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/misc/fastrpc.c | 5 | ||||
-rw-r--r-- | drivers/misc/habanalabs/common/debugfs.c | 5 | ||||
-rw-r--r-- | drivers/misc/habanalabs/common/device.c | 40 | ||||
-rw-r--r-- | drivers/misc/habanalabs/common/habanalabs.h | 2 | ||||
-rw-r--r-- | drivers/misc/habanalabs/common/habanalabs_ioctl.c | 12 | ||||
-rw-r--r-- | drivers/misc/habanalabs/common/irq.c | 2 | ||||
-rw-r--r-- | drivers/misc/habanalabs/common/mmu/mmu.c | 38 | ||||
-rw-r--r-- | drivers/misc/pvpanic.c | 1 | ||||
-rw-r--r-- | drivers/virt/acrn/hsm.c | 11 | ||||
-rw-r--r-- | drivers/virt/acrn/irqfd.c | 6 |
10 files changed, 94 insertions, 28 deletions
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index f12e909034ac..beda610e6b30 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -950,6 +950,11 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, if (!fl->cctx->rpdev) return -EPIPE; + if (handle == FASTRPC_INIT_HANDLE && !kernel) { + dev_warn_ratelimited(fl->sctx->dev, "user app trying to send a kernel RPC message (%d)\n", handle); + return -EPERM; + } + ctx = fastrpc_context_alloc(fl, kernel, sc, args); if (IS_ERR(ctx)) return PTR_ERR(ctx); diff --git a/drivers/misc/habanalabs/common/debugfs.c b/drivers/misc/habanalabs/common/debugfs.c index df847a6d19f4..9f19bee7b592 100644 --- a/drivers/misc/habanalabs/common/debugfs.c +++ b/drivers/misc/habanalabs/common/debugfs.c @@ -992,7 +992,6 @@ void hl_debugfs_add_device(struct hl_device *hdev) struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs; int count = ARRAY_SIZE(hl_debugfs_list); struct hl_debugfs_entry *entry; - struct dentry *ent; int i; dev_entry->hdev = hdev; @@ -1105,13 +1104,11 @@ void hl_debugfs_add_device(struct hl_device *hdev) &hl_security_violations_fops); for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) { - - ent = debugfs_create_file(hl_debugfs_list[i].name, + debugfs_create_file(hl_debugfs_list[i].name, 0444, dev_entry->root, entry, &hl_debugfs_fops); - entry->dent = ent; entry->info_ent = &hl_debugfs_list[i]; entry->dev_entry = dev_entry; } diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 15fcb5c31c4b..334009e83823 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -93,12 +93,19 @@ void hl_hpriv_put(struct hl_fpriv *hpriv) static int hl_device_release(struct inode *inode, struct file *filp) { struct hl_fpriv *hpriv = filp->private_data; + struct hl_device *hdev = hpriv->hdev; + + filp->private_data = NULL; + + if (!hdev) { + pr_crit("Closing FD after device was removed. Memory leak will occur and it is advised to reboot.\n"); + put_pid(hpriv->taskpid); + return 0; + } hl_cb_mgr_fini(hpriv->hdev, &hpriv->cb_mgr); hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr); - filp->private_data = NULL; - hl_hpriv_put(hpriv); return 0; @@ -107,15 +114,20 @@ static int hl_device_release(struct inode *inode, struct file *filp) static int hl_device_release_ctrl(struct inode *inode, struct file *filp) { struct hl_fpriv *hpriv = filp->private_data; - struct hl_device *hdev; + struct hl_device *hdev = hpriv->hdev; filp->private_data = NULL; - hdev = hpriv->hdev; + if (!hdev) { + pr_err("Closing FD after device was removed\n"); + goto out; + } mutex_lock(&hdev->fpriv_list_lock); list_del(&hpriv->dev_node); mutex_unlock(&hdev->fpriv_list_lock); +out: + put_pid(hpriv->taskpid); kfree(hpriv); @@ -134,8 +146,14 @@ static int hl_device_release_ctrl(struct inode *inode, struct file *filp) static int hl_mmap(struct file *filp, struct vm_area_struct *vma) { struct hl_fpriv *hpriv = filp->private_data; + struct hl_device *hdev = hpriv->hdev; unsigned long vm_pgoff; + if (!hdev) { + pr_err_ratelimited("Trying to mmap after device was removed! Please close FD\n"); + return -ENODEV; + } + vm_pgoff = vma->vm_pgoff; vma->vm_pgoff = HL_MMAP_OFFSET_VALUE_GET(vm_pgoff); @@ -883,6 +901,16 @@ wait_for_processes: return -EBUSY; } +static void device_disable_open_processes(struct hl_device *hdev) +{ + struct hl_fpriv *hpriv; + + mutex_lock(&hdev->fpriv_list_lock); + list_for_each_entry(hpriv, &hdev->fpriv_list, dev_node) + hpriv->hdev = NULL; + mutex_unlock(&hdev->fpriv_list_lock); +} + /* * hl_device_reset - reset the device * @@ -1556,8 +1584,10 @@ void hl_device_fini(struct hl_device *hdev) HL_PENDING_RESET_LONG_SEC); rc = device_kill_open_processes(hdev, HL_PENDING_RESET_LONG_SEC); - if (rc) + if (rc) { dev_crit(hdev->dev, "Failed to kill all open processes\n"); + device_disable_open_processes(hdev); + } hl_cb_pool_fini(hdev); diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index d933878b24d1..4b321e4f8059 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -1465,12 +1465,10 @@ struct hl_info_list { /** * struct hl_debugfs_entry - debugfs dentry wrapper. - * @dent: base debugfs entry structure. * @info_ent: dentry realted ops. * @dev_entry: ASIC specific debugfs manager. */ struct hl_debugfs_entry { - struct dentry *dent; const struct hl_info_list *info_ent; struct hl_dbg_device_entry *dev_entry; }; diff --git a/drivers/misc/habanalabs/common/habanalabs_ioctl.c b/drivers/misc/habanalabs/common/habanalabs_ioctl.c index 03af61cecd37..083a30969c5f 100644 --- a/drivers/misc/habanalabs/common/habanalabs_ioctl.c +++ b/drivers/misc/habanalabs/common/habanalabs_ioctl.c @@ -5,6 +5,8 @@ * All Rights Reserved. */ +#define pr_fmt(fmt) "habanalabs: " fmt + #include <uapi/misc/habanalabs.h> #include "habanalabs.h" @@ -682,6 +684,11 @@ long hl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) const struct hl_ioctl_desc *ioctl = NULL; unsigned int nr = _IOC_NR(cmd); + if (!hdev) { + pr_err_ratelimited("Sending ioctl after device was removed! Please close FD\n"); + return -ENODEV; + } + if ((nr >= HL_COMMAND_START) && (nr < HL_COMMAND_END)) { ioctl = &hl_ioctls[nr]; } else { @@ -700,6 +707,11 @@ long hl_ioctl_control(struct file *filep, unsigned int cmd, unsigned long arg) const struct hl_ioctl_desc *ioctl = NULL; unsigned int nr = _IOC_NR(cmd); + if (!hdev) { + pr_err_ratelimited("Sending ioctl after device was removed! Please close FD\n"); + return -ENODEV; + } + if (nr == _IOC_NR(HL_IOCTL_INFO)) { ioctl = &hl_ioctls_control[nr]; } else { diff --git a/drivers/misc/habanalabs/common/irq.c b/drivers/misc/habanalabs/common/irq.c index de53fb5f978a..44a0522b59b9 100644 --- a/drivers/misc/habanalabs/common/irq.c +++ b/drivers/misc/habanalabs/common/irq.c @@ -47,7 +47,7 @@ inline u32 hl_cq_inc_ptr(u32 ptr) * Increment ptr by 1. If it reaches the number of event queue * entries, set it to 0 */ -inline u32 hl_eq_inc_ptr(u32 ptr) +static inline u32 hl_eq_inc_ptr(u32 ptr) { ptr++; if (unlikely(ptr == HL_EQ_LENGTH)) diff --git a/drivers/misc/habanalabs/common/mmu/mmu.c b/drivers/misc/habanalabs/common/mmu/mmu.c index 71703a32350f..93c9e5f587e1 100644 --- a/drivers/misc/habanalabs/common/mmu/mmu.c +++ b/drivers/misc/habanalabs/common/mmu/mmu.c @@ -499,18 +499,32 @@ static void hl_mmu_pa_page_with_offset(struct hl_ctx *ctx, u64 virt_addr, else /* HL_VA_RANGE_TYPE_DRAM */ p = &prop->dmmu; - /* - * find the correct hop shift field in hl_mmu_properties structure - * in order to determine the right maks for the page offset. - */ - hop0_shift_off = offsetof(struct hl_mmu_properties, hop0_shift); - p = (char *)p + hop0_shift_off; - p = (char *)p + ((hops->used_hops - 1) * sizeof(u64)); - hop_shift = *(u64 *)p; - offset_mask = (1ull << hop_shift) - 1; - addr_mask = ~(offset_mask); - *phys_addr = (tmp_phys_addr & addr_mask) | - (virt_addr & offset_mask); + if ((hops->range_type == HL_VA_RANGE_TYPE_DRAM) && + !is_power_of_2(prop->dram_page_size)) { + u32 bit; + u64 page_offset_mask; + u64 phys_addr_mask; + + bit = __ffs64((u64)prop->dram_page_size); + page_offset_mask = ((1ull << bit) - 1); + phys_addr_mask = ~page_offset_mask; + *phys_addr = (tmp_phys_addr & phys_addr_mask) | + (virt_addr & page_offset_mask); + } else { + /* + * find the correct hop shift field in hl_mmu_properties + * structure in order to determine the right masks + * for the page offset. + */ + hop0_shift_off = offsetof(struct hl_mmu_properties, hop0_shift); + p = (char *)p + hop0_shift_off; + p = (char *)p + ((hops->used_hops - 1) * sizeof(u64)); + hop_shift = *(u64 *)p; + offset_mask = (1ull << hop_shift) - 1; + addr_mask = ~(offset_mask); + *phys_addr = (tmp_phys_addr & addr_mask) | + (virt_addr & offset_mask); + } } int hl_mmu_va_to_pa(struct hl_ctx *ctx, u64 virt_addr, u64 *phys_addr) diff --git a/drivers/misc/pvpanic.c b/drivers/misc/pvpanic.c index 9f350e05ef68..f1655f5ca016 100644 --- a/drivers/misc/pvpanic.c +++ b/drivers/misc/pvpanic.c @@ -140,6 +140,7 @@ static const struct of_device_id pvpanic_mmio_match[] = { { .compatible = "qemu,pvpanic-mmio", }, {} }; +MODULE_DEVICE_TABLE(of, pvpanic_mmio_match); static const struct acpi_device_id pvpanic_device_ids[] = { { "QEMU0001", 0 }, diff --git a/drivers/virt/acrn/hsm.c b/drivers/virt/acrn/hsm.c index 1f6b7c54a1a4..130e12b8652a 100644 --- a/drivers/virt/acrn/hsm.c +++ b/drivers/virt/acrn/hsm.c @@ -333,7 +333,7 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd, acrn_ioreq_request_clear(vm); break; case ACRN_IOCTL_PM_GET_CPU_STATE: - if (copy_from_user(&cstate_cmd, (void *)ioctl_param, + if (copy_from_user(&cstate_cmd, (void __user *)ioctl_param, sizeof(cstate_cmd))) return -EFAULT; @@ -404,6 +404,14 @@ fail_remove: } static DEVICE_ATTR_WO(remove_cpu); +static umode_t acrn_attr_visible(struct kobject *kobj, struct attribute *a, int n) +{ + if (a == &dev_attr_remove_cpu.attr) + return IS_ENABLED(CONFIG_HOTPLUG_CPU) ? a->mode : 0; + + return a->mode; +} + static struct attribute *acrn_attrs[] = { &dev_attr_remove_cpu.attr, NULL @@ -411,6 +419,7 @@ static struct attribute *acrn_attrs[] = { static struct attribute_group acrn_attr_group = { .attrs = acrn_attrs, + .is_visible = acrn_attr_visible, }; static const struct attribute_group *acrn_attr_groups[] = { diff --git a/drivers/virt/acrn/irqfd.c b/drivers/virt/acrn/irqfd.c index a8766d528e29..df5184979b28 100644 --- a/drivers/virt/acrn/irqfd.c +++ b/drivers/virt/acrn/irqfd.c @@ -112,7 +112,7 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args) { struct eventfd_ctx *eventfd = NULL; struct hsm_irqfd *irqfd, *tmp; - unsigned int events; + __poll_t events; struct fd f; int ret = 0; @@ -158,9 +158,9 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args) mutex_unlock(&vm->irqfds_lock); /* Check the pending event in this stage */ - events = f.file->f_op->poll(f.file, &irqfd->pt); + events = vfs_poll(f.file, &irqfd->pt); - if (events & POLLIN) + if (events & EPOLLIN) acrn_irqfd_inject(irqfd); fdput(f); |