Skip to content

Commit 0f6f874

Browse files
Marcelo Diop-Gonzalezgregkh
authored andcommitted
staging: vchiq: Have vchiq_dump_* functions return an error code
These functions currently modify the struct dump_context passed to them, and set context->actual to -EFAULT in case of error. The issue is that this is never returned to the user (except accidentally when things align so that that happens). So, have these functions return 0 on success and the appropriate error code otherwise, and return nonzero errors to the user. Reviewed-by: Dan Carpenter <[email protected]> Signed-off-by: Marcelo Diop-Gonzalez <[email protected]> Reviewed-by: Nicolas Saenz Julienne <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 0046b33 commit 0f6f874

File tree

4 files changed

+104
-52
lines changed

4 files changed

+104
-52
lines changed

drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,15 +247,14 @@ vchiq_complete_bulk(struct vchiq_bulk *bulk)
247247
bulk->actual);
248248
}
249249

250-
void
251-
vchiq_dump_platform_state(void *dump_context)
250+
int vchiq_dump_platform_state(void *dump_context)
252251
{
253252
char buf[80];
254253
int len;
255254

256255
len = snprintf(buf, sizeof(buf),
257256
" Platform: 2835 (VC master)");
258-
vchiq_dump(dump_context, buf, len + 1);
257+
return vchiq_dump(dump_context, buf, len + 1);
259258
}
260259

261260
enum vchiq_status

drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,14 +2072,13 @@ static int vchiq_release(struct inode *inode, struct file *file)
20722072
*
20732073
***************************************************************************/
20742074

2075-
void
2076-
vchiq_dump(void *dump_context, const char *str, int len)
2075+
int vchiq_dump(void *dump_context, const char *str, int len)
20772076
{
20782077
struct dump_context *context = (struct dump_context *)dump_context;
20792078
int copy_bytes;
20802079

20812080
if (context->actual >= context->space)
2082-
return;
2081+
return 0;
20832082

20842083
if (context->offset > 0) {
20852084
int skip_bytes = min_t(int, len, context->offset);
@@ -2088,14 +2087,14 @@ vchiq_dump(void *dump_context, const char *str, int len)
20882087
len -= skip_bytes;
20892088
context->offset -= skip_bytes;
20902089
if (context->offset > 0)
2091-
return;
2090+
return 0;
20922091
}
20932092
copy_bytes = min_t(int, len, context->space - context->actual);
20942093
if (copy_bytes == 0)
2095-
return;
2094+
return 0;
20962095
if (copy_to_user(context->buf + context->actual, str,
20972096
copy_bytes))
2098-
context->actual = -EFAULT;
2097+
return -EFAULT;
20992098
context->actual += copy_bytes;
21002099
len -= copy_bytes;
21012100

@@ -2109,8 +2108,9 @@ vchiq_dump(void *dump_context, const char *str, int len)
21092108

21102109
if (copy_to_user(context->buf + context->actual - 1,
21112110
&cr, 1))
2112-
context->actual = -EFAULT;
2111+
return -EFAULT;
21132112
}
2113+
return 0;
21142114
}
21152115

21162116
/****************************************************************************
@@ -2119,8 +2119,7 @@ vchiq_dump(void *dump_context, const char *str, int len)
21192119
*
21202120
***************************************************************************/
21212121

2122-
void
2123-
vchiq_dump_platform_instances(void *dump_context)
2122+
int vchiq_dump_platform_instances(void *dump_context)
21242123
{
21252124
struct vchiq_state *state = vchiq_get_state();
21262125
char buf[80];
@@ -2145,6 +2144,7 @@ vchiq_dump_platform_instances(void *dump_context)
21452144
for (i = 0; i < state->unused_service; i++) {
21462145
struct vchiq_service *service = state->services[i];
21472146
struct vchiq_instance *instance;
2147+
int err;
21482148

21492149
if (!service || service->base.callback != service_callback)
21502150
continue;
@@ -2162,9 +2162,12 @@ vchiq_dump_platform_instances(void *dump_context)
21622162
instance->completion_remove,
21632163
MAX_COMPLETIONS);
21642164

2165-
vchiq_dump(dump_context, buf, len + 1);
2165+
err = vchiq_dump(dump_context, buf, len + 1);
2166+
if (err)
2167+
return err;
21662168
instance->mark = 1;
21672169
}
2170+
return 0;
21682171
}
21692172

