diff options
Diffstat (limited to 'arch/arm/kvm/mmu.c')
-rw-r--r-- | arch/arm/kvm/mmu.c | 99 |
1 files changed, 92 insertions, 7 deletions
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 57a403a5c22b..3756dd3e85c2 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
@@ -611,6 +611,71 @@ static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size) | |||
611 | unmap_range(kvm, kvm->arch.pgd, start, size); | 611 | unmap_range(kvm, kvm->arch.pgd, start, size); |
612 | } | 612 | } |
613 | 613 | ||
614 | static void stage2_unmap_memslot(struct kvm *kvm, | ||
615 | struct kvm_memory_slot *memslot) | ||
616 | { | ||
617 | hva_t hva = memslot->userspace_addr; | ||
618 | phys_addr_t addr = memslot->base_gfn << PAGE_SHIFT; | ||
619 | phys_addr_t size = PAGE_SIZE * memslot->npages; | ||
620 | hva_t reg_end = hva + size; | ||
621 | |||
622 | /* | ||
623 | * A memory region could potentially cover multiple VMAs, and any holes | ||
624 | * between them, so iterate over all of them to find out if we should | ||
625 | * unmap any of them. | ||
626 | * | ||
627 | * +--------------------------------------------+ | ||
628 | * +---------------+----------------+ +----------------+ | ||
629 | * | : VMA 1 | VMA 2 | | VMA 3 : | | ||
630 | * +---------------+----------------+ +----------------+ | ||
631 | * | memory region | | ||
632 | * +--------------------------------------------+ | ||
633 | */ | ||
634 | do { | ||
635 | struct vm_area_struct *vma = find_vma(current->mm, hva); | ||
636 | hva_t vm_start, vm_end; | ||
637 | |||
638 | if (!vma || vma->vm_start >= reg_end) | ||
639 | break; | ||
640 | |||
641 | /* | ||
642 | * Take the intersection of this VMA with the memory region | ||
643 | */ | ||
644 | vm_start = max(hva, vma->vm_start); | ||
645 | vm_end = min(reg_end, vma->vm_end); | ||
646 | |||
647 | if (!(vma->vm_flags & VM_PFNMAP)) { | ||
648 | gpa_t gpa = addr + (vm_start - memslot->userspace_addr); | ||
649 | unmap_stage2_range(kvm, gpa, vm_end - vm_start); | ||
650 | } | ||
651 | hva = vm_end; | ||
652 | } while (hva < reg_end); | ||
653 | } | ||
654 | |||
655 | /** | ||
656 | * stage2_unmap_vm - Unmap Stage-2 RAM mappings | ||
657 | * @kvm: The struct kvm pointer | ||
658 | * | ||
659 | * Go through the memregions and unmap any reguler RAM | ||
660 | * backing memory already mapped to the VM. | ||
661 | */ | ||
662 | void stage2_unmap_vm(struct kvm *kvm) | ||
663 | { | ||
664 | struct kvm_memslots *slots; | ||
665 | struct kvm_memory_slot *memslot; | ||
666 | int idx; | ||
667 | |||
668 | idx = srcu_read_lock(&kvm->srcu); | ||
669 | spin_lock(&kvm->mmu_lock); | ||
670 | |||
671 | slots = kvm_memslots(kvm); | ||
672 | kvm_for_each_memslot(memslot, slots) | ||
673 | stage2_unmap_memslot(kvm, memslot); | ||
674 | |||
675 | spin_unlock(&kvm->mmu_lock); | ||
676 | srcu_read_unlock(&kvm->srcu, idx); | ||
677 | } | ||
678 | |||
614 | /** | 679 | /** |
615 | * kvm_free_stage2_pgd - free all stage-2 tables | 680 | * kvm_free_stage2_pgd - free all stage-2 tables |
616 | * @kvm: The KVM struct pointer for the VM. | 681 | * @kvm: The KVM struct pointer for the VM. |
@@ -834,6 +899,11 @@ static bool kvm_is_write_fault(struct kvm_vcpu *vcpu) | |||
834 | return kvm_vcpu_dabt_iswrite(vcpu); | 899 | return kvm_vcpu_dabt_iswrite(vcpu); |
835 | } | 900 | } |
836 | 901 | ||
902 | static bool kvm_is_device_pfn(unsigned long pfn) | ||
903 | { | ||
904 | return !pfn_valid(pfn); | ||
905 | } | ||
906 | |||
837 | static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | 907 | static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, |
838 | struct kvm_memory_slot *memslot, unsigned long hva, | 908 | struct kvm_memory_slot *memslot, unsigned long hva, |
839 | unsigned long fault_status) | 909 | unsigned long fault_status) |
@@ -847,6 +917,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
847 | struct vm_area_struct *vma; | 917 | struct vm_area_struct *vma; |
848 | pfn_t pfn; | 918 | pfn_t pfn; |
849 | pgprot_t mem_type = PAGE_S2; | 919 | pgprot_t mem_type = PAGE_S2; |
920 | bool fault_ipa_uncached; | ||
850 | 921 | ||
851 | write_fault = kvm_is_write_fault(vcpu); | 922 | write_fault = kvm_is_write_fault(vcpu); |
852 | if (fault_status == FSC_PERM && !write_fault) { | 923 | if (fault_status == FSC_PERM && !write_fault) { |
@@ -904,7 +975,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
904 | if (is_error_pfn(pfn)) | 975 | if (is_error_pfn(pfn)) |
905 | return -EFAULT; | 976 | return -EFAULT; |
906 | 977 | ||
907 | if (kvm_is_mmio_pfn(pfn)) | 978 | if (kvm_is_device_pfn(pfn)) |
908 | mem_type = PAGE_S2_DEVICE; | 979 | mem_type = PAGE_S2_DEVICE; |
909 | 980 | ||
910 | spin_lock(&kvm->mmu_lock); | 981 | spin_lock(&kvm->mmu_lock); |
@@ -913,6 +984,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
913 | if (!hugetlb && !force_pte) | 984 | if (!hugetlb && !force_pte) |
914 | hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa); | 985 | hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa); |
915 | 986 | ||
987 | fault_ipa_uncached = memslot->flags & KVM_MEMSLOT_INCOHERENT; | ||
988 | |||
916 | if (hugetlb) { | 989 | if (hugetlb) { |
917 | pmd_t new_pmd = pfn_pmd(pfn, mem_type); | 990 | pmd_t new_pmd = pfn_pmd(pfn, mem_type); |
918 | new_pmd = pmd_mkhuge(new_pmd); | 991 | new_pmd = pmd_mkhuge(new_pmd); |
@@ -920,7 +993,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
920 | kvm_set_s2pmd_writable(&new_pmd); | 993 | kvm_set_s2pmd_writable(&new_pmd); |
921 | kvm_set_pfn_dirty(pfn); | 994 | kvm_set_pfn_dirty(pfn); |
922 | } | 995 | } |
923 | coherent_cache_guest_page(vcpu, hva & PMD_MASK, PMD_SIZE); | 996 | coherent_cache_guest_page(vcpu, hva & PMD_MASK, PMD_SIZE, |
997 | fault_ipa_uncached); | ||
924 | ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd); | 998 | ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd); |
925 | } else { | 999 | } else { |
926 | pte_t new_pte = pfn_pte(pfn, mem_type); | 1000 | pte_t new_pte = pfn_pte(pfn, mem_type); |
@@ -928,7 +1002,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | |||
928 | kvm_set_s2pte_writable(&new_pte); | 1002 | kvm_set_s2pte_writable(&new_pte); |
929 | kvm_set_pfn_dirty(pfn); | 1003 | kvm_set_pfn_dirty(pfn); |
930 | } | 1004 | } |
931 | coherent_cache_guest_page(vcpu, hva, PAGE_SIZE); | 1005 | coherent_cache_guest_page(vcpu, hva, PAGE_SIZE, |
1006 | fault_ipa_uncached); | ||
932 | ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, | 1007 | ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, |
933 | pgprot_val(mem_type) == pgprot_val(PAGE_S2_DEVICE)); | 1008 | pgprot_val(mem_type) == pgprot_val(PAGE_S2_DEVICE)); |
934 | } | 1009 | } |
@@ -1288,11 +1363,12 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, | |||
1288 | hva = vm_end; | 1363 | hva = vm_end; |
1289 | } while (hva < reg_end); | 1364 | } while (hva < reg_end); |
1290 | 1365 | ||
1291 | if (ret) { | 1366 | spin_lock(&kvm->mmu_lock); |
1292 | spin_lock(&kvm->mmu_lock); | 1367 | if (ret) |
1293 | unmap_stage2_range(kvm, mem->guest_phys_addr, mem->memory_size); | 1368 | unmap_stage2_range(kvm, mem->guest_phys_addr, mem->memory_size); |
1294 | spin_unlock(&kvm->mmu_lock); | 1369 | else |
1295 | } | 1370 | stage2_flush_memslot(kvm, memslot); |
1371 | spin_unlock(&kvm->mmu_lock); | ||
1296 | return ret; | 1372 | return ret; |
1297 | } | 1373 | } |
1298 | 1374 | ||
@@ -1304,6 +1380,15 @@ void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *free, | |||
1304 | int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, | 1380 | int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, |
1305 | unsigned long npages) | 1381 | unsigned long npages) |
1306 | { | 1382 | { |
1383 | /* | ||
1384 | * Readonly memslots are not incoherent with the caches by definition, | ||
1385 | * but in practice, they are used mostly to emulate ROMs or NOR flashes | ||
1386 | * that the guest may consider devices and hence map as uncached. | ||
1387 | * To prevent incoherency issues in these cases, tag all readonly | ||
1388 | * regions as incoherent. | ||
1389 | */ | ||
1390 | if (slot->flags & KVM_MEM_READONLY) | ||
1391 | slot->flags |= KVM_MEMSLOT_INCOHERENT; | ||
1307 | return 0; | 1392 | return 0; |
1308 | } | 1393 | } |
1309 | 1394 | ||