|
17 | 17 | struct task_struct;
|
18 | 18 | struct user_regset;
|
19 | 19 |
|
| 20 | +struct membuf { |
| 21 | + void *p; |
| 22 | + size_t left; |
| 23 | +}; |
| 24 | + |
| 25 | +static inline int membuf_zero(struct membuf *s, size_t size) |
| 26 | +{ |
| 27 | + if (s->left) { |
| 28 | + if (size > s->left) |
| 29 | + size = s->left; |
| 30 | + memset(s->p, 0, size); |
| 31 | + s->p += size; |
| 32 | + s->left -= size; |
| 33 | + } |
| 34 | + return s->left; |
| 35 | +} |
| 36 | + |
| 37 | +static inline int membuf_write(struct membuf *s, const void *v, size_t size) |
| 38 | +{ |
| 39 | + if (s->left) { |
| 40 | + if (size > s->left) |
| 41 | + size = s->left; |
| 42 | + memcpy(s->p, v, size); |
| 43 | + s->p += size; |
| 44 | + s->left -= size; |
| 45 | + } |
| 46 | + return s->left; |
| 47 | +} |
| 48 | + |
| 49 | +/* current s->p must be aligned for v; v must be a scalar */ |
| 50 | +#define membuf_store(s, v) \ |
| 51 | +({ \ |
| 52 | + struct membuf *__s = (s); \ |
| 53 | + if (__s->left) { \ |
| 54 | + typeof(v) __v = (v); \ |
| 55 | + size_t __size = sizeof(__v); \ |
| 56 | + if (unlikely(__size > __s->left)) { \ |
| 57 | + __size = __s->left; \ |
| 58 | + memcpy(__s->p, &__v, __size); \ |
| 59 | + } else { \ |
| 60 | + *(typeof(__v + 0) *)__s->p = __v; \ |
| 61 | + } \ |
| 62 | + __s->p += __size; \ |
| 63 | + __s->left -= __size; \ |
| 64 | + } \ |
| 65 | + __s->left;}) |
20 | 66 |
|
21 | 67 | /**
|
22 | 68 | * user_regset_active_fn - type of @active function in &struct user_regset
|
@@ -57,6 +103,10 @@ typedef int user_regset_get_fn(struct task_struct *target,
|
57 | 103 | unsigned int pos, unsigned int count,
|
58 | 104 | void *kbuf, void __user *ubuf);
|
59 | 105 |
|
| 106 | +typedef int user_regset_get2_fn(struct task_struct *target, |
| 107 | + const struct user_regset *regset, |
| 108 | + struct membuf to); |
| 109 | + |
60 | 110 | /**
|
61 | 111 | * user_regset_set_fn - type of @set function in &struct user_regset
|
62 | 112 | * @target: thread being examined
|
@@ -186,6 +236,7 @@ typedef unsigned int user_regset_get_size_fn(struct task_struct *target,
|
186 | 236 | */
|
187 | 237 | struct user_regset {
|
188 | 238 | user_regset_get_fn *get;
|
| 239 | + user_regset_get2_fn *regset_get; |
189 | 240 | user_regset_set_fn *set;
|
190 | 241 | user_regset_active_fn *active;
|
191 | 242 | user_regset_writeback_fn *writeback;
|
|
0 commit comments