Skip to content

Commit 43120a6

Browse files
committed
Merge branch 'for-7.0/io_uring' into for-next
* for-7.0/io_uring: io_uring: track restrictions separately for IORING_OP and IORING_REGISTER io_uring: move ctx->restricted check into io_check_restriction() io_uring/register: set ctx->restricted when restrictions are parsed io_uring/register: have io_parse_restrictions() set restrictions enabled io_uring/register: have io_parse_restrictions() return number of ops
2 parents 10abb17 + d6406c4 commit 43120a6

File tree

3 files changed

+33
-16
lines changed

3 files changed

+33
-16
lines changed

include/linux/io_uring_types.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,10 @@ struct io_restriction {
224224
DECLARE_BITMAP(sqe_op, IORING_OP_LAST);
225225
u8 sqe_flags_allowed;
226226
u8 sqe_flags_required;
227-
bool registered;
227+
/* IORING_OP_* restrictions exist */
228+
bool op_registered;
229+
/* IORING_REGISTER_* restrictions exist */
230+
bool reg_registered;
228231
};
229232

230233
struct io_submit_link {
@@ -259,7 +262,8 @@ struct io_ring_ctx {
259262
struct {
260263
unsigned int flags;
261264
unsigned int drain_next: 1;
262-
unsigned int restricted: 1;
265+
unsigned int op_restricted: 1;
266+
unsigned int reg_restricted: 1;
263267
unsigned int off_timeout_used: 1;
264268
unsigned int drain_active: 1;
265269
unsigned int has_evfd: 1;

io_uring/io_uring.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,6 +2057,8 @@ static inline bool io_check_restriction(struct io_ring_ctx *ctx,
20572057
struct io_kiocb *req,
20582058
unsigned int sqe_flags)
20592059
{
2060+
if (!ctx->op_restricted)
2061+
return true;
20602062
if (!test_bit(req->opcode, ctx->restrictions.sqe_op))
20612063
return false;
20622064

@@ -2158,8 +2160,8 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
21582160
io_init_drain(ctx);
21592161
}
21602162
}
2161-
if (unlikely(ctx->restricted || ctx->drain_active || ctx->drain_next)) {
2162-
if (ctx->restricted && !io_check_restriction(ctx, req, sqe_flags))
2163+
if (unlikely(ctx->op_restricted || ctx->drain_active || ctx->drain_next)) {
2164+
if (!io_check_restriction(ctx, req, sqe_flags))
21632165
return io_init_fail_req(req, -EACCES);
21642166
/* knock it to the slow queue path, will be drained there */
21652167
if (ctx->drain_active)

io_uring/register.c

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ static int io_register_personality(struct io_ring_ctx *ctx)
103103
return id;
104104
}
105105

106+
/*
107+
* Returns number of restrictions parsed and added on success, or < 0 for
108+
* an error.
109+
*/
106110
static __cold int io_parse_restrictions(void __user *arg, unsigned int nr_args,
107111
struct io_restriction *restrictions)
108112
{
@@ -129,25 +133,31 @@ static __cold int io_parse_restrictions(void __user *arg, unsigned int nr_args,
129133
if (res[i].register_op >= IORING_REGISTER_LAST)
130134
goto err;
131135
__set_bit(res[i].register_op, restrictions->register_op);
136+
restrictions->reg_registered = true;
132137
break;
133138
case IORING_RESTRICTION_SQE_OP:
134139
if (res[i].sqe_op >= IORING_OP_LAST)
135140
goto err;
136141
__set_bit(res[i].sqe_op, restrictions->sqe_op);
142+
restrictions->op_registered = true;
137143
break;
138144
case IORING_RESTRICTION_SQE_FLAGS_ALLOWED:
139145
restrictions->sqe_flags_allowed = res[i].sqe_flags;
146+
restrictions->op_registered = true;
140147
break;
141148
case IORING_RESTRICTION_SQE_FLAGS_REQUIRED:
142149
restrictions->sqe_flags_required = res[i].sqe_flags;
150+
restrictions->op_registered = true;
143151
break;
144152
default:
145153
goto err;
146154
}
147155
}
148-
149-
ret = 0;
150-
156+
ret = nr_args;
157+
if (!nr_args) {
158+
restrictions->op_registered = true;
159+
restrictions->reg_registered = true;
160+
}
151161
err:
152162
kfree(res);
153163
return ret;
@@ -163,16 +173,20 @@ static __cold int io_register_restrictions(struct io_ring_ctx *ctx,
163173
return -EBADFD;
164174

165175
/* We allow only a single restrictions registration */
166-
if (ctx->restrictions.registered)
176+
if (ctx->restrictions.op_registered || ctx->restrictions.reg_registered)
167177
return -EBUSY;
168178

169179
ret = io_parse_restrictions(arg, nr_args, &ctx->restrictions);
170180
/* Reset all restrictions if an error happened */
171-
if (ret != 0)
181+
if (ret < 0) {
172182
memset(&ctx->restrictions, 0, sizeof(ctx->restrictions));
173-
else
174-
ctx->restrictions.registered = true;
175-
return ret;
183+
return ret;
184+
}
185+
if (ctx->restrictions.op_registered)
186+
ctx->op_restricted = 1;
187+
if (ctx->restrictions.reg_registered)
188+
ctx->reg_restricted = 1;
189+
return 0;
176190
}
177191

178192
static int io_register_enable_rings(struct io_ring_ctx *ctx)
@@ -190,9 +204,6 @@ static int io_register_enable_rings(struct io_ring_ctx *ctx)
190204
io_activate_pollwq(ctx);
191205
}
192206

193-
if (ctx->restrictions.registered)
194-
ctx->restricted = 1;
195-
196207
/* Keep submitter_task store before clearing IORING_SETUP_R_DISABLED */
197208
smp_store_release(&ctx->flags, ctx->flags & ~IORING_SETUP_R_DISABLED);
198209
if (ctx->sq_data && wq_has_sleeper(&ctx->sq_data->wait))
@@ -626,7 +637,7 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
626637
if (ctx->submitter_task && ctx->submitter_task != current)
627638
return -EEXIST;
628639

629-
if (ctx->restricted) {
640+
if (ctx->reg_restricted && !(ctx->flags & IORING_SETUP_R_DISABLED)) {
630641
opcode = array_index_nospec(opcode, IORING_REGISTER_LAST);
631642
if (!test_bit(opcode, ctx->restrictions.register_op))
632643
return -EACCES;

0 commit comments

Comments
 (0)