diff options
author | Yang Zhang <yang.z.zhang@Intel.com> | 2013-10-23 21:56:39 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2013-10-28 08:15:01 -0400 |
commit | e0230e1327fb862c9b6cde24ae62d55f9db62c9b (patch) | |
tree | 9579c57cd5b9f886fe6a8d1400d87560ec28d646 /virt | |
parent | a294c9bbd0dd0dea415a0ee5b8ee9c07f65f5496 (diff) |
KVM: Mapping IOMMU pages after updating memslot
In kvm_iommu_map_pages(), we need to know the page size via call
kvm_host_page_size(). And it will check whether the target slot
is valid before return the right page size.
Currently, we will map the iommu pages when creating a new slot.
But we call kvm_iommu_map_pages() during preparing the new slot.
At that time, the new slot is not visible by domain(still in preparing).
So we cannot get the right page size from kvm_host_page_size() and
this will break the IOMMU super page logic.
The solution is to map the iommu pages after we insert the new slot
into domain.
Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
Tested-by: Patrick Lu <patrick.lu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/kvm_main.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 0d20c320a33d..9ca014da134d 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -873,21 +873,6 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
873 | goto out_free; | 873 | goto out_free; |
874 | } | 874 | } |
875 | 875 | ||
876 | /* | ||
877 | * IOMMU mapping: New slots need to be mapped. Old slots need to be | ||
878 | * un-mapped and re-mapped if their base changes. Since base change | ||
879 | * unmapping is handled above with slot deletion, mapping alone is | ||
880 | * needed here. Anything else the iommu might care about for existing | ||
881 | * slots (size changes, userspace addr changes and read-only flag | ||
882 | * changes) is disallowed above, so any other attribute changes getting | ||
883 | * here can be skipped. | ||
884 | */ | ||
885 | if ((change == KVM_MR_CREATE) || (change == KVM_MR_MOVE)) { | ||
886 | r = kvm_iommu_map_pages(kvm, &new); | ||
887 | if (r) | ||
888 | goto out_slots; | ||
889 | } | ||
890 | |||
891 | /* actual memory is freed via old in kvm_free_physmem_slot below */ | 876 | /* actual memory is freed via old in kvm_free_physmem_slot below */ |
892 | if (change == KVM_MR_DELETE) { | 877 | if (change == KVM_MR_DELETE) { |
893 | new.dirty_bitmap = NULL; | 878 | new.dirty_bitmap = NULL; |
@@ -901,6 +886,20 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
901 | kvm_free_physmem_slot(&old, &new); | 886 | kvm_free_physmem_slot(&old, &new); |
902 | kfree(old_memslots); | 887 | kfree(old_memslots); |
903 | 888 | ||
889 | /* | ||
890 | * IOMMU mapping: New slots need to be mapped. Old slots need to be | ||
891 | * un-mapped and re-mapped if their base changes. Since base change | ||
892 | * unmapping is handled above with slot deletion, mapping alone is | ||
893 | * needed here. Anything else the iommu might care about for existing | ||
894 | * slots (size changes, userspace addr changes and read-only flag | ||
895 | * changes) is disallowed above, so any other attribute changes getting | ||
896 | * here can be skipped. | ||
897 | */ | ||
898 | if ((change == KVM_MR_CREATE) || (change == KVM_MR_MOVE)) { | ||
899 | r = kvm_iommu_map_pages(kvm, &new); | ||
900 | return r; | ||
901 | } | ||
902 | |||
904 | return 0; | 903 | return 0; |
905 | 904 | ||
906 | out_slots: | 905 | out_slots: |