On Fri, Sep 23, 2016 at 9:14 PM, <vijay.kilari@xxxxxxxxx> wrote: > From: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxx> > > VGICv3 CPU interface registers are accessed using > KVM_DEV_ARM_VGIC_CPU_SYSREGS ioctl. These registers are accessed > as 64-bit. The cpu MPIDR value is passed along with register id. > is used to identify the cpu for registers access. > > The version of VGIC v3 specification is define here > http://lists.infradead.org/pipermail/linux-arm-kernel/2016-July/445611.html > > Signed-off-by: Pavel Fedin <p.fedin@xxxxxxxxxxx> > Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxx> > --- > arch/arm64/include/uapi/asm/kvm.h | 3 + > arch/arm64/kvm/Makefile | 1 + > include/kvm/arm_vgic.h | 9 + > virt/kvm/arm/vgic/vgic-kvm-device.c | 27 +++ > virt/kvm/arm/vgic/vgic-mmio-v3.c | 19 +++ > virt/kvm/arm/vgic/vgic-sys-reg-v3.c | 324 ++++++++++++++++++++++++++++++++++++ > virt/kvm/arm/vgic/vgic-v3.c | 8 + > virt/kvm/arm/vgic/vgic.h | 4 + > 8 files changed, 395 insertions(+) > > diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h > index 56dc08d..91c7137 100644 > --- a/arch/arm64/include/uapi/asm/kvm.h > +++ b/arch/arm64/include/uapi/asm/kvm.h > @@ -206,9 +206,12 @@ struct kvm_arch_memory_slot { > (0xffffffffULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT) > #define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0 > #define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT) > +#define KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK (0xffff) > #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3 > #define KVM_DEV_ARM_VGIC_GRP_CTRL 4 > #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5 > +#define KVM_DEV_ARM_VGIC_CPU_SYSREGS 6 > + > #define KVM_DEV_ARM_VGIC_CTRL_INIT 0 > > /* Device Control API on vcpu fd */ > diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile > index d50a82a..1a14e29 100644 > --- a/arch/arm64/kvm/Makefile > +++ b/arch/arm64/kvm/Makefile > @@ -32,5 +32,6 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-mmio-v3.o > kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-kvm-device.o > kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-its.o > kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/irqchip.o > +kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-sys-reg-v3.o > kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o > kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o > diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h > index 002f092..730a18a 100644 > --- a/include/kvm/arm_vgic.h > +++ b/include/kvm/arm_vgic.h > @@ -71,6 +71,9 @@ struct vgic_global { > > /* GIC system register CPU interface */ > struct static_key_false gicv3_cpuif; > + > + /* Cache ICH_VTR_EL2 reg value */ > + u32 ich_vtr_el2; > }; > > extern struct vgic_global kvm_vgic_global_state; > @@ -269,6 +272,12 @@ struct vgic_cpu { > u64 pendbaser; > > bool lpis_enabled; > + > + /* Cache guest priority bits */ > + u32 num_pri_bits; > + > + /* Cache guest interrupt ID bits */ > + u32 num_id_bits; > }; > > extern struct static_key_false vgic_v2_cpuif_trap; > diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c > index 6c7d30c..da532d1 100644 > --- a/virt/kvm/arm/vgic/vgic-kvm-device.c > +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c > @@ -504,6 +504,14 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev, > if (!is_write) > *reg = tmp32; > break; > + case KVM_DEV_ARM_VGIC_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); > + break; > + } > default: > ret = -EINVAL; > break; > @@ -537,6 +545,15 @@ static int vgic_v3_set_attr(struct kvm_device *dev, > reg = tmp32; > return vgic_v3_attr_regs_access(dev, attr, ®, true); > } > + case KVM_DEV_ARM_VGIC_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); > + } > } > return -ENXIO; > } > @@ -563,6 +580,15 @@ static int vgic_v3_get_attr(struct kvm_device *dev, > tmp32 = reg; > return put_user(tmp32, uaddr); > } > + case KVM_DEV_ARM_VGIC_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); > + } > } > > return -ENXIO; > @@ -581,6 +607,7 @@ static int vgic_v3_has_attr(struct kvm_device *dev, > break; > case KVM_DEV_ARM_VGIC_GRP_DIST_REGS: > case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS: > + case KVM_DEV_ARM_VGIC_CPU_SYSREGS: > return vgic_v3_has_attr_regs(dev, attr); > case KVM_DEV_ARM_VGIC_GRP_NR_IRQS: > return 0; > diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c > index b35fb83..8f46e61 100644 > --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c > +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c > @@ -23,6 +23,7 @@ > > #include "vgic.h" > #include "vgic-mmio.h" > +#include "sys_regs.h" > > /* extract @num bytes at @offset bytes offset in data */ > unsigned long extract_bytes(u64 data, unsigned int offset, > @@ -639,6 +640,24 @@ int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr) > nr_regions = ARRAY_SIZE(vgic_v3_rdbase_registers); > break; > } > + case KVM_DEV_ARM_VGIC_CPU_SYSREGS: { > + u64 reg, id; > + unsigned long vgic_mpidr, mpidr_reg; > + struct kvm_vcpu *vcpu; > + > + vgic_mpidr = (attr->attr & KVM_DEV_ARM_VGIC_V3_MPIDR_MASK) >> > + KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT; > + > + /* Convert plain mpidr value to MPIDR reg format */ > + mpidr_reg = VGIC_TO_MPIDR(mpidr_reg); My bad, Wrong parameter. I will fix it. _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm