Char/Misc driver fixes for 5.2-rc4
Here are some small char and misc driver fixes for 5.2-rc4 to resolve a
number of reported issues.
The most "notable" one here is the kernel headers in proc^Wsysfs fixes.
Those changes move the header file info into sysfs and fixes the build
issues that you reported.
Other than that, a bunch of small habanalabs driver fixes, some fpga
driver fixes, and a few other tiny driver fixes.
All of these have been in linux-next for a while with no reported
issues.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-----BEGIN PGP SIGNATURE-----
iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCXPuEVg8cZ3JlZ0Brcm9h
aC5jb20ACgkQMUfUDdst+yma0QCfVPa7r1rHqljz1UgvjKJTzVg8g9wAn1W1mddx
MIlG+0+ZnBdaPzyzoY1O
=0LJD
-----END PGP SIGNATURE-----
Merge tag 'char-misc-5.2-rc4' 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 char and misc driver fixes for 5.2-rc4 to resolve
a number of reported issues.
The most "notable" one here is the kernel headers in proc^Wsysfs
fixes. Those changes move the header file info into sysfs and fixes
the build issues that you reported.
Other than that, a bunch of small habanalabs driver fixes, some fpga
driver fixes, and a few other tiny driver fixes.
All of these have been in linux-next for a while with no reported
issues"
* tag 'char-misc-5.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
habanalabs: Read upper bits of trace buffer from RWPHI
habanalabs: Fix virtual address access via debugfs for 2MB pages
fpga: zynqmp-fpga: Correctly handle error pointer
habanalabs: fix bug in checking huge page optimization
habanalabs: Avoid using a non-initialized MMU cache mutex
habanalabs: fix debugfs code
uapi/habanalabs: add opcode for enable/disable device debug mode
habanalabs: halt debug engines on user process close
test_firmware: Use correct snprintf() limit
genwqe: Prevent an integer overflow in the ioctl
parport: Fix mem leak in parport_register_dev_model
fpga: dfl: expand minor range when registering chrdev region
fpga: dfl: Add lockdep classes for pdata->lock
fpga: dfl: afu: Pass the correct device to dma_mapping_error()
fpga: stratix10-soc: fix use-after-free on s10_init()
w1: ds2408: Fix typo after 49695ac468
(reset on output_write retry with readback)
kheaders: Do not regenerate archive if config is not changed
kheaders: Move from proc to sysfs
lkdtm/bugs: Adjust recursion test to avoid elision
lkdtm/usercopy: Moves the KERNEL_DS test to non-canonical
This commit is contained in:
commit
1ce2c85137
@ -399,7 +399,7 @@ int afu_dma_map_region(struct dfl_feature_platform_data *pdata,
|
||||
region->pages[0], 0,
|
||||
region->length,
|
||||
DMA_BIDIRECTIONAL);
|
||||
if (dma_mapping_error(&pdata->dev->dev, region->iova)) {
|
||||
if (dma_mapping_error(dfl_fpga_pdata_to_parent(pdata), region->iova)) {
|
||||
dev_err(&pdata->dev->dev, "failed to map for dma\n");
|
||||
ret = -EFAULT;
|
||||
goto unpin_pages;
|
||||
|
@ -40,6 +40,13 @@ enum dfl_fpga_devt_type {
|
||||
DFL_FPGA_DEVT_MAX,
|
||||
};
|
||||
|
||||
static struct lock_class_key dfl_pdata_keys[DFL_ID_MAX];
|
||||
|
||||
static const char *dfl_pdata_key_strings[DFL_ID_MAX] = {
|
||||
"dfl-fme-pdata",
|
||||
"dfl-port-pdata",
|
||||
};
|
||||
|
||||
/**
|
||||
* dfl_dev_info - dfl feature device information.
|
||||
* @name: name string of the feature platform device.
|
||||
@ -315,7 +322,7 @@ static void dfl_chardev_uinit(void)
|
||||
for (i = 0; i < DFL_FPGA_DEVT_MAX; i++)
|
||||
if (MAJOR(dfl_chrdevs[i].devt)) {
|
||||
unregister_chrdev_region(dfl_chrdevs[i].devt,
|
||||
MINORMASK);
|
||||
MINORMASK + 1);
|
||||
dfl_chrdevs[i].devt = MKDEV(0, 0);
|
||||
}
|
||||
}
|
||||
@ -325,8 +332,8 @@ static int dfl_chardev_init(void)
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < DFL_FPGA_DEVT_MAX; i++) {
|
||||
ret = alloc_chrdev_region(&dfl_chrdevs[i].devt, 0, MINORMASK,
|
||||
dfl_chrdevs[i].name);
|
||||
ret = alloc_chrdev_region(&dfl_chrdevs[i].devt, 0,
|
||||
MINORMASK + 1, dfl_chrdevs[i].name);
|
||||
if (ret)
|
||||
goto exit;
|
||||
}
|
||||
@ -443,11 +450,16 @@ static int build_info_commit_dev(struct build_feature_devs_info *binfo)
|
||||
struct platform_device *fdev = binfo->feature_dev;
|
||||
struct dfl_feature_platform_data *pdata;
|
||||
struct dfl_feature_info *finfo, *p;
|
||||
enum dfl_id_type type;
|
||||
int ret, index = 0;
|
||||
|
||||
if (!fdev)
|
||||
return 0;
|
||||
|
||||
type = feature_dev_id_type(fdev);
|
||||
if (WARN_ON_ONCE(type >= DFL_ID_MAX))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* we do not need to care for the memory which is associated with
|
||||
* the platform device. After calling platform_device_unregister(),
|
||||
@ -463,6 +475,8 @@ static int build_info_commit_dev(struct build_feature_devs_info *binfo)
|
||||
pdata->num = binfo->feature_num;
|
||||
pdata->dfl_cdev = binfo->cdev;
|
||||
mutex_init(&pdata->lock);
|
||||
lockdep_set_class_and_name(&pdata->lock, &dfl_pdata_keys[type],
|
||||
dfl_pdata_key_strings[type]);
|
||||
|
||||
/*
|
||||
* the count should be initialized to 0 to make sure
|
||||
@ -497,7 +511,7 @@ static int build_info_commit_dev(struct build_feature_devs_info *binfo)
|
||||
|
||||
ret = platform_device_add(binfo->feature_dev);
|
||||
if (!ret) {
|
||||
if (feature_dev_id_type(binfo->feature_dev) == PORT_ID)
|
||||
if (type == PORT_ID)
|
||||
dfl_fpga_cdev_add_port_dev(binfo->cdev,
|
||||
binfo->feature_dev);
|
||||
else
|
||||
|
@ -507,12 +507,16 @@ static int __init s10_init(void)
|
||||
if (!fw_np)
|
||||
return -ENODEV;
|
||||
|
||||
of_node_get(fw_np);
|
||||
np = of_find_matching_node(fw_np, s10_of_match);
|
||||
if (!np)
|
||||
if (!np) {
|
||||
of_node_put(fw_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;
|
||||
|
||||
|
@ -47,7 +47,7 @@ static int zynqmp_fpga_ops_write(struct fpga_manager *mgr,
|
||||
char *kbuf;
|
||||
int ret;
|
||||
|
||||
if (!eemi_ops || !eemi_ops->fpga_load)
|
||||
if (IS_ERR_OR_NULL(eemi_ops) || !eemi_ops->fpga_load)
|
||||
return -ENXIO;
|
||||
|
||||
priv = mgr->priv;
|
||||
@ -81,7 +81,7 @@ static enum fpga_mgr_states zynqmp_fpga_ops_state(struct fpga_manager *mgr)
|
||||
const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
|
||||
u32 status;
|
||||
|
||||
if (!eemi_ops || !eemi_ops->fpga_get_status)
|
||||
if (IS_ERR_OR_NULL(eemi_ops) || !eemi_ops->fpga_get_status)
|
||||
return FPGA_MGR_STATE_UNKNOWN;
|
||||
|
||||
eemi_ops->fpga_get_status(&status);
|
||||
|
@ -780,6 +780,8 @@ static int genwqe_pin_mem(struct genwqe_file *cfile, struct genwqe_mem *m)
|
||||
|
||||
if ((m->addr == 0x0) || (m->size == 0))
|
||||
return -EINVAL;
|
||||
if (m->size > ULONG_MAX - PAGE_SIZE - (m->addr & ~PAGE_MASK))
|
||||
return -EINVAL;
|
||||
|
||||
map_addr = (m->addr & PAGE_MASK);
|
||||
map_size = round_up(m->size + (m->addr & ~PAGE_MASK), PAGE_SIZE);
|
||||
|
@ -586,6 +586,10 @@ int genwqe_user_vmap(struct genwqe_dev *cd, struct dma_mapping *m, void *uaddr,
|
||||
/* determine space needed for page_list. */
|
||||
data = (unsigned long)uaddr;
|
||||
offs = offset_in_page(data);
|
||||
if (size > ULONG_MAX - PAGE_SIZE - offs) {
|
||||
m->size = 0; /* mark unused and not added */
|
||||
return -EINVAL;
|
||||
}
|
||||
m->nr_pages = DIV_ROUND_UP(offs + size, PAGE_SIZE);
|
||||
|
||||
m->page_list = kcalloc(m->nr_pages,
|
||||
|
@ -26,6 +26,12 @@ static void hl_ctx_fini(struct hl_ctx *ctx)
|
||||
dma_fence_put(ctx->cs_pending[i]);
|
||||
|
||||
if (ctx->asid != HL_KERNEL_ASID_ID) {
|
||||
/*
|
||||
* The engines are stopped as there is no executing CS, but the
|
||||
* Coresight might be still working by accessing addresses
|
||||
* related to the stopped engines. Hence stop it explicitly.
|
||||
*/
|
||||
hdev->asic_funcs->halt_coresight(hdev);
|
||||
hl_vm_ctx_fini(ctx);
|
||||
hl_asid_free(hdev, ctx->asid);
|
||||
}
|
||||
|
@ -459,41 +459,31 @@ static ssize_t mmu_write(struct file *file, const char __user *buf,
|
||||
struct hl_debugfs_entry *entry = s->private;
|
||||
struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
|
||||
struct hl_device *hdev = dev_entry->hdev;
|
||||
char kbuf[MMU_KBUF_SIZE], asid_kbuf[MMU_ASID_BUF_SIZE],
|
||||
addr_kbuf[MMU_ADDR_BUF_SIZE];
|
||||
char kbuf[MMU_KBUF_SIZE];
|
||||
char *c;
|
||||
ssize_t rc;
|
||||
|
||||
if (!hdev->mmu_enable)
|
||||
return count;
|
||||
|
||||
memset(kbuf, 0, sizeof(kbuf));
|
||||
memset(asid_kbuf, 0, sizeof(asid_kbuf));
|
||||
memset(addr_kbuf, 0, sizeof(addr_kbuf));
|
||||
|
||||
if (count > sizeof(kbuf) - 1)
|
||||
goto err;
|
||||
if (copy_from_user(kbuf, buf, count))
|
||||
goto err;
|
||||
|
||||
kbuf[MMU_KBUF_SIZE - 1] = 0;
|
||||
kbuf[count] = 0;
|
||||
|
||||
c = strchr(kbuf, ' ');
|
||||
if (!c)
|
||||
goto err;
|
||||
*c = '\0';
|
||||
|
||||
memcpy(asid_kbuf, kbuf, c - kbuf);
|
||||
|
||||
rc = kstrtouint(asid_kbuf, 10, &dev_entry->mmu_asid);
|
||||
rc = kstrtouint(kbuf, 10, &dev_entry->mmu_asid);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
c = strstr(kbuf, " 0x");
|
||||
if (!c)
|
||||
if (strncmp(c+1, "0x", 2))
|
||||
goto err;
|
||||
|
||||
c += 3;
|
||||
memcpy(addr_kbuf, c, (kbuf + count) - c);
|
||||
|
||||
rc = kstrtoull(addr_kbuf, 16, &dev_entry->mmu_addr);
|
||||
rc = kstrtoull(c+3, 16, &dev_entry->mmu_addr);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
@ -510,6 +500,7 @@ static int device_va_to_pa(struct hl_device *hdev, u64 virt_addr,
|
||||
{
|
||||
struct hl_ctx *ctx = hdev->user_ctx;
|
||||
u64 hop_addr, hop_pte_addr, hop_pte;
|
||||
u64 offset_mask = HOP4_MASK | OFFSET_MASK;
|
||||
int rc = 0;
|
||||
|
||||
if (!ctx) {
|
||||
@ -552,12 +543,14 @@ static int device_va_to_pa(struct hl_device *hdev, u64 virt_addr,
|
||||
goto not_mapped;
|
||||
hop_pte_addr = get_hop4_pte_addr(ctx, hop_addr, virt_addr);
|
||||
hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
|
||||
|
||||
offset_mask = OFFSET_MASK;
|
||||
}
|
||||
|
||||
if (!(hop_pte & PAGE_PRESENT_MASK))
|
||||
goto not_mapped;
|
||||
|
||||
*phys_addr = (hop_pte & PTE_PHYS_ADDR_MASK) | (virt_addr & OFFSET_MASK);
|
||||
*phys_addr = (hop_pte & ~offset_mask) | (virt_addr & offset_mask);
|
||||
|
||||
goto out;
|
||||
|
||||
@ -600,10 +593,8 @@ static ssize_t hl_data_read32(struct file *f, char __user *buf,
|
||||
}
|
||||
|
||||
sprintf(tmp_buf, "0x%08x\n", val);
|
||||
rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
|
||||
strlen(tmp_buf) + 1);
|
||||
|
||||
return rc;
|
||||
return simple_read_from_buffer(buf, count, ppos, tmp_buf,
|
||||
strlen(tmp_buf));
|
||||
}
|
||||
|
||||
static ssize_t hl_data_write32(struct file *f, const char __user *buf,
|
||||
@ -645,7 +636,6 @@ static ssize_t hl_get_power_state(struct file *f, char __user *buf,
|
||||
struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
|
||||
struct hl_device *hdev = entry->hdev;
|
||||
char tmp_buf[200];
|
||||
ssize_t rc;
|
||||
int i;
|
||||
|
||||
if (*ppos)
|
||||
@ -660,10 +650,8 @@ static ssize_t hl_get_power_state(struct file *f, char __user *buf,
|
||||
|
||||
sprintf(tmp_buf,
|
||||
"current power state: %d\n1 - D0\n2 - D3hot\n3 - Unknown\n", i);
|
||||
rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
|
||||
strlen(tmp_buf) + 1);
|
||||
|
||||
return rc;
|
||||
return simple_read_from_buffer(buf, count, ppos, tmp_buf,
|
||||
strlen(tmp_buf));
|
||||
}
|
||||
|
||||
static ssize_t hl_set_power_state(struct file *f, const char __user *buf,
|
||||
@ -716,8 +704,8 @@ static ssize_t hl_i2c_data_read(struct file *f, char __user *buf,
|
||||
}
|
||||
|
||||
sprintf(tmp_buf, "0x%02x\n", val);
|
||||
rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
|
||||
strlen(tmp_buf) + 1);
|
||||
rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
|
||||
strlen(tmp_buf));
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -806,18 +794,9 @@ static ssize_t hl_led2_write(struct file *f, const char __user *buf,
|
||||
static ssize_t hl_device_read(struct file *f, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char tmp_buf[200];
|
||||
ssize_t rc;
|
||||
|
||||
if (*ppos)
|
||||
return 0;
|
||||
|
||||
sprintf(tmp_buf,
|
||||
"Valid values: disable, enable, suspend, resume, cpu_timeout\n");
|
||||
rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
|
||||
strlen(tmp_buf) + 1);
|
||||
|
||||
return rc;
|
||||
static const char *help =
|
||||
"Valid values: disable, enable, suspend, resume, cpu_timeout\n";
|
||||
return simple_read_from_buffer(buf, count, ppos, help, strlen(help));
|
||||
}
|
||||
|
||||
static ssize_t hl_device_write(struct file *f, const char __user *buf,
|
||||
@ -825,7 +804,7 @@ static ssize_t hl_device_write(struct file *f, const char __user *buf,
|
||||
{
|
||||
struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
|
||||
struct hl_device *hdev = entry->hdev;
|
||||
char data[30];
|
||||
char data[30] = {0};
|
||||
|
||||
/* don't allow partial writes */
|
||||
if (*ppos != 0)
|
||||
|
@ -231,6 +231,7 @@ static int device_early_init(struct hl_device *hdev)
|
||||
|
||||
mutex_init(&hdev->fd_open_cnt_lock);
|
||||
mutex_init(&hdev->send_cpu_message_lock);
|
||||
mutex_init(&hdev->mmu_cache_lock);
|
||||
INIT_LIST_HEAD(&hdev->hw_queues_mirror_list);
|
||||
spin_lock_init(&hdev->hw_queues_mirror_lock);
|
||||
atomic_set(&hdev->in_reset, 0);
|
||||
@ -260,6 +261,7 @@ early_fini:
|
||||
*/
|
||||
static void device_early_fini(struct hl_device *hdev)
|
||||
{
|
||||
mutex_destroy(&hdev->mmu_cache_lock);
|
||||
mutex_destroy(&hdev->send_cpu_message_lock);
|
||||
|
||||
hl_cb_mgr_fini(hdev, &hdev->kernel_cb_mgr);
|
||||
|
@ -4819,7 +4819,8 @@ static const struct hl_asic_funcs goya_funcs = {
|
||||
.set_dram_bar_base = goya_set_ddr_bar_base,
|
||||
.init_iatu = goya_init_iatu,
|
||||
.rreg = hl_rreg,
|
||||
.wreg = hl_wreg
|
||||
.wreg = hl_wreg,
|
||||
.halt_coresight = goya_halt_coresight
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -202,6 +202,7 @@ void goya_add_device_attr(struct hl_device *hdev,
|
||||
struct attribute_group *dev_attr_grp);
|
||||
int goya_armcp_info_get(struct hl_device *hdev);
|
||||
int goya_debug_coresight(struct hl_device *hdev, void *data);
|
||||
void goya_halt_coresight(struct hl_device *hdev);
|
||||
|
||||
void goya_mmu_prepare(struct hl_device *hdev, u32 asid);
|
||||
int goya_mmu_clear_pgt_range(struct hl_device *hdev);
|
||||
|
@ -425,8 +425,18 @@ static int goya_config_etr(struct hl_device *hdev,
|
||||
WREG32(base_reg + 0x28, 0);
|
||||
WREG32(base_reg + 0x304, 0);
|
||||
|
||||
if (params->output_size >= sizeof(u32))
|
||||
*(u32 *) params->output = RREG32(base_reg + 0x18);
|
||||
if (params->output_size >= sizeof(u64)) {
|
||||
u32 rwp, rwphi;
|
||||
|
||||
/*
|
||||
* The trace buffer address is 40 bits wide. The end of
|
||||
* the buffer is set in the RWP register (lower 32
|
||||
* bits), and in the RWPHI register (upper 8 bits).
|
||||
*/
|
||||
rwp = RREG32(base_reg + 0x18);
|
||||
rwphi = RREG32(base_reg + 0x3c) & 0xff;
|
||||
*(u64 *) params->output = ((u64) rwphi << 32) | rwp;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -626,3 +636,20 @@ int goya_debug_coresight(struct hl_device *hdev, void *data)
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void goya_halt_coresight(struct hl_device *hdev)
|
||||
{
|
||||
struct hl_debug_params params = {};
|
||||
int i, rc;
|
||||
|
||||
for (i = GOYA_ETF_FIRST ; i <= GOYA_ETF_LAST ; i++) {
|
||||
params.reg_idx = i;
|
||||
rc = goya_config_etf(hdev, ¶ms);
|
||||
if (rc)
|
||||
dev_err(hdev->dev, "halt ETF failed, %d/%d\n", rc, i);
|
||||
}
|
||||
|
||||
rc = goya_config_etr(hdev, ¶ms);
|
||||
if (rc)
|
||||
dev_err(hdev->dev, "halt ETR failed, %d\n", rc);
|
||||
}
|
||||
|
@ -501,6 +501,7 @@ enum hl_pll_frequency {
|
||||
* @init_iatu: Initialize the iATU unit inside the PCI controller.
|
||||
* @rreg: Read a register. Needed for simulator support.
|
||||
* @wreg: Write a register. Needed for simulator support.
|
||||
* @halt_coresight: stop the ETF and ETR traces.
|
||||
*/
|
||||
struct hl_asic_funcs {
|
||||
int (*early_init)(struct hl_device *hdev);
|
||||
@ -578,6 +579,7 @@ struct hl_asic_funcs {
|
||||
int (*init_iatu)(struct hl_device *hdev);
|
||||
u32 (*rreg)(struct hl_device *hdev, u32 reg);
|
||||
void (*wreg)(struct hl_device *hdev, u32 reg, u32 val);
|
||||
void (*halt_coresight)(struct hl_device *hdev);
|
||||
};
|
||||
|
||||
|
||||
|
@ -675,11 +675,6 @@ static int init_phys_pg_pack_from_userptr(struct hl_ctx *ctx,
|
||||
|
||||
total_npages += npages;
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
dma_addr &= PAGE_MASK_2MB;
|
||||
}
|
||||
|
||||
if ((npages % PGS_IN_2MB_PAGE) ||
|
||||
(dma_addr & (PAGE_SIZE_2MB - 1)))
|
||||
is_huge_page_opt = false;
|
||||
@ -704,7 +699,6 @@ static int init_phys_pg_pack_from_userptr(struct hl_ctx *ctx,
|
||||
phys_pg_pack->total_size = total_npages * page_size;
|
||||
|
||||
j = 0;
|
||||
first = true;
|
||||
for_each_sg(userptr->sgt->sgl, sg, userptr->sgt->nents, i) {
|
||||
npages = get_sg_info(sg, &dma_addr);
|
||||
|
||||
|
@ -404,15 +404,12 @@ int hl_mmu_init(struct hl_device *hdev)
|
||||
|
||||
/* MMU H/W init was already done in device hw_init() */
|
||||
|
||||
mutex_init(&hdev->mmu_cache_lock);
|
||||
|
||||
hdev->mmu_pgt_pool =
|
||||
gen_pool_create(__ffs(prop->mmu_hop_table_size), -1);
|
||||
|
||||
if (!hdev->mmu_pgt_pool) {
|
||||
dev_err(hdev->dev, "Failed to create page gen pool\n");
|
||||
rc = -ENOMEM;
|
||||
goto err_pool_create;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = gen_pool_add(hdev->mmu_pgt_pool, prop->mmu_pgt_addr +
|
||||
@ -436,8 +433,6 @@ int hl_mmu_init(struct hl_device *hdev)
|
||||
|
||||
err_pool_add:
|
||||
gen_pool_destroy(hdev->mmu_pgt_pool);
|
||||
err_pool_create:
|
||||
mutex_destroy(&hdev->mmu_cache_lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -459,7 +454,6 @@ void hl_mmu_fini(struct hl_device *hdev)
|
||||
|
||||
kvfree(hdev->mmu_shadow_hop0);
|
||||
gen_pool_destroy(hdev->mmu_pgt_pool);
|
||||
mutex_destroy(&hdev->mmu_cache_lock);
|
||||
|
||||
/* MMU H/W fini will be done in device hw_fini() */
|
||||
}
|
||||
|
@ -32,12 +32,20 @@ static int recur_count = REC_NUM_DEFAULT;
|
||||
|
||||
static DEFINE_SPINLOCK(lock_me_up);
|
||||
|
||||
static int recursive_loop(int remaining)
|
||||
/*
|
||||
* Make sure compiler does not optimize this function or stack frame away:
|
||||
* - function marked noinline
|
||||
* - stack variables are marked volatile
|
||||
* - stack variables are written (memset()) and read (pr_info())
|
||||
* - function has external effects (pr_info())
|
||||
* */
|
||||
static int noinline recursive_loop(int remaining)
|
||||
{
|
||||
char buf[REC_STACK_SIZE];
|
||||
volatile char buf[REC_STACK_SIZE];
|
||||
|
||||
/* Make sure compiler does not optimize this away. */
|
||||
memset(buf, (remaining & 0xff) | 0x1, REC_STACK_SIZE);
|
||||
memset((void *)buf, remaining & 0xFF, sizeof(buf));
|
||||
pr_info("loop %d/%d ...\n", (int)buf[remaining % sizeof(buf)],
|
||||
recur_count);
|
||||
if (!remaining)
|
||||
return 0;
|
||||
else
|
||||
@ -81,9 +89,12 @@ void lkdtm_LOOP(void)
|
||||
;
|
||||
}
|
||||
|
||||
void lkdtm_OVERFLOW(void)
|
||||
void lkdtm_EXHAUST_STACK(void)
|
||||
{
|
||||
(void) recursive_loop(recur_count);
|
||||
pr_info("Calling function with %d frame size to depth %d ...\n",
|
||||
REC_STACK_SIZE, recur_count);
|
||||
recursive_loop(recur_count);
|
||||
pr_info("FAIL: survived without exhausting stack?!\n");
|
||||
}
|
||||
|
||||
static noinline void __lkdtm_CORRUPT_STACK(void *stack)
|
||||
|
@ -106,12 +106,12 @@ static const struct crashtype crashtypes[] = {
|
||||
CRASHTYPE(WARNING),
|
||||
CRASHTYPE(EXCEPTION),
|
||||
CRASHTYPE(LOOP),
|
||||
CRASHTYPE(OVERFLOW),
|
||||
CRASHTYPE(EXHAUST_STACK),
|
||||
CRASHTYPE(CORRUPT_STACK),
|
||||
CRASHTYPE(CORRUPT_STACK_STRONG),
|
||||
CRASHTYPE(CORRUPT_LIST_ADD),
|
||||
CRASHTYPE(CORRUPT_LIST_DEL),
|
||||
CRASHTYPE(CORRUPT_USER_DS),
|
||||
CRASHTYPE(CORRUPT_STACK),
|
||||
CRASHTYPE(CORRUPT_STACK_STRONG),
|
||||
CRASHTYPE(STACK_GUARD_PAGE_LEADING),
|
||||
CRASHTYPE(STACK_GUARD_PAGE_TRAILING),
|
||||
CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE),
|
||||
|
@ -13,7 +13,7 @@ void lkdtm_BUG(void);
|
||||
void lkdtm_WARNING(void);
|
||||
void lkdtm_EXCEPTION(void);
|
||||
void lkdtm_LOOP(void);
|
||||
void lkdtm_OVERFLOW(void);
|
||||
void lkdtm_EXHAUST_STACK(void);
|
||||
void lkdtm_CORRUPT_STACK(void);
|
||||
void lkdtm_CORRUPT_STACK_STRONG(void);
|
||||
void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void);
|
||||
|
@ -324,14 +324,16 @@ free_user:
|
||||
|
||||
void lkdtm_USERCOPY_KERNEL_DS(void)
|
||||
{
|
||||
char __user *user_ptr = (char __user *)ERR_PTR(-EINVAL);
|
||||
char __user *user_ptr =
|
||||
(char __user *)(0xFUL << (sizeof(unsigned long) * 8 - 4));
|
||||
mm_segment_t old_fs = get_fs();
|
||||
char buf[10] = {0};
|
||||
|
||||
pr_info("attempting copy_to_user on unmapped kernel address\n");
|
||||
pr_info("attempting copy_to_user() to noncanonical address: %px\n",
|
||||
user_ptr);
|
||||
set_fs(KERNEL_DS);
|
||||
if (copy_to_user(user_ptr, buf, sizeof(buf)))
|
||||
pr_info("copy_to_user un unmapped kernel address failed\n");
|
||||
if (copy_to_user(user_ptr, buf, sizeof(buf)) == 0)
|
||||
pr_err("copy_to_user() to noncanonical address succeeded!?\n");
|
||||
set_fs(old_fs);
|
||||
}
|
||||
|
||||
|
@ -895,6 +895,7 @@ parport_register_dev_model(struct parport *port, const char *name,
|
||||
par_dev->devmodel = true;
|
||||
ret = device_register(&par_dev->dev);
|
||||
if (ret) {
|
||||
kfree(par_dev->state);
|
||||
put_device(&par_dev->dev);
|
||||
goto err_put_port;
|
||||
}
|
||||
@ -912,6 +913,7 @@ parport_register_dev_model(struct parport *port, const char *name,
|
||||
spin_unlock(&port->physport->pardevice_lock);
|
||||
pr_debug("%s: cannot grant exclusive access for device %s\n",
|
||||
port->name, name);
|
||||
kfree(par_dev->state);
|
||||
device_unregister(&par_dev->dev);
|
||||
goto err_put_port;
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ static ssize_t status_control_read(struct file *filp, struct kobject *kobj,
|
||||
W1_F29_REG_CONTROL_AND_STATUS, buf);
|
||||
}
|
||||
|
||||
#ifdef fCONFIG_W1_SLAVE_DS2408_READBACK
|
||||
#ifdef CONFIG_W1_SLAVE_DS2408_READBACK
|
||||
static bool optional_read_back_valid(struct w1_slave *sl, u8 expected)
|
||||
{
|
||||
u8 w1_buf[3];
|
||||
|
@ -413,6 +413,10 @@ struct hl_debug_params_spmu {
|
||||
#define HL_DEBUG_OP_SPMU 5
|
||||
/* Opcode for timestamp */
|
||||
#define HL_DEBUG_OP_TIMESTAMP 6
|
||||
/* Opcode for setting the device into or out of debug mode. The enable
|
||||
* variable should be 1 for enabling debug mode and 0 for disabling it
|
||||
*/
|
||||
#define HL_DEBUG_OP_SET_MODE 7
|
||||
|
||||
struct hl_debug_args {
|
||||
/*
|
||||
@ -574,8 +578,22 @@ struct hl_debug_args {
|
||||
*
|
||||
* This IOCTL allows the user to get debug traces from the chip.
|
||||
*
|
||||
* The user needs to provide the register index and essential data such as
|
||||
* buffer address and size.
|
||||
* Before the user can send configuration requests of the various
|
||||
* debug/profile engines, it needs to set the device into debug mode.
|
||||
* This is because the debug/profile infrastructure is shared component in the
|
||||
* device and we can't allow multiple users to access it at the same time.
|
||||
*
|
||||
* Once a user set the device into debug mode, the driver won't allow other
|
||||
* users to "work" with the device, i.e. open a FD. If there are multiple users
|
||||
* opened on the device, the driver won't allow any user to debug the device.
|
||||
*
|
||||
* For each configuration request, the user needs to provide the register index
|
||||
* and essential data such as buffer address and size.
|
||||
*
|
||||
* Once the user has finished using the debug/profile engines, he should
|
||||
* set the device into non-debug mode, i.e. disable debug mode.
|
||||
*
|
||||
* The driver can decide to "kick out" the user if he abuses this interface.
|
||||
*
|
||||
*/
|
||||
#define HL_IOCTL_DEBUG \
|
||||
|
15
init/Kconfig
15
init/Kconfig
@ -580,15 +580,14 @@ config IKCONFIG_PROC
|
||||
This option enables access to the kernel configuration file
|
||||
through /proc/config.gz.
|
||||
|
||||
config IKHEADERS_PROC
|
||||
tristate "Enable kernel header artifacts through /proc/kheaders.tar.xz"
|
||||
depends on PROC_FS
|
||||
config IKHEADERS
|
||||
tristate "Enable kernel headers through /sys/kernel/kheaders.tar.xz"
|
||||
depends on SYSFS
|
||||
help
|
||||
This option enables access to the kernel header and other artifacts that
|
||||
are generated during the build process. These can be used to build eBPF
|
||||
tracing programs, or similar programs. If you build the headers as a
|
||||
module, a module called kheaders.ko is built which can be loaded on-demand
|
||||
to get access to the headers.
|
||||
This option enables access to the in-kernel headers that are generated during
|
||||
the build process. These can be used to build eBPF tracing programs,
|
||||
or similar programs. If you build the headers as a module, a module called
|
||||
kheaders.ko is built which can be loaded on-demand to get access to headers.
|
||||
|
||||
config LOG_BUF_SHIFT
|
||||
int "Kernel log buffer size (16 => 64KB, 17 => 128KB)"
|
||||
|
@ -71,7 +71,7 @@ obj-$(CONFIG_UTS_NS) += utsname.o
|
||||
obj-$(CONFIG_USER_NS) += user_namespace.o
|
||||
obj-$(CONFIG_PID_NS) += pid_namespace.o
|
||||
obj-$(CONFIG_IKCONFIG) += configs.o
|
||||
obj-$(CONFIG_IKHEADERS_PROC) += kheaders.o
|
||||
obj-$(CONFIG_IKHEADERS) += kheaders.o
|
||||
obj-$(CONFIG_SMP) += stop_machine.o
|
||||
obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o
|
||||
obj-$(CONFIG_AUDIT) += audit.o auditfilter.o
|
||||
@ -127,7 +127,7 @@ $(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE
|
||||
$(obj)/kheaders.o: $(obj)/kheaders_data.tar.xz
|
||||
|
||||
quiet_cmd_genikh = CHK $(obj)/kheaders_data.tar.xz
|
||||
cmd_genikh = $(CONFIG_SHELL) $(srctree)/kernel/gen_ikh_data.sh $@
|
||||
cmd_genikh = $(CONFIG_SHELL) $(srctree)/kernel/gen_kheaders.sh $@
|
||||
$(obj)/kheaders_data.tar.xz: FORCE
|
||||
$(call cmd,genikh)
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# This script generates an archive consisting of kernel headers
|
||||
# for CONFIG_IKHEADERS_PROC.
|
||||
# for CONFIG_IKHEADERS.
|
||||
set -e
|
||||
spath="$(dirname "$(readlink -f "$0")")"
|
||||
kroot="$spath/.."
|
||||
@ -31,9 +31,8 @@ arch/$SRCARCH/include/
|
||||
|
||||
# This block is useful for debugging the incremental builds.
|
||||
# Uncomment it for debugging.
|
||||
# iter=1
|
||||
# if [ ! -f /tmp/iter ]; then echo 1 > /tmp/iter;
|
||||
# else; iter=$(($(cat /tmp/iter) + 1)); fi
|
||||
# if [ ! -f /tmp/iter ]; then iter=1; echo 1 > /tmp/iter;
|
||||
# else iter=$(($(cat /tmp/iter) + 1)); echo $iter > /tmp/iter; fi
|
||||
# find $src_file_list -type f | xargs ls -lR > /tmp/src-ls-$iter
|
||||
# find $obj_file_list -type f | xargs ls -lR > /tmp/obj-ls-$iter
|
||||
|
||||
@ -43,10 +42,18 @@ arch/$SRCARCH/include/
|
||||
pushd $kroot > /dev/null
|
||||
src_files_md5="$(find $src_file_list -type f |
|
||||
grep -v "include/generated/compile.h" |
|
||||
grep -v "include/generated/autoconf.h" |
|
||||
grep -v "include/config/auto.conf" |
|
||||
grep -v "include/config/auto.conf.cmd" |
|
||||
grep -v "include/config/tristate.conf" |
|
||||
xargs ls -lR | md5sum | cut -d ' ' -f1)"
|
||||
popd > /dev/null
|
||||
obj_files_md5="$(find $obj_file_list -type f |
|
||||
grep -v "include/generated/compile.h" |
|
||||
grep -v "include/generated/autoconf.h" |
|
||||
grep -v "include/config/auto.conf" |
|
||||
grep -v "include/config/auto.conf.cmd" |
|
||||
grep -v "include/config/tristate.conf" |
|
||||
xargs ls -lR | md5sum | cut -d ' ' -f1)"
|
||||
|
||||
if [ -f $tarfile ]; then tarfile_md5="$(md5sum $tarfile | cut -d ' ' -f1)"; fi
|
||||
@ -82,7 +89,7 @@ find $cpio_dir -type f -print0 |
|
||||
|
||||
tar -Jcf $tarfile -C $cpio_dir/ . > /dev/null
|
||||
|
||||
echo "$src_files_md5" > kernel/kheaders.md5
|
||||
echo "$src_files_md5" > kernel/kheaders.md5
|
||||
echo "$obj_files_md5" >> kernel/kheaders.md5
|
||||
echo "$(md5sum $tarfile | cut -d ' ' -f1)" >> kernel/kheaders.md5
|
||||
|
@ -8,9 +8,8 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
/*
|
||||
* Define kernel_headers_data and kernel_headers_data_end, within which the
|
||||
@ -31,39 +30,32 @@ extern char kernel_headers_data;
|
||||
extern char kernel_headers_data_end;
|
||||
|
||||
static ssize_t
|
||||
ikheaders_read_current(struct file *file, char __user *buf,
|
||||
size_t len, loff_t *offset)
|
||||
ikheaders_read(struct file *file, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
char *buf, loff_t off, size_t len)
|
||||
{
|
||||
return simple_read_from_buffer(buf, len, offset,
|
||||
&kernel_headers_data,
|
||||
&kernel_headers_data_end -
|
||||
&kernel_headers_data);
|
||||
memcpy(buf, &kernel_headers_data + off, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static const struct file_operations ikheaders_file_ops = {
|
||||
.read = ikheaders_read_current,
|
||||
.llseek = default_llseek,
|
||||
static struct bin_attribute kheaders_attr __ro_after_init = {
|
||||
.attr = {
|
||||
.name = "kheaders.tar.xz",
|
||||
.mode = 0444,
|
||||
},
|
||||
.read = &ikheaders_read,
|
||||
};
|
||||
|
||||
static int __init ikheaders_init(void)
|
||||
{
|
||||
struct proc_dir_entry *entry;
|
||||
|
||||
/* create the current headers file */
|
||||
entry = proc_create("kheaders.tar.xz", S_IRUGO, NULL,
|
||||
&ikheaders_file_ops);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
|
||||
proc_set_size(entry,
|
||||
&kernel_headers_data_end -
|
||||
&kernel_headers_data);
|
||||
return 0;
|
||||
kheaders_attr.size = (&kernel_headers_data_end -
|
||||
&kernel_headers_data);
|
||||
return sysfs_create_bin_file(kernel_kobj, &kheaders_attr);
|
||||
}
|
||||
|
||||
static void __exit ikheaders_cleanup(void)
|
||||
{
|
||||
remove_proc_entry("kheaders.tar.xz", NULL);
|
||||
sysfs_remove_bin_file(kernel_kobj, &kheaders_attr);
|
||||
}
|
||||
|
||||
module_init(ikheaders_init);
|
||||
|
@ -224,30 +224,30 @@ static ssize_t config_show(struct device *dev,
|
||||
|
||||
mutex_lock(&test_fw_mutex);
|
||||
|
||||
len += snprintf(buf, PAGE_SIZE,
|
||||
len += scnprintf(buf, PAGE_SIZE - len,
|
||||
"Custom trigger configuration for: %s\n",
|
||||
dev_name(dev));
|
||||
|
||||
if (test_fw_config->name)
|
||||
len += snprintf(buf+len, PAGE_SIZE,
|
||||
len += scnprintf(buf+len, PAGE_SIZE - len,
|
||||
"name:\t%s\n",
|
||||
test_fw_config->name);
|
||||
else
|
||||
len += snprintf(buf+len, PAGE_SIZE,
|
||||
len += scnprintf(buf+len, PAGE_SIZE - len,
|
||||
"name:\tEMTPY\n");
|
||||
|
||||
len += snprintf(buf+len, PAGE_SIZE,
|
||||
len += scnprintf(buf+len, PAGE_SIZE - len,
|
||||
"num_requests:\t%u\n", test_fw_config->num_requests);
|
||||
|
||||
len += snprintf(buf+len, PAGE_SIZE,
|
||||
len += scnprintf(buf+len, PAGE_SIZE - len,
|
||||
"send_uevent:\t\t%s\n",
|
||||
test_fw_config->send_uevent ?
|
||||
"FW_ACTION_HOTPLUG" :
|
||||
"FW_ACTION_NOHOTPLUG");
|
||||
len += snprintf(buf+len, PAGE_SIZE,
|
||||
len += scnprintf(buf+len, PAGE_SIZE - len,
|
||||
"sync_direct:\t\t%s\n",
|
||||
test_fw_config->sync_direct ? "true" : "false");
|
||||
len += snprintf(buf+len, PAGE_SIZE,
|
||||
len += scnprintf(buf+len, PAGE_SIZE - len,
|
||||
"read_fw_idx:\t%u\n", test_fw_config->read_fw_idx);
|
||||
|
||||
mutex_unlock(&test_fw_mutex);
|
||||
|
Loading…
Reference in New Issue
Block a user