aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm')
-rw-r--r--drivers/kvm/kvm.h6
-rw-r--r--drivers/kvm/kvm_main.c22
2 files changed, 26 insertions, 2 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index f3dda088e34b..82c3b13e5d0a 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -41,6 +41,8 @@
41#define KVM_MAX_VCPUS 4 41#define KVM_MAX_VCPUS 4
42#define KVM_ALIAS_SLOTS 4 42#define KVM_ALIAS_SLOTS 4
43#define KVM_MEMORY_SLOTS 8 43#define KVM_MEMORY_SLOTS 8
44/* memory slots that does not exposed to userspace */
45#define KVM_PRIVATE_MEM_SLOTS 4
44#define KVM_PERMILLE_MMU_PAGES 20 46#define KVM_PERMILLE_MMU_PAGES 20
45#define KVM_MIN_ALLOC_MMU_PAGES 64 47#define KVM_MIN_ALLOC_MMU_PAGES 64
46#define KVM_NUM_MMU_PAGES 1024 48#define KVM_NUM_MMU_PAGES 1024
@@ -361,7 +363,8 @@ struct kvm {
361 int naliases; 363 int naliases;
362 struct kvm_mem_alias aliases[KVM_ALIAS_SLOTS]; 364 struct kvm_mem_alias aliases[KVM_ALIAS_SLOTS];
363 int nmemslots; 365 int nmemslots;
364 struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS]; 366 struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS +
367 KVM_PRIVATE_MEM_SLOTS];
365 /* 368 /*
366 * Hash table of struct kvm_mmu_page. 369 * Hash table of struct kvm_mmu_page.
367 */ 370 */
@@ -529,6 +532,7 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data,
529int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len); 532int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len);
530int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len); 533int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len);
531struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn); 534struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn);
535int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn);
532void mark_page_dirty(struct kvm *kvm, gfn_t gfn); 536void mark_page_dirty(struct kvm *kvm, gfn_t gfn);
533 537
534enum emulation_result { 538enum emulation_result {
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 5113cbf75674..a044856bd02b 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -660,7 +660,7 @@ int kvm_set_memory_region(struct kvm *kvm,
660 goto out; 660 goto out;
661 if (mem->guest_phys_addr & (PAGE_SIZE - 1)) 661 if (mem->guest_phys_addr & (PAGE_SIZE - 1))
662 goto out; 662 goto out;
663 if (mem->slot >= KVM_MEMORY_SLOTS) 663 if (mem->slot >= KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS)
664 goto out; 664 goto out;
665 if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr) 665 if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr)
666 goto out; 666 goto out;
@@ -797,6 +797,8 @@ static int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
797 kvm_userspace_memory_region *mem, 797 kvm_userspace_memory_region *mem,
798 int user_alloc) 798 int user_alloc)
799{ 799{
800 if (mem->slot >= KVM_MEMORY_SLOTS)
801 return -EINVAL;
800 return kvm_set_memory_region(kvm, mem, user_alloc); 802 return kvm_set_memory_region(kvm, mem, user_alloc);
801} 803}
802 804
@@ -1010,6 +1012,22 @@ struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
1010 return __gfn_to_memslot(kvm, gfn); 1012 return __gfn_to_memslot(kvm, gfn);
1011} 1013}
1012 1014
1015int kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn)
1016{
1017 int i;
1018
1019 gfn = unalias_gfn(kvm, gfn);
1020 for (i = 0; i < KVM_MEMORY_SLOTS; ++i) {
1021 struct kvm_memory_slot *memslot = &kvm->memslots[i];
1022
1023 if (gfn >= memslot->base_gfn
1024 && gfn < memslot->base_gfn + memslot->npages)
1025 return 1;
1026 }
1027 return 0;
1028}
1029EXPORT_SYMBOL_GPL(kvm_is_visible_gfn);
1030
1013struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn) 1031struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
1014{ 1032{
1015 struct kvm_memory_slot *slot; 1033 struct kvm_memory_slot *slot;
@@ -3087,6 +3105,8 @@ static struct page *kvm_vm_nopage(struct vm_area_struct *vma,
3087 struct page *page; 3105 struct page *page;
3088 3106
3089 pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; 3107 pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
3108 if (!kvm_is_visible_gfn(kvm, pgoff))
3109 return NOPAGE_SIGBUS;
3090 page = gfn_to_page(kvm, pgoff); 3110 page = gfn_to_page(kvm, pgoff);
3091 if (is_error_page(page)) { 3111 if (is_error_page(page)) {
3092 kvm_release_page(page); 3112 kvm_release_page(page);