diff options
author | Gleb Natapov <gleb@redhat.com> | 2013-11-19 03:43:05 -0500 |
---|---|---|
committer | Gleb Natapov <gleb@redhat.com> | 2013-11-19 03:43:05 -0500 |
commit | 2ecd1aba597726c9053ba1a112e3d8fdc5ca08ff (patch) | |
tree | 2a89c219b3e348e6801c7803bd7afcb295f4949f /arch | |
parent | f080480488028bcc25357f85e8ae54ccc3bb7173 (diff) | |
parent | 40c2729bab48e2832b17c1fa8af9db60e776131b (diff) |
Merge tag 'kvm-arm-fixes-3.13-1' of git://git.linaro.org/people/cdall/linux-kvm-arm into next
Fix percpu vmalloc allocations
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/kvm/mmu.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 371958370de4..580906989db1 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
@@ -334,6 +334,17 @@ out: | |||
334 | return err; | 334 | return err; |
335 | } | 335 | } |
336 | 336 | ||
337 | static phys_addr_t kvm_kaddr_to_phys(void *kaddr) | ||
338 | { | ||
339 | if (!is_vmalloc_addr(kaddr)) { | ||
340 | BUG_ON(!virt_addr_valid(kaddr)); | ||
341 | return __pa(kaddr); | ||
342 | } else { | ||
343 | return page_to_phys(vmalloc_to_page(kaddr)) + | ||
344 | offset_in_page(kaddr); | ||
345 | } | ||
346 | } | ||
347 | |||
337 | /** | 348 | /** |
338 | * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode | 349 | * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode |
339 | * @from: The virtual kernel start address of the range | 350 | * @from: The virtual kernel start address of the range |
@@ -345,16 +356,27 @@ out: | |||
345 | */ | 356 | */ |
346 | int create_hyp_mappings(void *from, void *to) | 357 | int create_hyp_mappings(void *from, void *to) |
347 | { | 358 | { |
348 | unsigned long phys_addr = virt_to_phys(from); | 359 | phys_addr_t phys_addr; |
360 | unsigned long virt_addr; | ||
349 | unsigned long start = KERN_TO_HYP((unsigned long)from); | 361 | unsigned long start = KERN_TO_HYP((unsigned long)from); |
350 | unsigned long end = KERN_TO_HYP((unsigned long)to); | 362 | unsigned long end = KERN_TO_HYP((unsigned long)to); |
351 | 363 | ||
352 | /* Check for a valid kernel memory mapping */ | 364 | start = start & PAGE_MASK; |
353 | if (!virt_addr_valid(from) || !virt_addr_valid(to - 1)) | 365 | end = PAGE_ALIGN(end); |
354 | return -EINVAL; | ||
355 | 366 | ||
356 | return __create_hyp_mappings(hyp_pgd, start, end, | 367 | for (virt_addr = start; virt_addr < end; virt_addr += PAGE_SIZE) { |
357 | __phys_to_pfn(phys_addr), PAGE_HYP); | 368 | int err; |
369 | |||
370 | phys_addr = kvm_kaddr_to_phys(from + virt_addr - start); | ||
371 | err = __create_hyp_mappings(hyp_pgd, virt_addr, | ||
372 | virt_addr + PAGE_SIZE, | ||
373 | __phys_to_pfn(phys_addr), | ||
374 | PAGE_HYP); | ||
375 | if (err) | ||
376 | return err; | ||
377 | } | ||
378 | |||
379 | return 0; | ||
358 | } | 380 | } |
359 | 381 | ||
360 | /** | 382 | /** |