Skip to content

Commit db25081

Browse files
author
Marc Zyngier
committed
KVM: arm64: vgic-v3: Push user access into vgic_v3_cpu_sysregs_uaccess()
In order to start making the vgic sysreg access from userspace similar to all the other sysregs, push the userspace memory access one level down into vgic_v3_cpu_sysregs_uaccess(). The next step will be to rely on the sysreg infrastructure to perform this task. Reviewed-by: Reiji Watanabe <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent b61fc08 commit db25081

File tree

3 files changed

+24
-35
lines changed

3 files changed

+24
-35
lines changed

arch/arm64/kvm/vgic-sys-reg-v3.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,15 +278,21 @@ int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *
278278
return -ENXIO;
279279
}
280280

281-
int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id,
282-
u64 *reg)
281+
int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu,
282+
struct kvm_device_attr *attr,
283+
bool is_write)
283284
{
285+
u64 __user *uaddr = (u64 __user *)(long)attr->addr;
284286
struct sys_reg_params params;
285287
const struct sys_reg_desc *r;
286-
u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64;
288+
u64 sysreg;
287289

288-
if (is_write)
289-
params.regval = *reg;
290+
sysreg = attr_to_id(attr->attr);
291+
292+
if (is_write) {
293+
if (get_user(params.regval, uaddr))
294+
return -EFAULT;
295+
}
290296
params.is_write = is_write;
291297

292298
r = find_reg_by_id(sysreg, &params, gic_v3_icc_reg_descs,
@@ -297,8 +303,10 @@ int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id,
297303
if (!r->access(vcpu, &params, r))
298304
return -EINVAL;
299305

300-
if (!is_write)
301-
*reg = params.regval;
306+
if (!is_write) {
307+
if (put_user(params.regval, uaddr))
308+
return -EFAULT;
309+
}
302310

303311
return 0;
304312
}

arch/arm64/kvm/vgic/vgic-kvm-device.c

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ 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
515+
* @reg: address the value is read or written, NULL for sysregs
516516
* @is_write: true if userspace is writing a register
517517
*/
518518
static int vgic_v3_attr_regs_access(struct kvm_device *dev,
@@ -561,14 +561,9 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
561561
if (!is_write)
562562
*reg = tmp32;
563563
break;
564-
case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: {
565-
u64 regid;
566-
567-
regid = (attr->attr & KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK);
568-
ret = vgic_v3_cpu_sysregs_uaccess(vcpu, is_write,
569-
regid, reg);
564+
case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
565+
ret = vgic_v3_cpu_sysregs_uaccess(vcpu, attr, is_write);
570566
break;
571-
}
572567
case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
573568
unsigned int info, intid;
574569

@@ -617,15 +612,8 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
617612
reg = tmp32;
618613
return vgic_v3_attr_regs_access(dev, attr, &reg, true);
619614
}
620-
case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: {
621-
u64 __user *uaddr = (u64 __user *)(long)attr->addr;
622-
u64 reg;
623-
624-
if (get_user(reg, uaddr))
625-
return -EFAULT;
626-
627-
return vgic_v3_attr_regs_access(dev, attr, &reg, true);
628-
}
615+
case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
616+
return vgic_v3_attr_regs_access(dev, attr, NULL, true);
629617
case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
630618
u32 __user *uaddr = (u32 __user *)(long)attr->addr;
631619
u64 reg;
@@ -681,15 +669,8 @@ static int vgic_v3_get_attr(struct kvm_device *dev,
681669
tmp32 = reg;
682670
return put_user(tmp32, uaddr);
683671
}
684-
case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: {
685-
u64 __user *uaddr = (u64 __user *)(long)attr->addr;
686-
u64 reg;
687-
688-
ret = vgic_v3_attr_regs_access(dev, attr, &reg, false);
689-
if (ret)
690-
return ret;
691-
return put_user(reg, uaddr);
692-
}
672+
case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
673+
return vgic_v3_attr_regs_access(dev, attr, NULL, false);
693674
case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
694675
u32 __user *uaddr = (u32 __user *)(long)attr->addr;
695676
u64 reg;

arch/arm64/kvm/vgic/vgic.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ int vgic_v3_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
245245
int offset, u32 *val);
246246
int vgic_v3_redist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
247247
int offset, u32 *val);
248-
int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write,
249-
u64 id, u64 *val);
248+
int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu,
249+
struct kvm_device_attr *attr, bool is_write);
250250
int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
251251
int vgic_v3_line_level_info_uaccess(struct kvm_vcpu *vcpu, bool is_write,
252252
u32 intid, u64 *val);

0 commit comments

Comments
 (0)