From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andre Przywara Subject: [RFC PATCH 37/45] KVM: arm/arm64: vgic-new: Add userland GIC CPU interface access Date: Fri, 25 Mar 2016 02:05:00 +0000 Message-ID: <1458871508-17279-38-git-send-email-andre.przywara@arm.com> References: <1458871508-17279-1-git-send-email-andre.przywara@arm.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org To: Christoffer Dall , Marc Zyngier , Eric Auger Return-path: In-Reply-To: <1458871508-17279-1-git-send-email-andre.przywara@arm.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kvmarm-bounces@lists.cs.columbia.edu Sender: kvmarm-bounces@lists.cs.columbia.edu List-Id: kvm.vger.kernel.org Signed-off-by: Andre Przywara --- 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 2e2f8b6..7f78a16 100644 --- a/virt/kvm/arm/vgic/vgic_kvm_device.c +++ b/virt/kvm/arm/vgic/vgic_kvm_device.c @@ -17,8 +17,11 @@ #include #include #include +#include #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_access(vcpu, is_write, addr, 4, reg); -- 2.7.3 From mboxrd@z Thu Jan 1 00:00:00 1970 From: andre.przywara@arm.com (Andre Przywara) Date: Fri, 25 Mar 2016 02:05:00 +0000 Subject: [RFC PATCH 37/45] KVM: arm/arm64: vgic-new: Add userland GIC CPU interface access In-Reply-To: <1458871508-17279-1-git-send-email-andre.przywara@arm.com> References: <1458871508-17279-1-git-send-email-andre.przywara@arm.com> Message-ID: <1458871508-17279-38-git-send-email-andre.przywara@arm.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Signed-off-by: Andre Przywara --- 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 2e2f8b6..7f78a16 100644 --- a/virt/kvm/arm/vgic/vgic_kvm_device.c +++ b/virt/kvm/arm/vgic/vgic_kvm_device.c @@ -17,8 +17,11 @@ #include #include #include +#include #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_access(vcpu, is_write, addr, 4, reg); -- 2.7.3