21702173
/****************************************************************************
@@ -2173,9 +2176,8 @@ vchiq_dump_platform_instances(void *dump_context)
21732176
*
21742177
***************************************************************************/
21752178

2176-
void
2177-
vchiq_dump_platform_service_state(void *dump_context,
2178-
struct vchiq_service *service)
2179+
int vchiq_dump_platform_service_state(void *dump_context,
2180+
struct vchiq_service *service)
21792181
{
21802182
struct user_service *user_service =
21812183
(struct user_service *)service->base.userdata;
@@ -2196,7 +2198,7 @@ vchiq_dump_platform_service_state(void *dump_context,
21962198
" (dequeue pending)");
21972199
}
21982200

2199-
vchiq_dump(dump_context, buf, len + 1);
2201+
return vchiq_dump(dump_context, buf, len + 1);
22002202
}
22012203

22022204
/****************************************************************************
@@ -2210,13 +2212,16 @@ vchiq_read(struct file *file, char __user *buf,
22102212
size_t count, loff_t *ppos)
22112213
{
22122214
struct dump_context context;
2215+
int err;
22132216

22142217
context.buf = buf;
22152218
context.actual = 0;
22162219
context.space = count;
22172220
context.offset = *ppos;
22182221

2219-
vchiq_dump_state(&context, &g_state);
2222+
err = vchiq_dump_state(&context, &g_state);
2223+
if (err)
2224+
return err;
22202225

22212226
*ppos += context.actual;
22222227

drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c

Lines changed: 76 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3298,7 +3298,7 @@ vchiq_set_service_option(unsigned int handle,
32983298
return status;
32993299
}
33003300

3301-
static void
3301+
static int
33023302
vchiq_dump_shared_state(void *dump_context, struct vchiq_state *state,
33033303
struct vchiq_shared_state *shared, const char *label)
33043304
{
@@ -3318,16 +3318,21 @@ vchiq_dump_shared_state(void *dump_context, struct vchiq_state *state,
33183318
int i;
33193319
char buf[80];
33203320
int len;
3321+
int err;
33213322

33223323
len = scnprintf(buf, sizeof(buf),
33233324
" %s: slots %d-%d tx_pos=%x recycle=%x",
33243325
label, shared->slot_first, shared->slot_last,
33253326
shared->tx_pos, shared->slot_queue_recycle);
3326-
vchiq_dump(dump_context, buf, len + 1);
3327+
err = vchiq_dump(dump_context, buf, len + 1);
3328+
if (err)
3329+
return err;
33273330

33283331
len = scnprintf(buf, sizeof(buf),
33293332
" Slots claimed:");
3330-
vchiq_dump(dump_context, buf, len + 1);
3333+
err = vchiq_dump(dump_context, buf, len + 1);
3334+
if (err)
3335+
return err;
33313336

33323337
for (i = shared->slot_first; i <= shared->slot_last; i++) {
33333338
struct vchiq_slot_info slot_info =
@@ -3336,48 +3341,61 @@ vchiq_dump_shared_state(void *dump_context, struct vchiq_state *state,
33363341
len = scnprintf(buf, sizeof(buf),
33373342
" %d: %d/%d", i, slot_info.use_count,
33383343
slot_info.release_count);
3339-
vchiq_dump(dump_context, buf, len + 1);
3344+
err = vchiq_dump(dump_context, buf, len + 1);
3345+
if (err)
3346+
return err;
33403347
}
33413348
}
33423349

33433350
for (i = 1; i < shared->debug[DEBUG_ENTRIES]; i++) {
33443351
len = scnprintf(buf, sizeof(buf), " DEBUG: %s = %d(%x)",
33453352
debug_names[i], shared->debug[i], shared->debug[i]);
3346-
vchiq_dump(dump_context, buf, len + 1);
3353+
err = vchiq_dump(dump_context, buf, len + 1);
3354+
if (err)
3355+
return err;
33473356
}
3357+
return 0;
33483358
}
33493359

3350-
void
3351-
vchiq_dump_state(void *dump_context, struct vchiq_state *state)
3360+
int vchiq_dump_state(void *dump_context, struct vchiq_state *state)
33523361
{
33533362
char buf[80];
33543363
int len;
33553364
int i;
3365+
int err;
33563366

33573367
len = scnprintf(buf, sizeof(buf), "State %d: %s", state->id,
33583368
conn_state_names[state->conn_state]);
3359-
vchiq_dump(dump_context, buf, len + 1);
3369+
err = vchiq_dump(dump_context, buf, len + 1);
3370+
if (err)
3371+
return err;
33603372

33613373
len = scnprintf(buf, sizeof(buf),
33623374
" tx_pos=%x(@%pK), rx_pos=%x(@%pK)",
33633375
state->local->tx_pos,
33643376
state->tx_data + (state->local_tx_pos & VCHIQ_SLOT_MASK),
33653377
state->rx_pos,
33663378
state->rx_data + (state->rx_pos & VCHIQ_SLOT_MASK));
3367-
vchiq_dump(dump_context, buf, len + 1);
3379+
err = vchiq_dump(dump_context, buf, len + 1);
3380+
if (err)
3381+
return err;
33683382

33693383
len = scnprintf(buf, sizeof(buf),
33703384
" Version: %d (min %d)",
33713385
VCHIQ_VERSION, VCHIQ_VERSION_MIN);
3372-
vchiq_dump(dump_context, buf, len + 1);
3386+
err = vchiq_dump(dump_context, buf, len + 1);
3387+
if (err)
3388+
return err;
33733389

33743390
if (VCHIQ_ENABLE_STATS) {
33753391
len = scnprintf(buf, sizeof(buf),
33763392
" Stats: ctrl_tx_count=%d, ctrl_rx_count=%d, "
33773393
"error_count=%d",
33783394
state->stats.ctrl_tx_count, state->stats.ctrl_rx_count,
33793395
state->stats.error_count);
3380-
vchiq_dump(dump_context, buf, len + 1);
3396+
err = vchiq_dump(dump_context, buf, len + 1);
3397+
if (err)
3398+
return err;
33813399
}
33823400

33833401
len = scnprintf(buf, sizeof(buf),
@@ -3388,30 +3406,49 @@ vchiq_dump_state(void *dump_context, struct vchiq_state *state)
33883406
state->data_quota - state->data_use_count,
33893407
state->local->slot_queue_recycle - state->slot_queue_available,
33903408
state->stats.slot_stalls, state->stats.data_stalls);
3391-
vchiq_dump(dump_context, buf, len + 1);
3392-
3393-
vchiq_dump_platform_state(dump_context);
3394-
3395-
vchiq_dump_shared_state(dump_context, state, state->local, "Local");
3396-
vchiq_dump_shared_state(dump_context, state, state->remote, "Remote");
3397-
3398-
vchiq_dump_platform_instances(dump_context);
3409+
err = vchiq_dump(dump_context, buf, len + 1);
3410+
if (err)
3411+
return err;
3412+
3413+
err = vchiq_dump_platform_state(dump_context);
3414+
if (err)
3415+
return err;
3416+
3417+
err = vchiq_dump_shared_state(dump_context,
3418+
state,
3419+
state->local,
3420+
"Local");
3421+
if (err)
3422+
return err;
3423+
err = vchiq_dump_shared_state(dump_context,
3424+
state,
3425+
state->remote,
3426+
"Remote");
3427+
if (err)
3428+
return err;
3429+
3430+
err = vchiq_dump_platform_instances(dump_context);
3431+
if (err)
3432+
return err;
33993433

34003434
for (i = 0; i < state->unused_service; i++) {
34013435
struct vchiq_service *service = find_service_by_port(state, i);
34023436

34033437
if (service) {
3404-
vchiq_dump_service_state(dump_context, service);
3438+
err = vchiq_dump_service_state(dump_context, service);
34053439
unlock_service(service);
3440+
if (err)
3441+
return err;
34063442
}
34073443
}
3444+
return 0;
34083445
}
34093446

3410-
void
3411-
vchiq_dump_service_state(void *dump_context, struct vchiq_service *service)
3447+
int vchiq_dump_service_state(void *dump_context, struct vchiq_service *service)
34123448
{
34133449
char buf[80];
34143450
int len;
3451+
int err;
34153452

34163453
len = scnprintf(buf, sizeof(buf), "Service %u: %s (ref %u)",
34173454
service->localport, srvstate_names[service->srvstate],
@@ -3444,7 +3481,9 @@ vchiq_dump_service_state(void *dump_context, struct vchiq_service *service)
34443481
service_quota->slot_use_count,
34453482
service_quota->slot_quota);
34463483

3447-
vchiq_dump(dump_context, buf, len + 1);
3484+
err = vchiq_dump(dump_context, buf, len + 1);
3485+
if (err)
3486+
return err;
34483487

34493488
tx_pending = service->bulk_tx.local_insert -
34503489
service->bulk_tx.remote_insert;
@@ -3463,7 +3502,9 @@ vchiq_dump_service_state(void *dump_context, struct vchiq_service *service)
34633502
BULK_INDEX(service->bulk_rx.remove)].size : 0);
34643503

34653504
if (VCHIQ_ENABLE_STATS) {
3466-
vchiq_dump(dump_context, buf, len + 1);
3505+
err = vchiq_dump(dump_context, buf, len + 1);
3506+
if (err)
3507+
return err;
34673508

34683509
len = scnprintf(buf, sizeof(buf),
34693510
" Ctrl: tx_count=%d, tx_bytes=%llu, "
@@ -3472,7 +3513,9 @@ vchiq_dump_service_state(void *dump_context, struct vchiq_service *service)
34723513
service->stats.ctrl_tx_bytes,
34733514
service->stats.ctrl_rx_count,
34743515
service->stats.ctrl_rx_bytes);
3475-
vchiq_dump(dump_context, buf, len + 1);
3516+
err = vchiq_dump(dump_context, buf, len + 1);
3517+
if (err)
3518+
return err;
34763519

34773520
len = scnprintf(buf, sizeof(buf),
34783521
" Bulk: tx_count=%d, tx_bytes=%llu, "
@@ -3481,7 +3524,9 @@ vchiq_dump_service_state(void *dump_context, struct vchiq_service *service)
34813524
service->stats.bulk_tx_bytes,
34823525
service->stats.bulk_rx_count,
34833526
service->stats.bulk_rx_bytes);
3484-
vchiq_dump(dump_context, buf, len + 1);
3527+
err = vchiq_dump(dump_context, buf, len + 1);
3528+
if (err)
3529+
return err;
34853530

34863531
len = scnprintf(buf, sizeof(buf),
34873532
" %d quota stalls, %d slot stalls, "
@@ -3494,10 +3539,13 @@ vchiq_dump_service_state(void *dump_context, struct vchiq_service *service)
34943539
}
34953540
}
34963541

3497-
vchiq_dump(dump_context, buf, len + 1);
3542+
err = vchiq_dump(dump_context, buf, len + 1);
3543+
if (err)
3544+
return err;
34983545

34993546
if (service->srvstate != VCHIQ_SRVSTATE_FREE)
3500-
vchiq_dump_platform_service_state(dump_context, service);
3547+
err = vchiq_dump_platform_service_state(dump_context, service);
3548+
return err;
35013549
}
35023550

35033551
void

drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -526,10 +526,10 @@ vchiq_bulk_transfer(unsigned int handle, void *offset, int size,
526526
void *userdata, enum vchiq_bulk_mode mode,
527527
enum vchiq_bulk_dir dir);
528528

529-
extern void
529+
extern int
530530
vchiq_dump_state(void *dump_context, struct vchiq_state *state);
531531

532-
extern void
532+
extern int
533533
vchiq_dump_service_state(void *dump_context, struct vchiq_service *service);
534534

535535
extern void
@@ -602,16 +602,16 @@ vchiq_platform_resume(struct vchiq_state *state);
602602
extern void
603603
vchiq_platform_resumed(struct vchiq_state *state);
604604

605-
extern void
605+
extern int
606606
vchiq_dump(void *dump_context, const char *str, int len);
607607

608-
extern void
608+
extern int
609609
vchiq_dump_platform_state(void *dump_context);
610610

611-
extern void
611+
extern int
612612
vchiq_dump_platform_instances(void *dump_context);
613613

614-
extern void
614+
extern int
615615
vchiq_dump_platform_service_state(void *dump_context,
616616
struct vchiq_service *service);
617617

0 commit comments

Comments
 (0)