aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c61
1 files changed, 57 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 75c933b1a432..52388b1b52c2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -23,13 +23,40 @@
23 */ 23 */
24 24
25#include <drm/drmP.h> 25#include <drm/drmP.h>
26#include <drm/drm_auth.h>
26#include "amdgpu.h" 27#include "amdgpu.h"
27 28
28static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx) 29static int amdgpu_ctx_priority_permit(struct drm_file *filp,
30 enum amd_sched_priority priority)
31{
32 /* NORMAL and below are accessible by everyone */
33 if (priority <= AMD_SCHED_PRIORITY_NORMAL)
34 return 0;
35
36 if (capable(CAP_SYS_NICE))
37 return 0;
38
39 if (drm_is_current_master(filp))
40 return 0;
41
42 return -EACCES;
43}
44
45static int amdgpu_ctx_init(struct amdgpu_device *adev,
46 enum amd_sched_priority priority,
47 struct drm_file *filp,
48 struct amdgpu_ctx *ctx)
29{ 49{
30 unsigned i, j; 50 unsigned i, j;
31 int r; 51 int r;
32 52
53 if (priority < 0 || priority >= AMD_SCHED_PRIORITY_MAX)
54 return -EINVAL;
55
56 r = amdgpu_ctx_priority_permit(filp, priority);
57 if (r)
58 return r;
59
33 memset(ctx, 0, sizeof(*ctx)); 60 memset(ctx, 0, sizeof(*ctx));
34 ctx->adev = adev; 61 ctx->adev = adev;
35 kref_init(&ctx->refcount); 62 kref_init(&ctx->refcount);
@@ -51,7 +78,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx)
51 struct amdgpu_ring *ring = adev->rings[i]; 78 struct amdgpu_ring *ring = adev->rings[i];
52 struct amd_sched_rq *rq; 79 struct amd_sched_rq *rq;
53 80
54 rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL]; 81 rq = &ring->sched.sched_rq[priority];
55 82
56 if (ring == &adev->gfx.kiq.ring) 83 if (ring == &adev->gfx.kiq.ring)
57 continue; 84 continue;
@@ -100,6 +127,8 @@ static void amdgpu_ctx_fini(struct amdgpu_ctx *ctx)
100 127
101static int amdgpu_ctx_alloc(struct amdgpu_device *adev, 128static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
102 struct amdgpu_fpriv *fpriv, 129 struct amdgpu_fpriv *fpriv,
130 struct drm_file *filp,
131 enum amd_sched_priority priority,
103 uint32_t *id) 132 uint32_t *id)
104{ 133{
105 struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; 134 struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
@@ -117,8 +146,9 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
117 kfree(ctx); 146 kfree(ctx);
118 return r; 147 return r;
119 } 148 }
149
120 *id = (uint32_t)r; 150 *id = (uint32_t)r;
121 r = amdgpu_ctx_init(adev, ctx); 151 r = amdgpu_ctx_init(adev, priority, filp, ctx);
122 if (r) { 152 if (r) {
123 idr_remove(&mgr->ctx_handles, *id); 153 idr_remove(&mgr->ctx_handles, *id);
124 *id = 0; 154 *id = 0;
@@ -188,11 +218,30 @@ static int amdgpu_ctx_query(struct amdgpu_device *adev,
188 return 0; 218 return 0;
189} 219}
190 220
221static enum amd_sched_priority amdgpu_to_sched_priority(int amdgpu_priority)
222{
223 switch (amdgpu_priority) {
224 case AMDGPU_CTX_PRIORITY_HIGH_HW:
225 return AMD_SCHED_PRIORITY_HIGH_HW;
226 case AMDGPU_CTX_PRIORITY_HIGH_SW:
227 return AMD_SCHED_PRIORITY_HIGH_SW;
228 case AMDGPU_CTX_PRIORITY_NORMAL:
229 return AMD_SCHED_PRIORITY_NORMAL;
230 case AMDGPU_CTX_PRIORITY_LOW_SW:
231 case AMDGPU_CTX_PRIORITY_LOW_HW:
232 return AMD_SCHED_PRIORITY_LOW;
233 default:
234 WARN(1, "Invalid context priority %d\n", amdgpu_priority);
235 return AMD_SCHED_PRIORITY_NORMAL;
236 }
237}
238
191int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, 239int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
192 struct drm_file *filp) 240 struct drm_file *filp)
193{ 241{
194 int r; 242 int r;
195 uint32_t id; 243 uint32_t id;
244 enum amd_sched_priority priority;
196 245
197 union drm_amdgpu_ctx *args = data; 246 union drm_amdgpu_ctx *args = data;
198 struct amdgpu_device *adev = dev->dev_private; 247 struct amdgpu_device *adev = dev->dev_private;
@@ -200,10 +249,14 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
200 249
201 r = 0; 250 r = 0;
202 id = args->in.ctx_id; 251 id = args->in.ctx_id;
252 priority = amdgpu_to_sched_priority(args->in.priority);
253
254 if (priority >= AMD_SCHED_PRIORITY_MAX)
255 return -EINVAL;
203 256
204 switch (args->in.op) { 257 switch (args->in.op) {
205 case AMDGPU_CTX_OP_ALLOC_CTX: 258 case AMDGPU_CTX_OP_ALLOC_CTX:
206 r = amdgpu_ctx_alloc(adev, fpriv, &id); 259 r = amdgpu_ctx_alloc(adev, fpriv, filp, priority, &id);
207 args->out.alloc.ctx_id = id; 260 args->out.alloc.ctx_id = id;
208 break; 261 break;
209 case AMDGPU_CTX_OP_FREE_CTX: 262 case AMDGPU_CTX_OP_FREE_CTX: