aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2015-01-13 07:02:13 -0500
committerChristoffer Dall <christoffer.dall@linaro.org>2015-01-20 12:25:33 -0500
commit4fa96afd94a9bb29135d6e2e8fdb527e58f4fd5c (patch)
treeaa982135e881964a54d5e6e7f85563393abefb3d /virt
parentac3d373564d9744068d867a0eb16da2ff8d5ee9d (diff)
arm/arm64: KVM: force alignment of VGIC dist/CPU/redist addresses
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@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/vgic.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 184c6dbd5165..0cc6ab6005a0 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)
1683 struct vgic_dist *vgic = &kvm->arch.vgic; 1683 struct vgic_dist *vgic = &kvm->arch.vgic;
1684 int type_needed; 1684 int type_needed;
1685 phys_addr_t *addr_ptr, block_size; 1685 phys_addr_t *addr_ptr, block_size;
1686 phys_addr_t alignment;
1686 1687
1687 mutex_lock(&kvm->lock); 1688 mutex_lock(&kvm->lock);
1688 switch (type) { 1689 switch (type) {
@@ -1690,22 +1691,26 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
1690 type_needed = KVM_DEV_TYPE_ARM_VGIC_V2; 1691 type_needed = KVM_DEV_TYPE_ARM_VGIC_V2;
1691 addr_ptr = &vgic->vgic_dist_base; 1692 addr_ptr = &vgic->vgic_dist_base;
1692 block_size = KVM_VGIC_V2_DIST_SIZE; 1693 block_size = KVM_VGIC_V2_DIST_SIZE;
1694 alignment = SZ_4K;
1693 break; 1695 break;
1694 case KVM_VGIC_V2_ADDR_TYPE_CPU: 1696 case KVM_VGIC_V2_ADDR_TYPE_CPU:
1695 type_needed = KVM_DEV_TYPE_ARM_VGIC_V2; 1697 type_needed = KVM_DEV_TYPE_ARM_VGIC_V2;
1696 addr_ptr = &vgic->vgic_cpu_base; 1698 addr_ptr = &vgic->vgic_cpu_base;
1697 block_size = KVM_VGIC_V2_CPU_SIZE; 1699 block_size = KVM_VGIC_V2_CPU_SIZE;
1700 alignment = SZ_4K;
1698 break; 1701 break;
1699#ifdef CONFIG_ARM_GIC_V3 1702#ifdef CONFIG_ARM_GIC_V3
1700 case KVM_VGIC_V3_ADDR_TYPE_DIST: 1703 case KVM_VGIC_V3_ADDR_TYPE_DIST:
1701 type_needed = KVM_DEV_TYPE_ARM_VGIC_V3; 1704 type_needed = KVM_DEV_TYPE_ARM_VGIC_V3;
1702 addr_ptr = &vgic->vgic_dist_base; 1705 addr_ptr = &vgic->vgic_dist_base;
1703 block_size = KVM_VGIC_V3_DIST_SIZE; 1706 block_size = KVM_VGIC_V3_DIST_SIZE;
1707 alignment = SZ_64K;
1704 break; 1708 break;
1705 case KVM_VGIC_V3_ADDR_TYPE_REDIST: 1709 case KVM_VGIC_V3_ADDR_TYPE_REDIST:
1706 type_needed = KVM_DEV_TYPE_ARM_VGIC_V3; 1710 type_needed = KVM_DEV_TYPE_ARM_VGIC_V3;
1707 addr_ptr = &vgic->vgic_redist_base; 1711 addr_ptr = &vgic->vgic_redist_base;
1708 block_size = KVM_VGIC_V3_REDIST_SIZE; 1712 block_size = KVM_VGIC_V3_REDIST_SIZE;
1713 alignment = SZ_64K;
1709 break; 1714 break;
1710#endif 1715#endif
1711 default: 1716 default:
@@ -1718,10 +1723,15 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
1718 goto out; 1723 goto out;
1719 } 1724 }
1720 1725
1721 if (write) 1726 if (write) {
1722 r = vgic_ioaddr_assign(kvm, addr_ptr, *addr, block_size); 1727 if (!IS_ALIGNED(*addr, alignment))
1723 else 1728 r = -EINVAL;
1729 else
1730 r = vgic_ioaddr_assign(kvm, addr_ptr, *addr,
1731 block_size);
1732 } else {
1724 *addr = *addr_ptr; 1733 *addr = *addr_ptr;
1734 }
1725 1735
1726out: 1736out:
1727 mutex_unlock(&kvm->lock); 1737 mutex_unlock(&kvm->lock);