@@ -512,18 +512,18 @@ int vgic_v3_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr,
512
512
*
513
513
* @dev: kvm device handle
514
514
* @attr: kvm device attribute
515
- * @reg: address the value is read or written, NULL for sysregs
516
515
* @is_write: true if userspace is writing a register
517
516
*/
518
517
static int vgic_v3_attr_regs_access (struct kvm_device * dev ,
519
518
struct kvm_device_attr * attr ,
520
- u64 * reg , bool is_write )
519
+ bool is_write )
521
520
{
522
521
struct vgic_reg_attr reg_attr ;
523
522
gpa_t addr ;
524
523
struct kvm_vcpu * vcpu ;
524
+ bool uaccess ;
525
+ u32 val ;
525
526
int ret ;
526
- u32 tmp32 ;
527
527
528
528
ret = vgic_v3_parse_attr (dev , attr , & reg_attr );
529
529
if (ret )
@@ -532,6 +532,21 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
532
532
vcpu = reg_attr .vcpu ;
533
533
addr = reg_attr .addr ;
534
534
535
+ switch (attr -> group ) {
536
+ case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS :
537
+ /* Sysregs uaccess is performed by the sysreg handling code */
538
+ uaccess = false;
539
+ break ;
540
+ default :
541
+ uaccess = true;
542
+ }
543
+
544
+ if (uaccess && is_write ) {
545
+ u32 __user * uaddr = (u32 __user * )(unsigned long )attr -> addr ;
546
+ if (get_user (val , uaddr ))
547
+ return - EFAULT ;
548
+ }
549
+
535
550
mutex_lock (& dev -> kvm -> lock );
536
551
537
552
if (unlikely (!vgic_initialized (dev -> kvm ))) {
@@ -546,20 +561,10 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
546
561
547
562
switch (attr -> group ) {
548
563
case KVM_DEV_ARM_VGIC_GRP_DIST_REGS :
549
- if (is_write )
550
- tmp32 = * reg ;
551
-
552
- ret = vgic_v3_dist_uaccess (vcpu , is_write , addr , & tmp32 );
553
- if (!is_write )
554
- * reg = tmp32 ;
564
+ ret = vgic_v3_dist_uaccess (vcpu , is_write , addr , & val );
555
565
break ;
556
566
case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS :
557
- if (is_write )
558
- tmp32 = * reg ;
559
-
560
- ret = vgic_v3_redist_uaccess (vcpu , is_write , addr , & tmp32 );
561
- if (!is_write )
562
- * reg = tmp32 ;
567
+ ret = vgic_v3_redist_uaccess (vcpu , is_write , addr , & val );
563
568
break ;
564
569
case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS :
565
570
ret = vgic_v3_cpu_sysregs_uaccess (vcpu , attr , is_write );
@@ -570,14 +575,10 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
570
575
info = (attr -> attr & KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK ) >>
571
576
KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT ;
572
577
if (info == VGIC_LEVEL_INFO_LINE_LEVEL ) {
573
- if (is_write )
574
- tmp32 = * reg ;
575
578
intid = attr -> attr &
576
579
KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK ;
577
580
ret = vgic_v3_line_level_info_uaccess (vcpu , is_write ,
578
- intid , & tmp32 );
579
- if (!is_write )
580
- * reg = tmp32 ;
581
+ intid , & val );
581
582
} else {
582
583
ret = - EINVAL ;
583
584
}
@@ -591,6 +592,12 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
591
592
unlock_all_vcpus (dev -> kvm );
592
593
out :
593
594
mutex_unlock (& dev -> kvm -> lock );
595
+
596
+ if (!ret && uaccess && !is_write ) {
597
+ u32 __user * uaddr = (u32 __user * )(unsigned long )attr -> addr ;
598
+ ret = put_user (val , uaddr );
599
+ }
600
+
594
601
return ret ;
595
602
}
596
603
@@ -605,30 +612,12 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
605
612
606
613
switch (attr -> group ) {
607
614
case KVM_DEV_ARM_VGIC_GRP_DIST_REGS :
608
- case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS : {
609
- u32 __user * uaddr = (u32 __user * )(long )attr -> addr ;
610
- u32 tmp32 ;
611
- u64 reg ;
612
-
613
- if (get_user (tmp32 , uaddr ))
614
- return - EFAULT ;
615
-
616
- reg = tmp32 ;
617
- return vgic_v3_attr_regs_access (dev , attr , & reg , true);
618
- }
615
+ case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS :
616
+ return vgic_v3_attr_regs_access (dev , attr , true);
619
617
case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS :
620
- return vgic_v3_attr_regs_access (dev , attr , NULL , true);
621
- case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO : {
622
- u32 __user * uaddr = (u32 __user * )(long )attr -> addr ;
623
- u64 reg ;
624
- u32 tmp32 ;
625
-
626
- if (get_user (tmp32 , uaddr ))
627
- return - EFAULT ;
628
-
629
- reg = tmp32 ;
630
- return vgic_v3_attr_regs_access (dev , attr , & reg , true);
631
- }
618
+ return vgic_v3_attr_regs_access (dev , attr , true);
619
+ case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO :
620
+ return vgic_v3_attr_regs_access (dev , attr , true);
632
621
case KVM_DEV_ARM_VGIC_GRP_CTRL : {
633
622
int ret ;
634
623
@@ -662,30 +651,12 @@ static int vgic_v3_get_attr(struct kvm_device *dev,
662
651
663
652
switch (attr -> group ) {
664
653
case KVM_DEV_ARM_VGIC_GRP_DIST_REGS :
665
- case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS : {
666
- u32 __user * uaddr = (u32 __user * )(long )attr -> addr ;
667
- u64 reg ;
668
- u32 tmp32 ;
669
-
670
- ret = vgic_v3_attr_regs_access (dev , attr , & reg , false);
671
- if (ret )
672
- return ret ;
673
- tmp32 = reg ;
674
- return put_user (tmp32 , uaddr );
675
- }
654
+ case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS :
655
+ return vgic_v3_attr_regs_access (dev , attr , false);
676
656
case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS :
677
- return vgic_v3_attr_regs_access (dev , attr , NULL , false);
678
- case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO : {
679
- u32 __user * uaddr = (u32 __user * )(long )attr -> addr ;
680
- u64 reg ;
681
- u32 tmp32 ;
682
-
683
- ret = vgic_v3_attr_regs_access (dev , attr , & reg , false);
684
- if (ret )
685
- return ret ;
686
- tmp32 = reg ;
687
- return put_user (tmp32 , uaddr );
688
- }
657
+ return vgic_v3_attr_regs_access (dev , attr , false);
658
+ case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO :
659
+ return vgic_v3_attr_regs_access (dev , attr , false);
689
660
}
690
661
return - ENXIO ;
691
662
}
0 commit comments