[PATCH v3 47/55] KVM: arm/arm64: vgic-new: Add userland GIC CPU interface access
Andre Przywara
andre.przywara at arm.com
Fri May 13 03:44:38 PDT 2016
Hi,
On 13/05/16 08:53, Christoffer Dall wrote:
> On Thu, May 12, 2016 at 07:52:38PM +0100, Andre Przywara wrote:
>> Hi,
>>
>> On 12/05/16 19:47, Christoffer Dall wrote:
>>> On Fri, May 06, 2016 at 11:46:00AM +0100, 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.
>>>> [Marc: move and make VMCR accessors static, streamline MMIO handlers]
>>>
>>> does this mean Marc did this and serves as credit or is it a lost
>>> reminder?
>>
>> It was meant as credit. I thought that is the usual annotation for this?
>>
>
> I'm not sure if that's the usual way, I read it as a reminder, but it's
> not too important. Mostly wanting to make sure we're not forgetting
> some todo item.
>
>>>>
>>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>>> ---
>>>> Changelog v2 .. v3:
>>>> - total rework, moving into vgic-mmio-v2.c
>>>> - move vmcr accessor wrapper functions into this file
>>>> - use the register description table for CPU i/f registers as well
>>>> - add RAZ/WI handling for the active priority registers
>>>> - streamline MMIO handler functions
>>>>
>>>> virt/kvm/arm/vgic/vgic-kvm-device.c | 2 +-
>>>> virt/kvm/arm/vgic/vgic-mmio-v2.c | 104 ++++++++++++++++++++++++++++++++++++
>>>> virt/kvm/arm/vgic/vgic.h | 2 +
>>>> 3 files changed, 107 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
>>>> index bb33af8..2122ff2 100644
>>>> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
>>>> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
>>>> @@ -300,7 +300,7 @@ static int vgic_attr_regs_access(struct kvm_device *dev,
>>>>
>>>> switch (attr->group) {
>>>> case KVM_DEV_ARM_VGIC_GRP_CPU_REGS:
>>>> - ret = -EINVAL;
>>>> + ret = vgic_v2_cpuif_uaccess(vcpu, is_write, addr, reg);
>>>> break;
>>>> case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
>>>> ret = vgic_v2_dist_uaccess(vcpu, is_write, addr, reg);
>>>> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v2.c b/virt/kvm/arm/vgic/vgic-mmio-v2.c
>>>> index c453e6f..0060539 100644
>>>> --- a/virt/kvm/arm/vgic/vgic-mmio-v2.c
>>>> +++ b/virt/kvm/arm/vgic/vgic-mmio-v2.c
>>>> @@ -206,6 +206,84 @@ static void vgic_mmio_write_sgipends(struct kvm_vcpu *vcpu,
>>>> }
>>>> }
>>>>
>>>> +static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
>>>> +{
>>>> + if (kvm_vgic_global_state.type == VGIC_V2)
>>>> + vgic_v2_set_vmcr(vcpu, vmcr);
>>>> + else
>>>> + vgic_v3_set_vmcr(vcpu, vmcr);
>>>> +}
>>>> +
>>>> +static void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
>>>> +{
>>>> + if (kvm_vgic_global_state.type == VGIC_V2)
>>>> + vgic_v2_get_vmcr(vcpu, vmcr);
>>>> + else
>>>> + vgic_v3_get_vmcr(vcpu, vmcr);
>>>> +}
>>>> +
>>>> +#define GICC_ARCH_VERSION_V2 0x2
>>>> +
>>>> +/* These are for userland accesses only, there is no guest-facing emulation. */
>>>> +static unsigned long vgic_mmio_read_vcpuif(struct kvm_vcpu *vcpu,
>>>> + gpa_t addr, unsigned int len)
>>>> +{
>>>> + struct vgic_vmcr vmcr;
>>>> + u32 val;
>>>> +
>>>> + vgic_get_vmcr(vcpu, &vmcr);
>>>> +
>>>> + switch (addr & 0xff) {
>>>> + case GIC_CPU_CTRL:
>>>> + val = vmcr.ctlr;
>>>> + break;
>>>> + case GIC_CPU_PRIMASK:
>>>> + val = vmcr.pmr;
>>>> + break;
>>>> + case GIC_CPU_BINPOINT:
>>>> + val = vmcr.bpr;
>>>> + break;
>>>> + case GIC_CPU_ALIAS_BINPOINT:
>>>> + val = vmcr.abpr;
>>>> + break;
>>>> + case GIC_CPU_IDENT:
>>>> + val = ((PRODUCT_ID_KVM << 20) |
>>>> + (GICC_ARCH_VERSION_V2 << 16) |
>>>> + IMPLEMENTER_ARM);
>>>> + break;
>>>> + default:
>>>> + return 0;
>>>> + }
>>>> +
>>>> + return extract_bytes(val, addr & 3, len);
>>>
>>> I don't think we allow anything than a full 32-bit aligned accesses
>>> from userspace - we shouldn't at least.
>>
>> Indeed - I think userland was always 32-bit only. And since last night
>> we even enforce this. So potentially there are more extract_bytes()
>> calls that can go.
>>
> Right.
So can I replace every call to extract_bytes() with just a "return val;"
for every register that allows 32-bit accesses only?
I think that's safe now, just checking ...
Cheers,
Andre.
More information about the linux-arm-kernel
mailing list