@@ -76,8 +76,7 @@ int kvm_set_legacy_vgic_v2_addr(struct kvm *kvm, struct kvm_arm_device_addr *dev
7676/**
7777 * kvm_vgic_addr - set or get vgic VM base addresses
7878 * @kvm: pointer to the vm struct
79- * @type: the VGIC addr type, one of KVM_VGIC_V[23]_ADDR_TYPE_XXX
80- * @addr: pointer to address value
79+ * @attr: pointer to the attribute being retrieved/updated
8180 * @write: if true set the address in the VM address space, if false read the
8281 * address
8382 *
@@ -89,15 +88,22 @@ int kvm_set_legacy_vgic_v2_addr(struct kvm *kvm, struct kvm_arm_device_addr *dev
8988 * overlapping regions in case of a virtual GICv3 here, since we don't know
9089 * the number of VCPUs yet, so we defer this check to map_resources().
9190 */
92- int kvm_vgic_addr (struct kvm * kvm , unsigned long type , u64 * addr , bool write )
91+ static int kvm_vgic_addr (struct kvm * kvm , struct kvm_device_attr * attr , bool write )
9392{
94- int r = 0 ;
93+ u64 __user * uaddr = ( u64 __user * ) attr -> addr ;
9594 struct vgic_dist * vgic = & kvm -> arch .vgic ;
9695 phys_addr_t * addr_ptr , alignment , size ;
9796 u64 undef_value = VGIC_ADDR_UNDEF ;
97+ u64 addr ;
98+ int r ;
99+
100+ /* Reading a redistributor region addr implies getting the index */
101+ if (write || attr -> attr == KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION )
102+ if (get_user (addr , uaddr ))
103+ return - EFAULT ;
98104
99105 mutex_lock (& kvm -> lock );
100- switch (type ) {
106+ switch (attr -> attr ) {
101107 case KVM_VGIC_V2_ADDR_TYPE_DIST :
102108 r = vgic_check_type (kvm , KVM_DEV_TYPE_ARM_VGIC_V2 );
103109 addr_ptr = & vgic -> vgic_dist_base ;
@@ -123,7 +129,7 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
123129 if (r )
124130 break ;
125131 if (write ) {
126- r = vgic_v3_set_redist_base (kvm , 0 , * addr , 0 );
132+ r = vgic_v3_set_redist_base (kvm , 0 , addr , 0 );
127133 goto out ;
128134 }
129135 rdreg = list_first_entry_or_null (& vgic -> rd_regions ,
@@ -143,14 +149,12 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
143149 if (r )
144150 break ;
145151
146- index = * addr & KVM_VGIC_V3_RDIST_INDEX_MASK ;
152+ index = addr & KVM_VGIC_V3_RDIST_INDEX_MASK ;
147153
148154 if (write ) {
149- gpa_t base = * addr & KVM_VGIC_V3_RDIST_BASE_MASK ;
150- u32 count = (* addr & KVM_VGIC_V3_RDIST_COUNT_MASK )
151- >> KVM_VGIC_V3_RDIST_COUNT_SHIFT ;
152- u8 flags = (* addr & KVM_VGIC_V3_RDIST_FLAGS_MASK )
153- >> KVM_VGIC_V3_RDIST_FLAGS_SHIFT ;
155+ gpa_t base = addr & KVM_VGIC_V3_RDIST_BASE_MASK ;
156+ u32 count = FIELD_GET (KVM_VGIC_V3_RDIST_COUNT_MASK , addr );
157+ u8 flags = FIELD_GET (KVM_VGIC_V3_RDIST_FLAGS_MASK , addr );
154158
155159 if (!count || flags )
156160 r = - EINVAL ;
@@ -166,9 +170,9 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
166170 goto out ;
167171 }
168172
169- * addr = index ;
170- * addr |= rdreg -> base ;
171- * addr |= (u64 )rdreg -> count << KVM_VGIC_V3_RDIST_COUNT_SHIFT ;
173+ addr = index ;
174+ addr |= rdreg -> base ;
175+ addr |= (u64 )rdreg -> count << KVM_VGIC_V3_RDIST_COUNT_SHIFT ;
172176 goto out ;
173177 }
174178 default :
@@ -179,15 +183,19 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
179183 goto out ;
180184
181185 if (write ) {
182- r = vgic_check_iorange (kvm , * addr_ptr , * addr , alignment , size );
186+ r = vgic_check_iorange (kvm , * addr_ptr , addr , alignment , size );
183187 if (!r )
184- * addr_ptr = * addr ;
188+ * addr_ptr = addr ;
185189 } else {
186- * addr = * addr_ptr ;
190+ addr = * addr_ptr ;
187191 }
188192
189193out :
190194 mutex_unlock (& kvm -> lock );
195+
196+ if (!r && !write )
197+ r = put_user (addr , uaddr );
198+
191199 return r ;
192200}
193201
@@ -197,17 +205,9 @@ static int vgic_set_common_attr(struct kvm_device *dev,
197205 int r ;
198206
199207 switch (attr -> group ) {
200- case KVM_DEV_ARM_VGIC_GRP_ADDR : {
201- u64 __user * uaddr = (u64 __user * )(long )attr -> addr ;
202- u64 addr ;
203- unsigned long type = (unsigned long )attr -> attr ;
204-
205- if (get_user (addr , uaddr ))
206- return - EFAULT ;
207-
208- r = kvm_vgic_addr (dev -> kvm , type , & addr , true);
208+ case KVM_DEV_ARM_VGIC_GRP_ADDR :
209+ r = kvm_vgic_addr (dev -> kvm , attr , true);
209210 return (r == - ENODEV ) ? - ENXIO : r ;
210- }
211211 case KVM_DEV_ARM_VGIC_GRP_NR_IRQS : {
212212 u32 __user * uaddr = (u32 __user * )(long )attr -> addr ;
213213 u32 val ;
@@ -260,22 +260,9 @@ static int vgic_get_common_attr(struct kvm_device *dev,
260260 int r = - ENXIO ;
261261
262262 switch (attr -> group ) {
263- case KVM_DEV_ARM_VGIC_GRP_ADDR : {
264- u64 __user * uaddr = (u64 __user * )(long )attr -> addr ;
265- u64 addr ;
266- unsigned long type = (unsigned long )attr -> attr ;
267-
268- if (get_user (addr , uaddr ))
269- return - EFAULT ;
270-
271- r = kvm_vgic_addr (dev -> kvm , type , & addr , false);
272- if (r )
273- return (r == - ENODEV ) ? - ENXIO : r ;
274-
275- if (put_user (addr , uaddr ))
276- return - EFAULT ;
277- break ;
278- }
263+ case KVM_DEV_ARM_VGIC_GRP_ADDR :
264+ r = kvm_vgic_addr (dev -> kvm , attr , false);
265+ return (r == - ENODEV ) ? - ENXIO : r ;
279266 case KVM_DEV_ARM_VGIC_GRP_NR_IRQS : {
280267 u32 __user * uaddr = (u32 __user * )(long )attr -> addr ;
281268
0 commit comments