@@ -512,18 +512,18 @@ int vgic_v3_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr,
512512 *
513513 * @dev: kvm device handle
514514 * @attr: kvm device attribute
515- * @reg: address the value is read or written, NULL for sysregs
516515 * @is_write: true if userspace is writing a register
517516 */
518517static int vgic_v3_attr_regs_access (struct kvm_device * dev ,
519518 struct kvm_device_attr * attr ,
520- u64 * reg , bool is_write )
519+ bool is_write )
521520{
522521 struct vgic_reg_attr reg_attr ;
523522 gpa_t addr ;
524523 struct kvm_vcpu * vcpu ;
524+ bool uaccess ;
525+ u32 val ;
525526 int ret ;
526- u32 tmp32 ;
527527
528528 ret = vgic_v3_parse_attr (dev , attr , & reg_attr );
529529 if (ret )
@@ -532,6 +532,21 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
532532 vcpu = reg_attr .vcpu ;
533533 addr = reg_attr .addr ;
534534
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+
535550 mutex_lock (& dev -> kvm -> lock );
536551
537552 if (unlikely (!vgic_initialized (dev -> kvm ))) {
@@ -546,20 +561,10 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
546561
547562 switch (attr -> group ) {
548563 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 );
555565 break ;
556566 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 );
563568 break ;
564569 case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS :
565570 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,
570575 info = (attr -> attr & KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK ) >>
571576 KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT ;
572577 if (info == VGIC_LEVEL_INFO_LINE_LEVEL ) {
573- if (is_write )
574- tmp32 = * reg ;
575578 intid = attr -> attr &
576579 KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK ;
577580 ret = vgic_v3_line_level_info_uaccess (vcpu , is_write ,
578- intid , & tmp32 );
579- if (!is_write )
580- * reg = tmp32 ;
581+ intid , & val );
581582 } else {
582583 ret = - EINVAL ;
583584 }
@@ -591,6 +592,12 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
591592 unlock_all_vcpus (dev -> kvm );
592593out :
593594 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+
594601 return ret ;
595602}
596603
@@ -605,30 +612,12 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
605612
606613 switch (attr -> group ) {
607614 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);
619617 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);
632621 case KVM_DEV_ARM_VGIC_GRP_CTRL : {
633622 int ret ;
634623
@@ -662,30 +651,12 @@ static int vgic_v3_get_attr(struct kvm_device *dev,
662651
663652 switch (attr -> group ) {
664653 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);
676656 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);
689660 }
690661 return - ENXIO ;
691662}
0 commit comments