aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/kvm_main.c
diff options
context:
space:
mode:
authorIzik Eidus <izike@qumranet.com>2007-10-24 17:57:46 -0400
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:52:56 -0500
commite0d62c7f48605119a7f9fa632e77561c89928963 (patch)
treeeb11b29780f12433897a720a7c9db719663152cf /drivers/kvm/kvm_main.c
parent210c7c4d7f200f00ec34960a8c96bb990cbd266d (diff)
KVM: Add kernel-internal memory slots
Reserve a few memory slots for kernel internal use. This is good for case you have to register memory region and you want to be sure it was not registered from userspace, and for case you want to register a memory region that won't be seen from userspace. Signed-off-by: Izik Eidus <izike@qumranet.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r--drivers/kvm/kvm_main.c22
1 files changed, 21 insertions, 1 deletions
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);