diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2010-01-28 06:37:56 -0500 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2010-03-01 10:36:08 -0500 |
commit | 8f0b1ab6fb045a1324d9435ba00c2940783b0041 (patch) | |
tree | 34db9f9080cea014150249da16348ed3e3e01fc3 | |
parent | c45b4fd416f5497b6b38dd70acc0e5b01399e5c9 (diff) |
KVM: Introduce kvm_host_page_size
This patch introduces a generic function to find out the
host page size for a given gfn. This function is needed by
the kvm iommu code. This patch also simplifies the x86
host_mapping_level function.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | arch/x86/kvm/mmu.c | 18 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 1 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 25 |
3 files changed, 28 insertions, 16 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index dc4d954efacd..913ef4b7939a 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -468,24 +468,10 @@ static int has_wrprotected_page(struct kvm *kvm, | |||
468 | 468 | ||
469 | static int host_mapping_level(struct kvm *kvm, gfn_t gfn) | 469 | static int host_mapping_level(struct kvm *kvm, gfn_t gfn) |
470 | { | 470 | { |
471 | unsigned long page_size = PAGE_SIZE; | 471 | unsigned long page_size; |
472 | struct vm_area_struct *vma; | ||
473 | unsigned long addr; | ||
474 | int i, ret = 0; | 472 | int i, ret = 0; |
475 | 473 | ||
476 | addr = gfn_to_hva(kvm, gfn); | 474 | page_size = kvm_host_page_size(kvm, gfn); |
477 | if (kvm_is_error_hva(addr)) | ||
478 | return PT_PAGE_TABLE_LEVEL; | ||
479 | |||
480 | down_read(¤t->mm->mmap_sem); | ||
481 | vma = find_vma(current->mm, addr); | ||
482 | if (!vma) | ||
483 | goto out; | ||
484 | |||
485 | page_size = vma_kernel_pagesize(vma); | ||
486 | |||
487 | out: | ||
488 | up_read(¤t->mm->mmap_sem); | ||
489 | 475 | ||
490 | for (i = PT_PAGE_TABLE_LEVEL; | 476 | for (i = PT_PAGE_TABLE_LEVEL; |
491 | i < (PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES); ++i) { | 477 | i < (PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES); ++i) { |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 665c37063f30..3145b281de9d 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -300,6 +300,7 @@ int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len); | |||
300 | int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len); | 300 | int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len); |
301 | struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn); | 301 | struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn); |
302 | int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn); | 302 | int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn); |
303 | unsigned long kvm_host_page_size(struct kvm *kvm, gfn_t gfn); | ||
303 | void mark_page_dirty(struct kvm *kvm, gfn_t gfn); | 304 | void mark_page_dirty(struct kvm *kvm, gfn_t gfn); |
304 | 305 | ||
305 | void kvm_vcpu_block(struct kvm_vcpu *vcpu); | 306 | void kvm_vcpu_block(struct kvm_vcpu *vcpu); |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 2b0974a14835..0a360c26cc34 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/spinlock.h> | 45 | #include <linux/spinlock.h> |
46 | #include <linux/compat.h> | 46 | #include <linux/compat.h> |
47 | #include <linux/srcu.h> | 47 | #include <linux/srcu.h> |
48 | #include <linux/hugetlb.h> | ||
48 | 49 | ||
49 | #include <asm/processor.h> | 50 | #include <asm/processor.h> |
50 | #include <asm/io.h> | 51 | #include <asm/io.h> |
@@ -867,6 +868,30 @@ int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn) | |||
867 | } | 868 | } |
868 | EXPORT_SYMBOL_GPL(kvm_is_visible_gfn); | 869 | EXPORT_SYMBOL_GPL(kvm_is_visible_gfn); |
869 | 870 | ||
871 | unsigned long kvm_host_page_size(struct kvm *kvm, gfn_t gfn) | ||
872 | { | ||
873 | struct vm_area_struct *vma; | ||
874 | unsigned long addr, size; | ||
875 | |||
876 | size = PAGE_SIZE; | ||
877 | |||
878 | addr = gfn_to_hva(kvm, gfn); | ||
879 | if (kvm_is_error_hva(addr)) | ||
880 | return PAGE_SIZE; | ||
881 | |||
882 | down_read(¤t->mm->mmap_sem); | ||
883 | vma = find_vma(current->mm, addr); | ||
884 | if (!vma) | ||
885 | goto out; | ||
886 | |||
887 | size = vma_kernel_pagesize(vma); | ||
888 | |||
889 | out: | ||
890 | up_read(¤t->mm->mmap_sem); | ||
891 | |||
892 | return size; | ||
893 | } | ||
894 | |||
870 | int memslot_id(struct kvm *kvm, gfn_t gfn) | 895 | int memslot_id(struct kvm *kvm, gfn_t gfn) |
871 | { | 896 | { |
872 | int i; | 897 | int i; |