Commit 88fe4924 authored by Linus Torvalds's avatar Linus Torvalds

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
parents be61af33 65527a51
...@@ -950,6 +950,11 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, ...@@ -950,6 +950,11 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel,
if (!fl->cctx->rpdev) if (!fl->cctx->rpdev)
return -EPIPE; 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); ctx = fastrpc_context_alloc(fl, kernel, sc, args);
if (IS_ERR(ctx)) if (IS_ERR(ctx))
return PTR_ERR(ctx); return PTR_ERR(ctx);
......
...@@ -992,7 +992,6 @@ void hl_debugfs_add_device(struct hl_device *hdev) ...@@ -992,7 +992,6 @@ void hl_debugfs_add_device(struct hl_device *hdev)
struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs; struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
int count = ARRAY_SIZE(hl_debugfs_list); int count = ARRAY_SIZE(hl_debugfs_list);
struct hl_debugfs_entry *entry; struct hl_debugfs_entry *entry;
struct dentry *ent;
int i; int i;
dev_entry->hdev = hdev; dev_entry->hdev = hdev;
...@@ -1105,13 +1104,11 @@ void hl_debugfs_add_device(struct hl_device *hdev) ...@@ -1105,13 +1104,11 @@ void hl_debugfs_add_device(struct hl_device *hdev)
&hl_security_violations_fops); &hl_security_violations_fops);
for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) { for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) {
debugfs_create_file(hl_debugfs_list[i].name,
ent = debugfs_create_file(hl_debugfs_list[i].name,
0444, 0444,
dev_entry->root, dev_entry->root,
entry, entry,
&hl_debugfs_fops); &hl_debugfs_fops);
entry->dent = ent;
entry->info_ent = &hl_debugfs_list[i]; entry->info_ent = &hl_debugfs_list[i];
entry->dev_entry = dev_entry; entry->dev_entry = dev_entry;
} }
......
...@@ -93,12 +93,19 @@ void hl_hpriv_put(struct hl_fpriv *hpriv) ...@@ -93,12 +93,19 @@ void hl_hpriv_put(struct hl_fpriv *hpriv)
static int hl_device_release(struct inode *inode, struct file *filp) static int hl_device_release(struct inode *inode, struct file *filp)
{ {
struct hl_fpriv *hpriv = filp->private_data; 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_cb_mgr_fini(hpriv->hdev, &hpriv->cb_mgr);
hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr); hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr);
filp->private_data = NULL;
hl_hpriv_put(hpriv); hl_hpriv_put(hpriv);
return 0; return 0;
...@@ -107,15 +114,20 @@ static int hl_device_release(struct inode *inode, struct file *filp) ...@@ -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) static int hl_device_release_ctrl(struct inode *inode, struct file *filp)
{ {
struct hl_fpriv *hpriv = filp->private_data; struct hl_fpriv *hpriv = filp->private_data;
struct hl_device *hdev; struct hl_device *hdev = hpriv->hdev;
filp->private_data = NULL; 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); mutex_lock(&hdev->fpriv_list_lock);
list_del(&hpriv->dev_node); list_del(&hpriv->dev_node);
mutex_unlock(&hdev->fpriv_list_lock); mutex_unlock(&hdev->fpriv_list_lock);
out:
put_pid(hpriv->taskpid);
kfree(hpriv); kfree(hpriv);
...@@ -134,8 +146,14 @@ static int hl_device_release_ctrl(struct inode *inode, struct file *filp) ...@@ -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) static int hl_mmap(struct file *filp, struct vm_area_struct *vma)
{ {
struct hl_fpriv *hpriv = filp->private_data; struct hl_fpriv *hpriv = filp->private_data;
struct hl_device *hdev = hpriv->hdev;
unsigned long vm_pgoff; 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; vm_pgoff = vma->vm_pgoff;
vma->vm_pgoff = HL_MMAP_OFFSET_VALUE_GET(vm_pgoff); vma->vm_pgoff = HL_MMAP_OFFSET_VALUE_GET(vm_pgoff);
...@@ -883,6 +901,16 @@ static int device_kill_open_processes(struct hl_device *hdev, u32 timeout) ...@@ -883,6 +901,16 @@ static int device_kill_open_processes(struct hl_device *hdev, u32 timeout)
return -EBUSY; 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 * hl_device_reset - reset the device
* *
...@@ -1556,8 +1584,10 @@ void hl_device_fini(struct hl_device *hdev) ...@@ -1556,8 +1584,10 @@ void hl_device_fini(struct hl_device *hdev)
HL_PENDING_RESET_LONG_SEC); HL_PENDING_RESET_LONG_SEC);
rc = device_kill_open_processes(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"); dev_crit(hdev->dev, "Failed to kill all open processes\n");
device_disable_open_processes(hdev);
}
hl_cb_pool_fini(hdev); hl_cb_pool_fini(hdev);
......
...@@ -1465,12 +1465,10 @@ struct hl_info_list { ...@@ -1465,12 +1465,10 @@ struct hl_info_list {
/** /**
* struct hl_debugfs_entry - debugfs dentry wrapper. * struct hl_debugfs_entry - debugfs dentry wrapper.
* @dent: base debugfs entry structure.
* @info_ent: dentry realted ops. * @info_ent: dentry realted ops.
* @dev_entry: ASIC specific debugfs manager. * @dev_entry: ASIC specific debugfs manager.
*/ */
struct hl_debugfs_entry { struct hl_debugfs_entry {
struct dentry *dent;
const struct hl_info_list *info_ent; const struct hl_info_list *info_ent;
struct hl_dbg_device_entry *dev_entry; struct hl_dbg_device_entry *dev_entry;
}; };
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
* All Rights Reserved. * All Rights Reserved.
*/ */
#define pr_fmt(fmt) "habanalabs: " fmt
#include <uapi/misc/habanalabs.h> #include <uapi/misc/habanalabs.h>
#include "habanalabs.h" #include "habanalabs.h"
...@@ -682,6 +684,11 @@ long hl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) ...@@ -682,6 +684,11 @@ long hl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
const struct hl_ioctl_desc *ioctl = NULL; const struct hl_ioctl_desc *ioctl = NULL;
unsigned int nr = _IOC_NR(cmd); 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)) { if ((nr >= HL_COMMAND_START) && (nr < HL_COMMAND_END)) {
ioctl = &hl_ioctls[nr]; ioctl = &hl_ioctls[nr];
} else { } else {
...@@ -700,6 +707,11 @@ long hl_ioctl_control(struct file *filep, unsigned int cmd, unsigned long arg) ...@@ -700,6 +707,11 @@ long hl_ioctl_control(struct file *filep, unsigned int cmd, unsigned long arg)
const struct hl_ioctl_desc *ioctl = NULL; const struct hl_ioctl_desc *ioctl = NULL;
unsigned int nr = _IOC_NR(cmd); 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)) { if (nr == _IOC_NR(HL_IOCTL_INFO)) {
ioctl = &hl_ioctls_control[nr]; ioctl = &hl_ioctls_control[nr];
} else { } else {
......
...@@ -47,7 +47,7 @@ inline u32 hl_cq_inc_ptr(u32 ptr) ...@@ -47,7 +47,7 @@ inline u32 hl_cq_inc_ptr(u32 ptr)
* Increment ptr by 1. If it reaches the number of event queue * Increment ptr by 1. If it reaches the number of event queue
* entries, set it to 0 * entries, set it to 0
*/ */
inline u32 hl_eq_inc_ptr(u32 ptr) static inline u32 hl_eq_inc_ptr(u32 ptr)
{ {
ptr++; ptr++;
if (unlikely(ptr == HL_EQ_LENGTH)) if (unlikely(ptr == HL_EQ_LENGTH))
......
...@@ -499,18 +499,32 @@ static void hl_mmu_pa_page_with_offset(struct hl_ctx *ctx, u64 virt_addr, ...@@ -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 */ else /* HL_VA_RANGE_TYPE_DRAM */
p = &prop->dmmu; p = &prop->dmmu;
/* if ((hops->range_type == HL_VA_RANGE_TYPE_DRAM) &&
* find the correct hop shift field in hl_mmu_properties structure !is_power_of_2(prop->dram_page_size)) {
* in order to determine the right maks for the page offset. u32 bit;
*/ u64 page_offset_mask;
hop0_shift_off = offsetof(struct hl_mmu_properties, hop0_shift); u64 phys_addr_mask;
p = (char *)p + hop0_shift_off;
p = (char *)p + ((hops->used_hops - 1) * sizeof(u64)); bit = __ffs64((u64)prop->dram_page_size);
hop_shift = *(u64 *)p; page_offset_mask = ((1ull << bit) - 1);
offset_mask = (1ull << hop_shift) - 1; phys_addr_mask = ~page_offset_mask;
addr_mask = ~(offset_mask); *phys_addr = (tmp_phys_addr & phys_addr_mask) |
*phys_addr = (tmp_phys_addr & addr_mask) | (virt_addr & page_offset_mask);
(virt_addr & 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) int hl_mmu_va_to_pa(struct hl_ctx *ctx, u64 virt_addr, u64 *phys_addr)
......
...@@ -140,6 +140,7 @@ static const struct of_device_id pvpanic_mmio_match[] = { ...@@ -140,6 +140,7 @@ static const struct of_device_id pvpanic_mmio_match[] = {
{ .compatible = "qemu,pvpanic-mmio", }, { .compatible = "qemu,pvpanic-mmio", },
{} {}
}; };
MODULE_DEVICE_TABLE(of, pvpanic_mmio_match);
static const struct acpi_device_id pvpanic_device_ids[] = { static const struct acpi_device_id pvpanic_device_ids[] = {
{ "QEMU0001", 0 }, { "QEMU0001", 0 },
......
...@@ -333,7 +333,7 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd, ...@@ -333,7 +333,7 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd,
acrn_ioreq_request_clear(vm); acrn_ioreq_request_clear(vm);
break; break;
case ACRN_IOCTL_PM_GET_CPU_STATE: 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))) sizeof(cstate_cmd)))
return -EFAULT; return -EFAULT;
...@@ -404,6 +404,14 @@ static ssize_t remove_cpu_store(struct device *dev, ...@@ -404,6 +404,14 @@ static ssize_t remove_cpu_store(struct device *dev,
} }
static DEVICE_ATTR_WO(remove_cpu); 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[] = { static struct attribute *acrn_attrs[] = {
&dev_attr_remove_cpu.attr, &dev_attr_remove_cpu.attr,
NULL NULL
...@@ -411,6 +419,7 @@ static struct attribute *acrn_attrs[] = { ...@@ -411,6 +419,7 @@ static struct attribute *acrn_attrs[] = {
static struct attribute_group acrn_attr_group = { static struct attribute_group acrn_attr_group = {
.attrs = acrn_attrs, .attrs = acrn_attrs,
.is_visible = acrn_attr_visible,
}; };
static const struct attribute_group *acrn_attr_groups[] = { static const struct attribute_group *acrn_attr_groups[] = {
......
...@@ -112,7 +112,7 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args) ...@@ -112,7 +112,7 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args)
{ {
struct eventfd_ctx *eventfd = NULL; struct eventfd_ctx *eventfd = NULL;
struct hsm_irqfd *irqfd, *tmp; struct hsm_irqfd *irqfd, *tmp;
unsigned int events; __poll_t events;
struct fd f; struct fd f;
int ret = 0; int ret = 0;
...@@ -158,9 +158,9 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args) ...@@ -158,9 +158,9 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args)
mutex_unlock(&vm->irqfds_lock); mutex_unlock(&vm->irqfds_lock);
/* Check the pending event in this stage */ /* 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); acrn_irqfd_inject(irqfd);
fdput(f); fdput(f);
......
...@@ -108,6 +108,8 @@ static inline void cpu_maps_update_done(void) ...@@ -108,6 +108,8 @@ static inline void cpu_maps_update_done(void)
{ {
} }
static inline int add_cpu(unsigned int cpu) { return 0;}
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
extern struct bus_type cpu_subsys; extern struct bus_type cpu_subsys;
...@@ -137,6 +139,7 @@ static inline int cpus_read_trylock(void) { return true; } ...@@ -137,6 +139,7 @@ static inline int cpus_read_trylock(void) { return true; }
static inline void lockdep_assert_cpus_held(void) { } static inline void lockdep_assert_cpus_held(void) { }
static inline void cpu_hotplug_disable(void) { } static inline void cpu_hotplug_disable(void) { }
static inline void cpu_hotplug_enable(void) { } static inline void cpu_hotplug_enable(void) { }
static inline int remove_cpu(unsigned int cpu) { return -EPERM; }
static inline void smp_shutdown_nonboot_cpus(unsigned int primary_cpu) { } static inline void smp_shutdown_nonboot_cpus(unsigned int primary_cpu) { }
#endif /* !CONFIG_HOTPLUG_CPU */ #endif /* !CONFIG_HOTPLUG_CPU */
......
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