diff options
-rw-r--r-- | arch/arm/kvm/mmu.c | 34 | ||||
-rw-r--r-- | arch/x86/kvm/mmu_audit.c | 2 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 5 |
3 files changed, 32 insertions, 9 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 | /** |
diff --git a/arch/x86/kvm/mmu_audit.c b/arch/x86/kvm/mmu_audit.c index daff69e21150..1185fe7a7f47 100644 --- a/arch/x86/kvm/mmu_audit.c +++ b/arch/x86/kvm/mmu_audit.c | |||
@@ -296,4 +296,4 @@ static struct kernel_param_ops audit_param_ops = { | |||
296 | .get = param_get_bool, | 296 | .get = param_get_bool, |
297 | }; | 297 | }; |
298 | 298 | ||
299 | module_param_cb(mmu_audit, &audit_param_ops, &mmu_audit, 0644); | 299 | arch_param_cb(mmu_audit, &audit_param_ops, &mmu_audit, 0644); |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 662f34c3287e..a0aa84b5941a 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -1615,8 +1615,9 @@ EXPORT_SYMBOL_GPL(kvm_read_guest_cached); | |||
1615 | 1615 | ||
1616 | int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len) | 1616 | int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len) |
1617 | { | 1617 | { |
1618 | return kvm_write_guest_page(kvm, gfn, (const void *) empty_zero_page, | 1618 | const void *zero_page = (const void *) __va(page_to_phys(ZERO_PAGE(0))); |
1619 | offset, len); | 1619 | |
1620 | return kvm_write_guest_page(kvm, gfn, zero_page, offset, len); | ||
1620 | } | 1621 | } |
1621 | EXPORT_SYMBOL_GPL(kvm_clear_guest_page); | 1622 | EXPORT_SYMBOL_GPL(kvm_clear_guest_page); |
1622 | 1623 | ||