Commit 8aa75b72 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'misc-habanalabs-fixes-2019-05-24' of...

Merge tag 'misc-habanalabs-fixes-2019-05-24' of git://people.freedesktop.org/~gabbayo/linux into char-misc-linus

Oded writes:

This tag contains the following fixes:

- Halt debug engines when user process closes the FD. We can't allow the
  device to issue transactions for a user which doesn't exists anymore.

- Fix various security holes in debugfs API.

- Add a new opcode to the DEBUG IOCTL API. The opcode is designed
  for setting the device into and out of debug mode. Although not a fix
  per-se, because this is a new IOCTL which is upstreamed in kernel 5.2, I
  think this is justified at this point because we won't be able to change
  the API later.

- Fix a bug where the code used an uninitialized mutex

* tag 'misc-habanalabs-fixes-2019-05-24' of git://people.freedesktop.org/~gabbayo/linux:
  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
parents 498ddaa3 8d45f1de
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -26,6 +26,12 @@ static void hl_ctx_fini(struct hl_ctx *ctx)
		dma_fence_put(ctx->cs_pending[i]);
		dma_fence_put(ctx->cs_pending[i]);


	if (ctx->asid != HL_KERNEL_ASID_ID) {
	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_vm_ctx_fini(ctx);
		hl_asid_free(hdev, ctx->asid);
		hl_asid_free(hdev, ctx->asid);
	}
	}
+18 −42
Original line number Original line Diff line number Diff line
@@ -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_debugfs_entry *entry = s->private;
	struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
	struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
	struct hl_device *hdev = dev_entry->hdev;
	struct hl_device *hdev = dev_entry->hdev;
	char kbuf[MMU_KBUF_SIZE], asid_kbuf[MMU_ASID_BUF_SIZE],
	char kbuf[MMU_KBUF_SIZE];
		addr_kbuf[MMU_ADDR_BUF_SIZE];
	char *c;
	char *c;
	ssize_t rc;
	ssize_t rc;


	if (!hdev->mmu_enable)
	if (!hdev->mmu_enable)
		return count;
		return count;


	memset(kbuf, 0, sizeof(kbuf));
	if (count > sizeof(kbuf) - 1)
	memset(asid_kbuf, 0, sizeof(asid_kbuf));
		goto err;
	memset(addr_kbuf, 0, sizeof(addr_kbuf));

	if (copy_from_user(kbuf, buf, count))
	if (copy_from_user(kbuf, buf, count))
		goto err;
		goto err;

	kbuf[count] = 0;
	kbuf[MMU_KBUF_SIZE - 1] = 0;


	c = strchr(kbuf, ' ');
	c = strchr(kbuf, ' ');
	if (!c)
	if (!c)
		goto err;
		goto err;
	*c = '\0';


	memcpy(asid_kbuf, kbuf, c - kbuf);
	rc = kstrtouint(kbuf, 10, &dev_entry->mmu_asid);

	rc = kstrtouint(asid_kbuf, 10, &dev_entry->mmu_asid);
	if (rc)
	if (rc)
		goto err;
		goto err;


	c = strstr(kbuf, " 0x");
	if (strncmp(c+1, "0x", 2))
	if (!c)
		goto err;
		goto err;

	rc = kstrtoull(c+3, 16, &dev_entry->mmu_addr);
	c += 3;
	memcpy(addr_kbuf, c, (kbuf + count) - c);

	rc = kstrtoull(addr_kbuf, 16, &dev_entry->mmu_addr);
	if (rc)
	if (rc)
		goto err;
		goto err;


@@ -600,10 +590,8 @@ static ssize_t hl_data_read32(struct file *f, char __user *buf,
	}
	}


	sprintf(tmp_buf, "0x%08x\n", val);
	sprintf(tmp_buf, "0x%08x\n", val);
	rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
	return simple_read_from_buffer(buf, count, ppos, tmp_buf,
			strlen(tmp_buf) + 1);
			strlen(tmp_buf));

	return rc;
}
}


