[PATCH v7 20/20] arm/arm64: KVM: force alignment of VGIC dist/CPU/redist addresses

Christoffer Dall christoffer.dall at linaro.org
Thu Jan 15 04:29:12 PST 2015


On Wed, Jan 14, 2015 at 04:31:24PM +0000, Andre Przywara wrote:
> Although the GIC architecture requires us to map the MMIO regions
> only at page aligned addresses, we currently do not enforce this from
> the kernel side.
> Restrict any vGICv2 regions to be 4K aligned and any GICv3 regions
> to be 64K aligned. Document this requirement.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
> Changelog:
>  (new in v7)
> 
>  Documentation/virtual/kvm/devices/arm-vgic.txt |    4 ++++
>  virt/kvm/arm/vgic.c                            |   16 +++++++++++++---
>  2 files changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/devices/arm-vgic.txt b/Documentation/virtual/kvm/devices/arm-vgic.txt
> index 5d4fd4b..3fb9054 100644
> --- a/Documentation/virtual/kvm/devices/arm-vgic.txt
> +++ b/Documentation/virtual/kvm/devices/arm-vgic.txt
> @@ -20,20 +20,24 @@ Groups:
>      KVM_VGIC_V2_ADDR_TYPE_DIST (rw, 64-bit)
>        Base address in the guest physical address space of the GIC distributor
>        register mappings. Only valid for KVM_DEV_TYPE_ARM_VGIC_V2.
> +      This address needs to be 4K aligned and the region covers 4 KByte.
>  
>      KVM_VGIC_V2_ADDR_TYPE_CPU (rw, 64-bit)
>        Base address in the guest physical address space of the GIC virtual cpu
>        interface register mappings. Only valid for KVM_DEV_TYPE_ARM_VGIC_V2.
> +      This address needs to be 4K aligned and the region covers 4 KByte.
>  
>      KVM_VGIC_V3_ADDR_TYPE_DIST (rw, 64-bit)
>        Base address in the guest physical address space of the GICv3 distributor
>        register mappings. Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.
> +      This address needs to be 64K aligned and the region covers 64 KByte.
>  
>      KVM_VGIC_V3_ADDR_TYPE_REDIST (rw, 64-bit)
>        Base address in the guest physical address space of the GICv3
>        redistributor register mappings. There are two 64K pages for each
>        VCPU and all of the redistributor pages are contiguous.
>        Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.
> +      This address needs to be 64K aligned.
>  
>  
>    KVM_DEV_ARM_VGIC_GRP_DIST_REGS
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index 184c6db..0cc6ab6 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -1683,6 +1683,7 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
>  	struct vgic_dist *vgic = &kvm->arch.vgic;
>  	int type_needed;
>  	phys_addr_t *addr_ptr, block_size;
> +	phys_addr_t alignment;
>  
>  	mutex_lock(&kvm->lock);
>  	switch (type) {
> @@ -1690,22 +1691,26 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
>  		type_needed = KVM_DEV_TYPE_ARM_VGIC_V2;
>  		addr_ptr = &vgic->vgic_dist_base;
>  		block_size = KVM_VGIC_V2_DIST_SIZE;
> +		alignment = SZ_4K;
>  		break;
>  	case KVM_VGIC_V2_ADDR_TYPE_CPU:
>  		type_needed = KVM_DEV_TYPE_ARM_VGIC_V2;
>  		addr_ptr = &vgic->vgic_cpu_base;
>  		block_size = KVM_VGIC_V2_CPU_SIZE;
> +		alignment = SZ_4K;
>  		break;
>  #ifdef CONFIG_ARM_GIC_V3
>  	case KVM_VGIC_V3_ADDR_TYPE_DIST:
>  		type_needed = KVM_DEV_TYPE_ARM_VGIC_V3;
>  		addr_ptr = &vgic->vgic_dist_base;
>  		block_size = KVM_VGIC_V3_DIST_SIZE;
> +		alignment = SZ_64K;
>  		break;
>  	case KVM_VGIC_V3_ADDR_TYPE_REDIST:
>  		type_needed = KVM_DEV_TYPE_ARM_VGIC_V3;
>  		addr_ptr = &vgic->vgic_redist_base;
>  		block_size = KVM_VGIC_V3_REDIST_SIZE;
> +		alignment = SZ_64K;
>  		break;
>  #endif
>  	default:
> @@ -1718,10 +1723,15 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
>  		goto out;
>  	}
>  
> -	if (write)
> -		r = vgic_ioaddr_assign(kvm, addr_ptr, *addr, block_size);
> -	else
> +	if (write) {
> +		if (!IS_ALIGNED(*addr, alignment))
> +			r = -EINVAL;
> +		else
> +			r = vgic_ioaddr_assign(kvm, addr_ptr, *addr,
> +					       block_size);
> +	} else {
>  		*addr = *addr_ptr;
> +	}
>  
>  out:
>  	mutex_unlock(&kvm->lock);
> -- 

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>



More information about the linux-arm-kernel mailing list