diff options
author | Dave Airlie <airlied@redhat.com> | 2017-11-30 18:14:46 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-11-30 18:14:46 -0500 |
commit | 662e70400721f7bcf3b689acfe418f745f76096b (patch) | |
tree | 9991783a1ef0af97480d9036186afa0cb15912db | |
parent | a42ea78f5b73d8aba9665ad34fb88e483f442f6f (diff) | |
parent | b4d085201d86af69cbda2214c6dafc0be240ef9f (diff) |
Merge tag 'drm-amdkfd-fixes-2017-11-26' of git://people.freedesktop.org/~gabbayo/linux into drm-fixes
This is amdkfd pull request for -rc2. It contains three small fixes to the
CIK SDMA code, compilation error fix in kfd_ioctl.h and fix to accessing
a pointer after it was released.
* tag 'drm-amdkfd-fixes-2017-11-26' of git://people.freedesktop.org/~gabbayo/linux:
uapi: fix linux/kfd_ioctl.h userspace compilation errors
drm/amdkfd: fix amdkfd use-after-free GP fault
drm/amdkfd: Fix SDMA oversubsription handling
drm/amdkfd: Fix SDMA ring buffer size calculation
drm/amdgpu: Fix SDMA load/unload sequence on HWS disabled mode
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_module.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 18 | ||||
-rw-r--r-- | include/uapi/linux/kfd_ioctl.h | 22 |
5 files changed, 67 insertions, 27 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c index 47d1c132ac40..1e3e9be7d77e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | |||
@@ -379,29 +379,50 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd) | |||
379 | { | 379 | { |
380 | struct amdgpu_device *adev = get_amdgpu_device(kgd); | 380 | struct amdgpu_device *adev = get_amdgpu_device(kgd); |
381 | struct cik_sdma_rlc_registers *m; | 381 | struct cik_sdma_rlc_registers *m; |
382 | unsigned long end_jiffies; | ||
382 | uint32_t sdma_base_addr; | 383 | uint32_t sdma_base_addr; |
384 | uint32_t data; | ||
383 | 385 | ||
384 | m = get_sdma_mqd(mqd); | 386 | m = get_sdma_mqd(mqd); |
385 | sdma_base_addr = get_sdma_base_addr(m); | 387 | sdma_base_addr = get_sdma_base_addr(m); |
386 | 388 | ||
387 | WREG32(sdma_base_addr + mmSDMA0_RLC0_VIRTUAL_ADDR, | 389 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, |
388 | m->sdma_rlc_virtual_addr); | 390 | m->sdma_rlc_rb_cntl & (~SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK)); |
389 | 391 | ||
390 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, | 392 | end_jiffies = msecs_to_jiffies(2000) + jiffies; |
391 | m->sdma_rlc_rb_base); | 393 | while (true) { |
394 | data = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS); | ||
395 | if (data & SDMA0_RLC0_CONTEXT_STATUS__IDLE_MASK) | ||
396 | break; | ||
397 | if (time_after(jiffies, end_jiffies)) | ||
398 | return -ETIME; | ||
399 | usleep_range(500, 1000); | ||
400 | } | ||
401 | if (m->sdma_engine_id) { | ||
402 | data = RREG32(mmSDMA1_GFX_CONTEXT_CNTL); | ||
403 | data = REG_SET_FIELD(data, SDMA1_GFX_CONTEXT_CNTL, | ||
404 | RESUME_CTX, 0); | ||
405 | WREG32(mmSDMA1_GFX_CONTEXT_CNTL, data); | ||
406 | } else { | ||
407 | data = RREG32(mmSDMA0_GFX_CONTEXT_CNTL); | ||
408 | data = REG_SET_FIELD(data, SDMA0_GFX_CONTEXT_CNTL, | ||
409 | RESUME_CTX, 0); | ||
410 | WREG32(mmSDMA0_GFX_CONTEXT_CNTL, data); | ||
411 | } | ||
392 | 412 | ||
413 | WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, | ||
414 | m->sdma_rlc_doorbell); | ||
415 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, 0); | ||
416 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0); | ||
417 | WREG32(sdma_base_addr + mmSDMA0_RLC0_VIRTUAL_ADDR, | ||
418 | m->sdma_rlc_virtual_addr); | ||
419 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, m->sdma_rlc_rb_base); | ||
393 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE_HI, | 420 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE_HI, |
394 | m->sdma_rlc_rb_base_hi); | 421 | m->sdma_rlc_rb_base_hi); |
395 | |||
396 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_LO, | 422 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_LO, |
397 | m->sdma_rlc_rb_rptr_addr_lo); | 423 | m->sdma_rlc_rb_rptr_addr_lo); |
398 | |||
399 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_HI, | 424 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_HI, |
400 | m->sdma_rlc_rb_rptr_addr_hi); | 425 | m->sdma_rlc_rb_rptr_addr_hi); |
401 | |||
402 | WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, | ||
403 | m->sdma_rlc_doorbell); | ||
404 | |||
405 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, | 426 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, |
406 | m->sdma_rlc_rb_cntl); | 427 | m->sdma_rlc_rb_cntl); |
407 | 428 | ||
@@ -574,9 +595,9 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, | |||
574 | } | 595 | } |
575 | 596 | ||
576 | WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, 0); | 597 | WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, 0); |
577 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, 0); | 598 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, |
578 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0); | 599 | RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL) | |
579 | WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, 0); | 600 | SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK); |
580 | 601 | ||
581 | return 0; | 602 | return 0; |
582 | } | 603 | } |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c index 6c5a9cab55de..f744caeaee04 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
25 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
26 | #include <linux/device.h> | 26 | #include <linux/device.h> |
27 | #include <linux/printk.h> | ||
27 | #include "kfd_priv.h" | 28 | #include "kfd_priv.h" |
28 | 29 | ||
29 | #define KFD_DRIVER_AUTHOR "AMD Inc. and others" | 30 | #define KFD_DRIVER_AUTHOR "AMD Inc. and others" |
@@ -132,7 +133,7 @@ static void __exit kfd_module_exit(void) | |||
132 | kfd_process_destroy_wq(); | 133 | kfd_process_destroy_wq(); |
133 | kfd_topology_shutdown(); | 134 | kfd_topology_shutdown(); |
134 | kfd_chardev_exit(); | 135 | kfd_chardev_exit(); |
135 | dev_info(kfd_device, "Removed module\n"); | 136 | pr_info("amdkfd: Removed module\n"); |
136 | } | 137 | } |
137 | 138 | ||
138 | module_init(kfd_module_init); | 139 | module_init(kfd_module_init); |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c index 4859d263fa2a..4728fad3fd74 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c | |||
@@ -202,8 +202,8 @@ static int update_mqd_sdma(struct mqd_manager *mm, void *mqd, | |||
202 | struct cik_sdma_rlc_registers *m; | 202 | struct cik_sdma_rlc_registers *m; |
203 | 203 | ||
204 | m = get_sdma_mqd(mqd); | 204 | m = get_sdma_mqd(mqd); |
205 | m->sdma_rlc_rb_cntl = ffs(q->queue_size / sizeof(unsigned int)) << | 205 | m->sdma_rlc_rb_cntl = (ffs(q->queue_size / sizeof(unsigned int)) - 1) |
206 | SDMA0_RLC0_RB_CNTL__RB_SIZE__SHIFT | | 206 | << SDMA0_RLC0_RB_CNTL__RB_SIZE__SHIFT | |
207 | q->vmid << SDMA0_RLC0_RB_CNTL__RB_VMID__SHIFT | | 207 | q->vmid << SDMA0_RLC0_RB_CNTL__RB_VMID__SHIFT | |
208 | 1 << SDMA0_RLC0_RB_CNTL__RPTR_WRITEBACK_ENABLE__SHIFT | | 208 | 1 << SDMA0_RLC0_RB_CNTL__RPTR_WRITEBACK_ENABLE__SHIFT | |
209 | 6 << SDMA0_RLC0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT; | 209 | 6 << SDMA0_RLC0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT; |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index 2bec902fc939..a3f1e62c60ba 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | |||
@@ -191,6 +191,24 @@ int pqm_create_queue(struct process_queue_manager *pqm, | |||
191 | 191 | ||
192 | switch (type) { | 192 | switch (type) { |
193 | case KFD_QUEUE_TYPE_SDMA: | 193 | case KFD_QUEUE_TYPE_SDMA: |
194 | if (dev->dqm->queue_count >= | ||
195 | CIK_SDMA_QUEUES_PER_ENGINE * CIK_SDMA_ENGINE_NUM) { | ||
196 | pr_err("Over-subscription is not allowed for SDMA.\n"); | ||
197 | retval = -EPERM; | ||
198 | goto err_create_queue; | ||
199 | } | ||
200 | |||
201 | retval = create_cp_queue(pqm, dev, &q, properties, f, *qid); | ||
202 | if (retval != 0) | ||
203 | goto err_create_queue; | ||
204 | pqn->q = q; | ||
205 | pqn->kq = NULL; | ||
206 | retval = dev->dqm->ops.create_queue(dev->dqm, q, &pdd->qpd, | ||
207 | &q->properties.vmid); | ||
208 | pr_debug("DQM returned %d for create_queue\n", retval); | ||
209 | print_queue(q); | ||
210 | break; | ||
211 | |||
194 | case KFD_QUEUE_TYPE_COMPUTE: | 212 | case KFD_QUEUE_TYPE_COMPUTE: |
195 | /* check if there is over subscription */ | 213 | /* check if there is over subscription */ |
196 | if ((sched_policy == KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) && | 214 | if ((sched_policy == KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) && |
diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h index 731d0df722e3..6e80501368ae 100644 --- a/include/uapi/linux/kfd_ioctl.h +++ b/include/uapi/linux/kfd_ioctl.h | |||
@@ -233,29 +233,29 @@ struct kfd_ioctl_wait_events_args { | |||
233 | }; | 233 | }; |
234 | 234 | ||
235 | struct kfd_ioctl_set_scratch_backing_va_args { | 235 | struct kfd_ioctl_set_scratch_backing_va_args { |
236 | uint64_t va_addr; /* to KFD */ | 236 | __u64 va_addr; /* to KFD */ |
237 | uint32_t gpu_id; /* to KFD */ | 237 | __u32 gpu_id; /* to KFD */ |
238 | uint32_t pad; | 238 | __u32 pad; |
239 | }; | 239 | }; |
240 | 240 | ||
241 | struct kfd_ioctl_get_tile_config_args { | 241 | struct kfd_ioctl_get_tile_config_args { |
242 | /* to KFD: pointer to tile array */ | 242 | /* to KFD: pointer to tile array */ |
243 | uint64_t tile_config_ptr; | 243 | __u64 tile_config_ptr; |
244 | /* to KFD: pointer to macro tile array */ | 244 | /* to KFD: pointer to macro tile array */ |
245 | uint64_t macro_tile_config_ptr; | 245 | __u64 macro_tile_config_ptr; |
246 | /* to KFD: array size allocated by user mode | 246 | /* to KFD: array size allocated by user mode |
247 | * from KFD: array size filled by kernel | 247 | * from KFD: array size filled by kernel |
248 | */ | 248 | */ |
249 | uint32_t num_tile_configs; | 249 | __u32 num_tile_configs; |
250 | /* to KFD: array size allocated by user mode | 250 | /* to KFD: array size allocated by user mode |
251 | * from KFD: array size filled by kernel | 251 | * from KFD: array size filled by kernel |
252 | */ | 252 | */ |
253 | uint32_t num_macro_tile_configs; | 253 | __u32 num_macro_tile_configs; |
254 | 254 | ||
255 | uint32_t gpu_id; /* to KFD */ | 255 | __u32 gpu_id; /* to KFD */ |
256 | uint32_t gb_addr_config; /* from KFD */ | 256 | __u32 gb_addr_config; /* from KFD */ |
257 | uint32_t num_banks; /* from KFD */ | 257 | __u32 num_banks; /* from KFD */ |
258 | uint32_t num_ranks; /* from KFD */ | 258 | __u32 num_ranks; /* from KFD */ |
259 | /* struct size can be extended later if needed | 259 | /* struct size can be extended later if needed |
260 | * without breaking ABI compatibility | 260 | * without breaking ABI compatibility |
261 | */ | 261 | */ |