static ssize_t hl_data_write32(struct file *f, const char __user *buf,
static ssize_t hl_data_write32(struct file *f, const char __user *buf,
@@ -645,7 +633,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_dbg_device_entry *entry = file_inode(f)->i_private;
	struct hl_device *hdev = entry->hdev;
	struct hl_device *hdev = entry->hdev;
	char tmp_buf[200];
	char tmp_buf[200];
	ssize_t rc;
	int i;
	int i;


	if (*ppos)
	if (*ppos)
@@ -660,10 +647,8 @@ static ssize_t hl_get_power_state(struct file *f, char __user *buf,


	sprintf(tmp_buf,
	sprintf(tmp_buf,
		"current power state: %d\n1 - D0\n2 - D3hot\n3 - Unknown\n", i);
		"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,
	return simple_read_from_buffer(buf, count, ppos, tmp_buf,
			strlen(tmp_buf) + 1);
			strlen(tmp_buf));

	return rc;
}
}


static ssize_t hl_set_power_state(struct file *f, const char __user *buf,
static ssize_t hl_set_power_state(struct file *f, const char __user *buf,
@@ -716,8 +701,8 @@ static ssize_t hl_i2c_data_read(struct file *f, char __user *buf,
	}
	}


	sprintf(tmp_buf, "0x%02x\n", val);
	sprintf(tmp_buf, "0x%02x\n", val);
	rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
	rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
			strlen(tmp_buf) + 1);
			strlen(tmp_buf));


	return rc;
	return rc;
}
}
@@ -806,18 +791,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,
static ssize_t hl_device_read(struct file *f, char __user *buf,
					size_t count, loff_t *ppos)
					size_t count, loff_t *ppos)
{
{
	char tmp_buf[200];
	static const char *help =
	ssize_t rc;
		"Valid values: disable, enable, suspend, resume, cpu_timeout\n";

	return simple_read_from_buffer(buf, count, ppos, help, strlen(help));
	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 ssize_t hl_device_write(struct file *f, const char __user *buf,
static ssize_t hl_device_write(struct file *f, const char __user *buf,
@@ -825,7 +801,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_dbg_device_entry *entry = file_inode(f)->i_private;
	struct hl_device *hdev = entry->hdev;
	struct hl_device *hdev = entry->hdev;
	char data[30];
	char data[30] = {0};


	/* don't allow partial writes */
	/* don't allow partial writes */
	if (*ppos != 0)
	if (*ppos != 0)
+2 −0
Original line number Original line Diff line number Diff line
@@ -231,6 +231,7 @@ static int device_early_init(struct hl_device *hdev)


	mutex_init(&hdev->fd_open_cnt_lock);
	mutex_init(&hdev->fd_open_cnt_lock);
	mutex_init(&hdev->send_cpu_message_lock);
	mutex_init(&hdev->send_cpu_message_lock);
	mutex_init(&hdev->mmu_cache_lock);
	INIT_LIST_HEAD(&hdev->hw_queues_mirror_list);
	INIT_LIST_HEAD(&hdev->hw_queues_mirror_list);
	spin_lock_init(&hdev->hw_queues_mirror_lock);
	spin_lock_init(&hdev->hw_queues_mirror_lock);
	atomic_set(&hdev->in_reset, 0);
	atomic_set(&hdev->in_reset, 0);
@@ -260,6 +261,7 @@ early_fini:
 */
 */
static void device_early_fini(struct hl_device *hdev)
static void device_early_fini(struct hl_device *hdev)
{
{
	mutex_destroy(&hdev->mmu_cache_lock);
	mutex_destroy(&hdev->send_cpu_message_lock);
	mutex_destroy(&hdev->send_cpu_message_lock);


	hl_cb_mgr_fini(hdev, &hdev->kernel_cb_mgr);
	hl_cb_mgr_fini(hdev, &hdev->kernel_cb_mgr);
+2 −1
Original line number Original line Diff line number Diff line
@@ -4819,7 +4819,8 @@ static const struct hl_asic_funcs goya_funcs = {
	.set_dram_bar_base = goya_set_ddr_bar_base,
	.set_dram_bar_base = goya_set_ddr_bar_base,
	.init_iatu = goya_init_iatu,
	.init_iatu = goya_init_iatu,
	.rreg = hl_rreg,
	.rreg = hl_rreg,
	.wreg = hl_wreg
	.wreg = hl_wreg,
	.halt_coresight = goya_halt_coresight
};
};


/*
/*
+1 −0
Original line number Original line Diff line number Diff line
@@ -202,6 +202,7 @@ void goya_add_device_attr(struct hl_device *hdev,
			struct attribute_group *dev_attr_grp);
			struct attribute_group *dev_attr_grp);
int goya_armcp_info_get(struct hl_device *hdev);
int goya_armcp_info_get(struct hl_device *hdev);
int goya_debug_coresight(struct hl_device *hdev, void *data);
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);
void goya_mmu_prepare(struct hl_device *hdev, u32 asid);
int goya_mmu_clear_pgt_range(struct hl_device *hdev);
int goya_mmu_clear_pgt_range(struct hl_device *hdev);
Loading