-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drm/i915: Introduce the i915_user_extension_method
An idea for extending uABI inspired by Vulkan's extension chains. Instead of expanding the data struct for each ioctl every time we need to add a new feature, define an extension chain instead. As we add optional interfaces to control the ioctl, we define a new extension struct that can be linked into the ioctl data only when required by the user. The key advantage being able to ignore large control structs for optional interfaces/extensions, while being able to process them in a consistent manner. In comparison to other extensible ioctls, the key difference is the use of a linked chain of extension structs vs an array of tagged pointers. For example, struct drm_amdgpu_cs_chunk { __u32 chunk_id; __u32 length_dw; __u64 chunk_data; }; struct drm_amdgpu_cs_in { __u32 ctx_id; __u32 bo_list_handle; __u32 num_chunks; __u32 _pad; __u64 chunks; }; allows userspace to pass in array of pointers to extension structs, but must therefore keep constructing that array along side the command stream. In dynamic situations like that, a linked list is preferred and does not similar from extra cache line misses as the extension structs themselves must still be loaded separate to the chunks array. v2: Apply the tail call optimisation directly to nip the worry of stack overflow in the bud. v3: Defend against recursion. v4: Fixup local types to match new uabi Opens: - do we include the result as an out-field in each chain? struct i915_user_extension { __u64 next_extension; __u64 name; __s32 result; __u32 mbz; /* reserved for future use */ }; * Undecided, so provision some room for future expansion. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190322092325.5883-1-chris@chris-wilson.co.uk
- Loading branch information
Chris Wilson
committed
Mar 22, 2019
1 parent
b9d52d3
commit 9d1305e
Showing
5 changed files
with
135 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* SPDX-License-Identifier: MIT | ||
* | ||
* Copyright © 2018 Intel Corporation | ||
*/ | ||
|
||
#include <linux/nospec.h> | ||
#include <linux/sched/signal.h> | ||
#include <linux/uaccess.h> | ||
|
||
#include <uapi/drm/i915_drm.h> | ||
|
||
#include "i915_user_extensions.h" | ||
#include "i915_utils.h" | ||
|
||
int i915_user_extensions(struct i915_user_extension __user *ext, | ||
const i915_user_extension_fn *tbl, | ||
unsigned int count, | ||
void *data) | ||
{ | ||
unsigned int stackdepth = 512; | ||
|
||
while (ext) { | ||
int i, err; | ||
u32 name; | ||
u64 next; | ||
|
||
if (!stackdepth--) /* recursion vs useful flexibility */ | ||
return -E2BIG; | ||
|
||
err = check_user_mbz(&ext->flags); | ||
if (err) | ||
return err; | ||
|
||
for (i = 0; i < ARRAY_SIZE(ext->rsvd); i++) { | ||
err = check_user_mbz(&ext->rsvd[i]); | ||
if (err) | ||
return err; | ||
} | ||
|
||
if (get_user(name, &ext->name)) | ||
return -EFAULT; | ||
|
||
err = -EINVAL; | ||
if (name < count) { | ||
name = array_index_nospec(name, count); | ||
if (tbl[name]) | ||
err = tbl[name](ext, data); | ||
} | ||
if (err) | ||
return err; | ||
|
||
if (get_user(next, &ext->next_extension) || | ||
overflows_type(next, ext)) | ||
return -EFAULT; | ||
|
||
ext = u64_to_user_ptr(next); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* SPDX-License-Identifier: MIT | ||
* | ||
* Copyright © 2018 Intel Corporation | ||
*/ | ||
|
||
#ifndef I915_USER_EXTENSIONS_H | ||
#define I915_USER_EXTENSIONS_H | ||
|
||
struct i915_user_extension; | ||
|
||
typedef int (*i915_user_extension_fn)(struct i915_user_extension __user *ext, | ||
void *data); | ||
|
||
int i915_user_extensions(struct i915_user_extension __user *ext, | ||
const i915_user_extension_fn *tbl, | ||
unsigned int count, | ||
void *data); | ||
|
||
#endif /* I915_USER_EXTENSIONS_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters