return -ENXIO;
}
-int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id,
- u64 *reg)
+int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr,
+ bool is_write)
{
+ u64 __user *uaddr = (u64 __user *)(long)attr->addr;
struct sys_reg_params params;
const struct sys_reg_desc *r;
- u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64;
+ u64 sysreg;
- if (is_write)
- params.regval = *reg;
+ sysreg = attr_to_id(attr->attr);
+
+ if (is_write) {
+ if (get_user(params.regval, uaddr))
+ return -EFAULT;
+ }
params.is_write = is_write;
r = find_reg_by_id(sysreg, ¶ms, gic_v3_icc_reg_descs,
if (!r->access(vcpu, ¶ms, r))
return -EINVAL;
- if (!is_write)
- *reg = params.regval;
+ if (!is_write) {
+ if (put_user(params.regval, uaddr))
+ return -EFAULT;
+ }
return 0;
}
*
* @dev: kvm device handle
* @attr: kvm device attribute
- * @reg: address the value is read or written
+ * @reg: address the value is read or written, NULL for sysregs
* @is_write: true if userspace is writing a register
*/
static int vgic_v3_attr_regs_access(struct kvm_device *dev,
if (!is_write)
*reg = tmp32;
break;
- case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: {
- u64 regid;
-
- regid = (attr->attr & KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK);
- ret = vgic_v3_cpu_sysregs_uaccess(vcpu, is_write,
- regid, reg);
+ case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
+ ret = vgic_v3_cpu_sysregs_uaccess(vcpu, attr, is_write);
break;
- }
case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
unsigned int info, intid;
reg = tmp32;
return vgic_v3_attr_regs_access(dev, attr, ®, true);
}
- case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: {
- u64 __user *uaddr = (u64 __user *)(long)attr->addr;
- u64 reg;
-
- if (get_user(reg, uaddr))
- return -EFAULT;
-
- return vgic_v3_attr_regs_access(dev, attr, ®, true);
- }
+ case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
+ return vgic_v3_attr_regs_access(dev, attr, NULL, true);
case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
u32 __user *uaddr = (u32 __user *)(long)attr->addr;
u64 reg;
tmp32 = reg;
return put_user(tmp32, uaddr);
}
- case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: {
- u64 __user *uaddr = (u64 __user *)(long)attr->addr;
- u64 reg;
-
- ret = vgic_v3_attr_regs_access(dev, attr, ®, false);
- if (ret)
- return ret;
- return put_user(reg, uaddr);
- }
+ case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
+ return vgic_v3_attr_regs_access(dev, attr, NULL, false);
case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
u32 __user *uaddr = (u32 __user *)(long)attr->addr;
u64 reg;
int offset, u32 *val);
int vgic_v3_redist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
int offset, u32 *val);
-int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write,
- u64 id, u64 *val);
+int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu,
+ struct kvm_device_attr *attr, bool is_write);
int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
int vgic_v3_line_level_info_uaccess(struct kvm_vcpu *vcpu, bool is_write,
u32 intid, u64 *val);