aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/kvm/kvm.h9
-rw-r--r--drivers/kvm/kvm_main.c89
-rw-r--r--include/linux/kvm.h10
3 files changed, 104 insertions, 4 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index d19985a5508a..fceeb840a255 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -51,6 +51,7 @@
51#define UNMAPPED_GVA (~(gpa_t)0) 51#define UNMAPPED_GVA (~(gpa_t)0)
52 52
53#define KVM_MAX_VCPUS 1 53#define KVM_MAX_VCPUS 1
54#define KVM_ALIAS_SLOTS 4
54#define KVM_MEMORY_SLOTS 4 55#define KVM_MEMORY_SLOTS 4
55#define KVM_NUM_MMU_PAGES 256 56#define KVM_NUM_MMU_PAGES 256
56#define KVM_MIN_FREE_MMU_PAGES 5 57#define KVM_MIN_FREE_MMU_PAGES 5
@@ -312,6 +313,12 @@ struct kvm_vcpu {
312 struct kvm_cpuid_entry cpuid_entries[KVM_MAX_CPUID_ENTRIES]; 313 struct kvm_cpuid_entry cpuid_entries[KVM_MAX_CPUID_ENTRIES];
313}; 314};
314 315
316struct kvm_mem_alias {
317 gfn_t base_gfn;
318 unsigned long npages;
319 gfn_t target_gfn;
320};
321
315struct kvm_memory_slot { 322struct kvm_memory_slot {
316 gfn_t base_gfn; 323 gfn_t base_gfn;
317 unsigned long npages; 324 unsigned long npages;
@@ -322,6 +329,8 @@ struct kvm_memory_slot {
322 329
323struct kvm { 330struct kvm {
324 spinlock_t lock; /* protects everything except vcpus */ 331 spinlock_t lock; /* protects everything except vcpus */
332 int naliases;
333 struct kvm_mem_alias aliases[KVM_ALIAS_SLOTS];
325 int nmemslots; 334 int nmemslots;
326 struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS]; 335 struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS];
327 /* 336 /*
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index a0ec5dda3305..e495855727e2 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -846,7 +846,73 @@ out:
846 return r; 846 return r;
847} 847}
848 848
849struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn) 849/*
850 * Set a new alias region. Aliases map a portion of physical memory into
851 * another portion. This is useful for memory windows, for example the PC
852 * VGA region.
853 */
854static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm,
855 struct kvm_memory_alias *alias)
856{
857 int r, n;
858 struct kvm_mem_alias *p;
859
860 r = -EINVAL;
861 /* General sanity checks */
862 if (alias->memory_size & (PAGE_SIZE - 1))
863 goto out;
864 if (alias->guest_phys_addr & (PAGE_SIZE - 1))
865 goto out;
866 if (alias->slot >= KVM_ALIAS_SLOTS)
867 goto out;
868 if (alias->guest_phys_addr + alias->memory_size
869 < alias->guest_phys_addr)
870 goto out;
871 if (alias->target_phys_addr + alias->memory_size
872 < alias->target_phys_addr)
873 goto out;
874
875 spin_lock(&kvm->lock);
876
877 p = &kvm->aliases[alias->slot];
878 p->base_gfn = alias->guest_phys_addr >> PAGE_SHIFT;
879 p->npages = alias->memory_size >> PAGE_SHIFT;
880 p->target_gfn = alias->target_phys_addr >> PAGE_SHIFT;
881
882 for (n = KVM_ALIAS_SLOTS; n > 0; --n)
883 if (kvm->aliases[n - 1].npages)
884 break;
885 kvm->naliases = n;
886
887 spin_unlock(&kvm->lock);
888
889 vcpu_load(&kvm->vcpus[0]);
890 spin_lock(&kvm->lock);
891 kvm_mmu_zap_all(&kvm->vcpus[0]);
892 spin_unlock(&kvm->lock);
893 vcpu_put(&kvm->vcpus[0]);
894
895 return 0;
896
897out:
898 return r;
899}
900
901static gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
902{
903 int i;
904 struct kvm_mem_alias *alias;
905
906 for (i = 0; i < kvm->naliases; ++i) {
907 alias = &kvm->aliases[i];
908 if (gfn >= alias->base_gfn
909 && gfn < alias->base_gfn + alias->npages)
910 return alias->target_gfn + gfn - alias->base_gfn;
911 }
912 return gfn;
913}
914
915static struct kvm_memory_slot *__gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
850{ 916{
851 int i; 917 int i;
852 918
@@ -859,13 +925,19 @@ struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
859 } 925 }
860 return NULL; 926 return NULL;
861} 927}
862EXPORT_SYMBOL_GPL(gfn_to_memslot); 928
929struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
930{
931 gfn = unalias_gfn(kvm, gfn);
932 return __gfn_to_memslot(kvm, gfn);
933}
863 934
864struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn) 935struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
865{ 936{
866 struct kvm_memory_slot *slot; 937 struct kvm_memory_slot *slot;
867 938
868 slot = gfn_to_memslot(kvm, gfn); 939 gfn = unalias_gfn(kvm, gfn);
940 slot = __gfn_to_memslot(kvm, gfn);
869 if (!slot) 941 if (!slot)
870 return NULL; 942 return NULL;
871 return slot->phys_mem[gfn - slot->base_gfn]; 943 return slot->phys_mem[gfn - slot->base_gfn];
@@ -2512,6 +2584,17 @@ static long kvm_vm_ioctl(struct file *filp,
2512 goto out; 2584 goto out;
2513 break; 2585 break;
2514 } 2586 }
2587 case KVM_SET_MEMORY_ALIAS: {
2588 struct kvm_memory_alias alias;
2589
2590 r = -EFAULT;
2591 if (copy_from_user(&alias, argp, sizeof alias))
2592 goto out;
2593 r = kvm_vm_ioctl_set_memory_alias(kvm, &alias);
2594 if (r)
2595 goto out;
2596 break;
2597 }
2515 default: 2598 default:
2516 ; 2599 ;
2517 } 2600 }
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 728b24cf5d77..da9b23fa4b6c 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -11,7 +11,7 @@
11#include <asm/types.h> 11#include <asm/types.h>
12#include <linux/ioctl.h> 12#include <linux/ioctl.h>
13 13
14#define KVM_API_VERSION 9 14#define KVM_API_VERSION 10
15 15
16/* 16/*
17 * Architectural interrupt line count, and the size of the bitmap needed 17 * Architectural interrupt line count, and the size of the bitmap needed
@@ -33,6 +33,13 @@ struct kvm_memory_region {
33/* for kvm_memory_region::flags */ 33/* for kvm_memory_region::flags */
34#define KVM_MEM_LOG_DIRTY_PAGES 1UL 34#define KVM_MEM_LOG_DIRTY_PAGES 1UL
35 35
36struct kvm_memory_alias {
37 __u32 slot; /* this has a different namespace than memory slots */
38 __u32 flags;
39 __u64 guest_phys_addr;
40 __u64 memory_size;
41 __u64 target_phys_addr;
42};
36 43
37enum kvm_exit_reason { 44enum kvm_exit_reason {
38 KVM_EXIT_UNKNOWN = 0, 45 KVM_EXIT_UNKNOWN = 0,
@@ -261,6 +268,7 @@ struct kvm_signal_mask {
261 */ 268 */
262#define KVM_CREATE_VCPU _IO(KVMIO, 0x41) 269#define KVM_CREATE_VCPU _IO(KVMIO, 0x41)
263#define KVM_GET_DIRTY_LOG _IOW(KVMIO, 0x42, struct kvm_dirty_log) 270#define KVM_GET_DIRTY_LOG _IOW(KVMIO, 0x42, struct kvm_dirty_log)
271#define KVM_SET_MEMORY_ALIAS _IOW(KVMIO, 0x43, struct kvm_memory_alias)
264 272
265/* 273/*
266 * ioctls for vcpu fds 274 * ioctls for vcpu fds