On 28/04/16 17:46, Andre Przywara wrote: > Using the VMCR accessors we provide access to GIC CPU interface state > to userland by wiring it up to the existing userland interface. > > Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx> > --- > virt/kvm/arm/vgic/vgic-kvm-device.c | 72 ++++++++++++++++++++++++++++++++++++- > 1 file changed, 71 insertions(+), 1 deletion(-) > > diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c > index 38260ae..eaf5c1d 100644 > --- a/virt/kvm/arm/vgic/vgic-kvm-device.c > +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c > @@ -17,8 +17,11 @@ > #include <kvm/vgic/vgic.h> > #include <linux/uaccess.h> > #include <asm/kvm_mmu.h> > +#include <linux/irqchip/arm-gic.h> > #include "vgic.h" > > +#define GICC_ARCH_VERSION_V2 0x2 > + > /* common helpers */ > > static int vgic_ioaddr_overlap(struct kvm *kvm) > @@ -252,6 +255,69 @@ void kvm_register_vgic_device(unsigned long type) > } > } > > +static u32 vgic_read_vcpuif(struct kvm_vcpu *vcpu, int offset) > +{ > + struct vgic_vmcr vmcr; > + u32 *field; > + > + switch (offset) { > + case GIC_CPU_CTRL: > + field = &vmcr.ctlr; > + break; > + case GIC_CPU_PRIMASK: > + field = &vmcr.pmr; > + break; > + case GIC_CPU_BINPOINT: > + field = &vmcr.bpr; > + break; > + case GIC_CPU_ALIAS_BINPOINT: > + field = &vmcr.abpr; > + break; > + case GIC_CPU_IDENT: > + return (PRODUCT_ID_KVM << 20) | > + (GICC_ARCH_VERSION_V2 << 16) | > + (IMPLEMENTER_ARM << 0); > + default: > + return 0; > + } > + > + vgic_get_vmcr(vcpu, &vmcr); > + > + return *field; > +} > + > +static bool vgic_write_vcpuif(struct kvm_vcpu *vcpu, int offset, u32 value) > +{ > + struct vgic_vmcr vmcr; > + u32 *field; > + > + switch (offset) { > + case GIC_CPU_CTRL: > + field = &vmcr.ctlr; > + break; > + case GIC_CPU_PRIMASK: > + field = &vmcr.pmr; > + break; > + case GIC_CPU_BINPOINT: > + field = &vmcr.bpr; > + break; > + case GIC_CPU_ALIAS_BINPOINT: > + field = &vmcr.abpr; > + break; > + default: > + return false; > + } > + > + vgic_get_vmcr(vcpu, &vmcr); > + if (*field == value) > + return false; > + > + *field = value; > + vgic_set_vmcr(vcpu, &vmcr); > + > + return true; > +} > + > /** vgic_attr_regs_access: allows user space to read/write VGIC registers > * > * @dev: kvm device handle > @@ -300,7 +366,11 @@ static int vgic_attr_regs_access(struct kvm_device *dev, > > switch (attr->group) { > case KVM_DEV_ARM_VGIC_GRP_CPU_REGS: > - ret = -EINVAL; > + ret = 0; > + if (is_write) > + vgic_write_vcpuif(vcpu, addr, *reg); > + else > + *reg = vgic_read_vcpuif(vcpu, addr); > break; > case KVM_DEV_ARM_VGIC_GRP_DIST_REGS: > ret = vgic_v2_dist_uaccess(vcpu, is_write, addr, reg); > Shouldn't we have this implemented as an MMIO table, and moved to the vgic-v2-mmio.c file? Thanks, M. -- Jazz is not dead. It just smells funny... -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html