aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kvm
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2012-10-28 11:52:57 +0000
committerChristoffer Dall <cdall@cs.columbia.edu>2013-03-06 15:48:44 -0800
commitb4034bde5f168f2383a54b4573e1e440dbc169cf (patch)
tree04504f235132f1ac109b58efecc5c5f049374e28 /arch/arm/kvm
parentARM: KVM: allow HYP mappings to be at an offset from kernel mappings (diff)
downloadlinux-dev-b4034bde5f168f2383a54b4573e1e440dbc169cf.tar.xz
linux-dev-b4034bde5f168f2383a54b4573e1e440dbc169cf.zip
ARM: KVM: fix address validation for HYP mappings
__create_hyp_mappings() performs some kind of address validation before creating the mapping, by verifying that the start address is above PAGE_OFFSET. This check is not completely correct for kernel memory (the upper boundary has to be checked as well so we do not end up with highmem pages), and wrong for IO mappings (the mapping must exist in the vmalloc region). Fix this by using the proper predicates (virt_addr_valid and is_vmalloc_addr), which also work correctly on ARM64 (where the vmalloc region is below PAGE_OFFSET). Also change the BUG_ON() into a less agressive error return. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm/kvm')
-rw-r--r--arch/arm/kvm/mmu.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index ead6b16eeb09..ec14269a791c 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -200,8 +200,13 @@ static int __create_hyp_mappings(void *from, void *to, unsigned long *pfn_base)
unsigned long addr, next;
int err = 0;
- BUG_ON(start > end);
- if (start < PAGE_OFFSET)
+ if (start >= end)
+ return -EINVAL;
+ /* Check for a valid kernel memory mapping */
+ if (!pfn_base && (!virt_addr_valid(from) || !virt_addr_valid(to - 1)))
+ return -EINVAL;
+ /* Check for a valid kernel IO mapping */
+ if (pfn_base && (!is_vmalloc_addr(from) || !is_vmalloc_addr(to - 1)))
return -EINVAL;
mutex_lock(&kvm_hyp_pgd_mutex);