aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kvm/mmu.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index b0de86b56c13..cb79a5dd6d96 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -307,6 +307,17 @@ out:
307 return err; 307 return err;
308} 308}
309 309
310static phys_addr_t kvm_kaddr_to_phys(void *kaddr)
311{
312 if (!is_vmalloc_addr(kaddr)) {
313 BUG_ON(!virt_addr_valid(kaddr));
314 return __pa(kaddr);
315 } else {
316 return page_to_phys(vmalloc_to_page(kaddr)) +
317 offset_in_page(kaddr);
318 }
319}
320
310/** 321/**
311 * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode 322 * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode
312 * @from: The virtual kernel start address of the range 323 * @from: The virtual kernel start address of the range
@@ -318,16 +329,27 @@ out:
318 */ 329 */
319int create_hyp_mappings(void *from, void *to) 330int create_hyp_mappings(void *from, void *to)
320{ 331{
321 unsigned long phys_addr = virt_to_phys(from); 332 phys_addr_t phys_addr;
333 unsigned long virt_addr;
322 unsigned long start = KERN_TO_HYP((unsigned long)from); 334 unsigned long start = KERN_TO_HYP((unsigned long)from);
323 unsigned long end = KERN_TO_HYP((unsigned long)to); 335 unsigned long end = KERN_TO_HYP((unsigned long)to);
324 336
325 /* Check for a valid kernel memory mapping */ 337 start = start & PAGE_MASK;
326 if (!virt_addr_valid(from) || !virt_addr_valid(to - 1)) 338 end = PAGE_ALIGN(end);
327 return -EINVAL;
328 339
329 return __create_hyp_mappings(hyp_pgd, start, end, 340 for (virt_addr = start; virt_addr < end; virt_addr += PAGE_SIZE) {
330 __phys_to_pfn(phys_addr), PAGE_HYP); 341 int err;
342
343 phys_addr = kvm_kaddr_to_phys(from + virt_addr - start);
344 err = __create_hyp_mappings(hyp_pgd, virt_addr,
345 virt_addr + PAGE_SIZE,
346 __phys_to_pfn(phys_addr),
347 PAGE_HYP);
348 if (err)
349 return err;
350 }
351
352 return 0;
331} 353}
332 354
333/** 355/**