@@ -387,6 +387,24 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user(
387
387
return ERR_PTR (err );
388
388
}
389
389
390
+ static int mmc_blk_ioctl_copy_to_user (struct mmc_ioc_cmd __user * ic_ptr ,
391
+ struct mmc_blk_ioc_data * idata )
392
+ {
393
+ struct mmc_ioc_cmd * ic = & idata -> ic ;
394
+
395
+ if (copy_to_user (& (ic_ptr -> response ), ic -> response ,
396
+ sizeof (ic -> response )))
397
+ return - EFAULT ;
398
+
399
+ if (!idata -> ic .write_flag ) {
400
+ if (copy_to_user ((void __user * )(unsigned long )ic -> data_ptr ,
401
+ idata -> buf , idata -> buf_bytes ))
402
+ return - EFAULT ;
403
+ }
404
+
405
+ return 0 ;
406
+ }
407
+
390
408
static int ioctl_rpmb_card_status_poll (struct mmc_card * card , u32 * status ,
391
409
u32 retries_max )
392
410
{
@@ -447,12 +465,9 @@ static int ioctl_do_sanitize(struct mmc_card *card)
447
465
return err ;
448
466
}
449
467
450
- static int mmc_blk_ioctl_cmd (struct block_device * bdev ,
451
- struct mmc_ioc_cmd __user * ic_ptr )
468
+ static int __mmc_blk_ioctl_cmd (struct mmc_card * card , struct mmc_blk_data * md ,
469
+ struct mmc_blk_ioc_data * idata )
452
470
{
453
- struct mmc_blk_ioc_data * idata ;
454
- struct mmc_blk_data * md ;
455
- struct mmc_card * card ;
456
471
struct mmc_command cmd = {0 };
457
472
struct mmc_data data = {0 };
458
473
struct mmc_request mrq = {NULL };
@@ -461,33 +476,12 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
461
476
int is_rpmb = false;
462
477
u32 status = 0 ;
463
478
464
- /*
465
- * The caller must have CAP_SYS_RAWIO, and must be calling this on the
466
- * whole block device, not on a partition. This prevents overspray
467
- * between sibling partitions.
468
- */
469
- if ((!capable (CAP_SYS_RAWIO )) || (bdev != bdev -> bd_contains ))
470
- return - EPERM ;
471
-
472
- idata = mmc_blk_ioctl_copy_from_user (ic_ptr );
473
- if (IS_ERR (idata ))
474
- return PTR_ERR (idata );
475
-
476
- md = mmc_blk_get (bdev -> bd_disk );
477
- if (!md ) {
478
- err = - EINVAL ;
479
- goto cmd_err ;
480
- }
479
+ if (!card || !md || !idata )
480
+ return - EINVAL ;
481
481
482
482
if (md -> area_type & MMC_BLK_DATA_AREA_RPMB )
483
483
is_rpmb = true;
484
484
485
- card = md -> queue .card ;
486
- if (IS_ERR (card )) {
487
- err = PTR_ERR (card );
488
- goto cmd_done ;
489
- }
490
-
491
485
cmd .opcode = idata -> ic .opcode ;
492
486
cmd .arg = idata -> ic .arg ;
493
487
cmd .flags = idata -> ic .flags ;
@@ -530,23 +524,21 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
530
524
531
525
mrq .cmd = & cmd ;
532
526
533
- mmc_get_card (card );
534
-
535
527
err = mmc_blk_part_switch (card , md );
536
528
if (err )
537
- goto cmd_rel_host ;
529
+ return err ;
538
530
539
531
if (idata -> ic .is_acmd ) {
540
532
err = mmc_app_cmd (card -> host , card );
541
533
if (err )
542
- goto cmd_rel_host ;
534
+ return err ;
543
535
}
544
536
545
537
if (is_rpmb ) {
546
538
err = mmc_set_blockcount (card , data .blocks ,
547
539
idata -> ic .write_flag & (1 << 31 ));
548
540
if (err )
549
- goto cmd_rel_host ;
541
+ return err ;
550
542
}
551
543
552
544
if ((MMC_EXTRACT_INDEX_FROM_ARG (cmd .arg ) == EXT_CSD_SANITIZE_START ) &&
@@ -557,22 +549,20 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
557
549
pr_err ("%s: ioctl_do_sanitize() failed. err = %d" ,
558
550
__func__ , err );
559
551
560
- goto cmd_rel_host ;
552
+ return err ;
561
553
}
562
554
563
555
mmc_wait_for_req (card -> host , & mrq );
564
556
565
557
if (cmd .error ) {
566
558
dev_err (mmc_dev (card -> host ), "%s: cmd error %d\n" ,
567
559
__func__ , cmd .error );
568
- err = cmd .error ;
569
- goto cmd_rel_host ;
560
+ return cmd .error ;
570
561
}
571
562
if (data .error ) {
572
563
dev_err (mmc_dev (card -> host ), "%s: data error %d\n" ,
573
564
__func__ , data .error );
574
- err = data .error ;
575
- goto cmd_rel_host ;
565
+ return data .error ;
576
566
}
577
567
578
568
/*
@@ -582,18 +572,7 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
582
572
if (idata -> ic .postsleep_min_us )
583
573
usleep_range (idata -> ic .postsleep_min_us , idata -> ic .postsleep_max_us );
584
574
585
- if (copy_to_user (& (ic_ptr -> response ), cmd .resp , sizeof (cmd .resp ))) {
586
- err = - EFAULT ;
587
- goto cmd_rel_host ;
588
- }
589
-
590
- if (!idata -> ic .write_flag ) {
591
- if (copy_to_user ((void __user * )(unsigned long ) idata -> ic .data_ptr ,
592
- idata -> buf , idata -> buf_bytes )) {
593
- err = - EFAULT ;
594
- goto cmd_rel_host ;
595
- }
596
- }
575
+ memcpy (& (idata -> ic .response ), cmd .resp , sizeof (cmd .resp ));
597
576
598
577
if (is_rpmb ) {
599
578
/*
@@ -607,9 +586,42 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
607
586
__func__ , status , err );
608
587
}
609
588
610
- cmd_rel_host :
589
+ return err ;
590
+ }
591
+
592
+ static int mmc_blk_ioctl_cmd (struct block_device * bdev ,
593
+ struct mmc_ioc_cmd __user * ic_ptr )
594
+ {
595
+ struct mmc_blk_ioc_data * idata ;
596
+ struct mmc_blk_data * md ;
597
+ struct mmc_card * card ;
598
+ int err ;
599
+
600
+ idata = mmc_blk_ioctl_copy_from_user (ic_ptr );
601
+ if (IS_ERR (idata ))
602
+ return PTR_ERR (idata );
603
+
604
+ md = mmc_blk_get (bdev -> bd_disk );
605
+ if (!md ) {
606
+ err = - EINVAL ;
607
+ goto cmd_err ;
608
+ }
609
+
610
+ card = md -> queue .card ;
611
+ if (IS_ERR (card )) {
612
+ err = PTR_ERR (card );
613
+ goto cmd_done ;
614
+ }
615
+
616
+ mmc_get_card (card );
617
+
618
+ err = __mmc_blk_ioctl_cmd (card , md , idata );
619
+
611
620
mmc_put_card (card );
612
621
622
+ if (!err )
623
+ err = mmc_blk_ioctl_copy_to_user (ic_ptr , idata );
624
+
613
625
cmd_done :
614
626
mmc_blk_put (md );
615
627
cmd_err :
@@ -618,13 +630,97 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
618
630
return err ;
619
631
}
620
632
633
+ static int mmc_blk_ioctl_multi_cmd (struct block_device * bdev ,
634
+ struct mmc_ioc_multi_cmd __user * user )
635
+ {
636
+ struct mmc_blk_ioc_data * * idata = NULL ;
637
+ struct mmc_ioc_cmd __user * cmds = user -> cmds ;
638
+ struct mmc_card * card ;
639
+ struct mmc_blk_data * md ;
640
+ int i , err = - EFAULT ;
641
+ __u64 num_of_cmds ;
642
+
643
+ if (copy_from_user (& num_of_cmds , & user -> num_of_cmds ,
644
+ sizeof (num_of_cmds )))
645
+ return - EFAULT ;
646
+
647
+ if (num_of_cmds > MMC_IOC_MAX_CMDS )
648
+ return - EINVAL ;
649
+
650
+ idata = kcalloc (num_of_cmds , sizeof (* idata ), GFP_KERNEL );
651
+ if (!idata )
652
+ return - ENOMEM ;
653
+
654
+ for (i = 0 ; i < num_of_cmds ; i ++ ) {
655
+ idata [i ] = mmc_blk_ioctl_copy_from_user (& cmds [i ]);
656
+ if (IS_ERR (idata [i ])) {
657
+ err = PTR_ERR (idata [i ]);
658
+ num_of_cmds = i ;
659
+ goto cmd_err ;
660
+ }
661
+ }
662
+
663
+ md = mmc_blk_get (bdev -> bd_disk );
664
+ if (!md )
665
+ goto cmd_err ;
666
+
667
+ card = md -> queue .card ;
668
+ if (IS_ERR (card )) {
669
+ err = PTR_ERR (card );
670
+ goto cmd_done ;
671
+ }
672
+
673
+ mmc_get_card (card );
674
+
675
+ for (i = 0 ; i < num_of_cmds ; i ++ ) {
676
+ err = __mmc_blk_ioctl_cmd (card , md , idata [i ]);
677
+ if (err ) {
678
+ mmc_put_card (card );
679
+ goto cmd_done ;
680
+ }
681
+ }
682
+
683
+ mmc_put_card (card );
684
+
685
+ /* copy to user if data and response */
686
+ for (i = 0 ; i < num_of_cmds ; i ++ ) {
687
+ err = mmc_blk_ioctl_copy_to_user (& cmds [i ], idata [i ]);
688
+ if (err )
689
+ break ;
690
+ }
691
+
692
+ cmd_done :
693
+ mmc_blk_put (md );
694
+ cmd_err :
695
+ for (i = 0 ; i < num_of_cmds ; i ++ ) {
696
+ kfree (idata [i ]-> buf );
697
+ kfree (idata [i ]);
698
+ }
699
+ kfree (idata );
700
+ return err ;
701
+ }
702
+
621
703
static int mmc_blk_ioctl (struct block_device * bdev , fmode_t mode ,
622
704
unsigned int cmd , unsigned long arg )
623
705
{
624
- int ret = - EINVAL ;
625
- if (cmd == MMC_IOC_CMD )
626
- ret = mmc_blk_ioctl_cmd (bdev , (struct mmc_ioc_cmd __user * )arg );
627
- return ret ;
706
+ /*
707
+ * The caller must have CAP_SYS_RAWIO, and must be calling this on the
708
+ * whole block device, not on a partition. This prevents overspray
709
+ * between sibling partitions.
710
+ */
711
+ if ((!capable (CAP_SYS_RAWIO )) || (bdev != bdev -> bd_contains ))
712
+ return - EPERM ;
713
+
714
+ switch (cmd ) {
715
+ case MMC_IOC_CMD :
716
+ return mmc_blk_ioctl_cmd (bdev ,
717
+ (struct mmc_ioc_cmd __user * )arg );
718
+ case MMC_IOC_MULTI_CMD :
719
+ return mmc_blk_ioctl_multi_cmd (bdev ,
720
+ (struct mmc_ioc_multi_cmd __user * )arg );
721
+ default :
722
+ return - EINVAL ;
723
+ }
628
724
}
629
725
630
726
#ifdef CONFIG_COMPAT
0 commit comments