diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ia64/include/asm/kvm_host.h | 3 | ||||
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 10 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kvm_host.h | 3 | ||||
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 10 | ||||
-rw-r--r-- | arch/s390/include/asm/kvm_host.h | 3 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 10 | ||||
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 9 | ||||
-rw-r--r-- | arch/x86/kvm/mmu.c | 2 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 59 |
9 files changed, 108 insertions, 1 deletions
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h index 2689ee54a1c9..e35b3a84a40b 100644 --- a/arch/ia64/include/asm/kvm_host.h +++ b/arch/ia64/include/asm/kvm_host.h | |||
@@ -459,6 +459,9 @@ struct kvm_sal_data { | |||
459 | unsigned long boot_gp; | 459 | unsigned long boot_gp; |
460 | }; | 460 | }; |
461 | 461 | ||
462 | struct kvm_arch_memory_slot { | ||
463 | }; | ||
464 | |||
462 | struct kvm_arch { | 465 | struct kvm_arch { |
463 | spinlock_t dirty_log_lock; | 466 | spinlock_t dirty_log_lock; |
464 | 467 | ||
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 8ca7261e7b3d..d8ddbba6fe7d 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -1571,6 +1571,16 @@ int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) | |||
1571 | return VM_FAULT_SIGBUS; | 1571 | return VM_FAULT_SIGBUS; |
1572 | } | 1572 | } |
1573 | 1573 | ||
1574 | void kvm_arch_free_memslot(struct kvm_memory_slot *free, | ||
1575 | struct kvm_memory_slot *dont) | ||
1576 | { | ||
1577 | } | ||
1578 | |||
1579 | int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) | ||
1580 | { | ||
1581 | return 0; | ||
1582 | } | ||
1583 | |||
1574 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 1584 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
1575 | struct kvm_memory_slot *memslot, | 1585 | struct kvm_memory_slot *memslot, |
1576 | struct kvm_memory_slot old, | 1586 | struct kvm_memory_slot old, |
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 1843d5d2a3be..52eb9c1f4fe0 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
@@ -213,6 +213,9 @@ struct revmap_entry { | |||
213 | #define KVMPPC_PAGE_WRITETHRU HPTE_R_W /* 0x40 */ | 213 | #define KVMPPC_PAGE_WRITETHRU HPTE_R_W /* 0x40 */ |
214 | #define KVMPPC_GOT_PAGE 0x80 | 214 | #define KVMPPC_GOT_PAGE 0x80 |
215 | 215 | ||
216 | struct kvm_arch_memory_slot { | ||
217 | }; | ||
218 | |||
216 | struct kvm_arch { | 219 | struct kvm_arch { |
217 | #ifdef CONFIG_KVM_BOOK3S_64_HV | 220 | #ifdef CONFIG_KVM_BOOK3S_64_HV |
218 | unsigned long hpt_virt; | 221 | unsigned long hpt_virt; |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 0e21d155eea7..00d7e345b3fe 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -281,6 +281,16 @@ long kvm_arch_dev_ioctl(struct file *filp, | |||
281 | return -EINVAL; | 281 | return -EINVAL; |
282 | } | 282 | } |
283 | 283 | ||
284 | void kvm_arch_free_memslot(struct kvm_memory_slot *free, | ||
285 | struct kvm_memory_slot *dont) | ||
286 | { | ||
287 | } | ||
288 | |||
289 | int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) | ||
290 | { | ||
291 | return 0; | ||
292 | } | ||
293 | |||
284 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 294 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
285 | struct kvm_memory_slot *memslot, | 295 | struct kvm_memory_slot *memslot, |
286 | struct kvm_memory_slot old, | 296 | struct kvm_memory_slot old, |
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index e6304268ea28..7343872890a2 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
@@ -245,6 +245,9 @@ struct kvm_vm_stat { | |||
245 | u32 remote_tlb_flush; | 245 | u32 remote_tlb_flush; |
246 | }; | 246 | }; |
247 | 247 | ||
248 | struct kvm_arch_memory_slot { | ||
249 | }; | ||
250 | |||
248 | struct kvm_arch{ | 251 | struct kvm_arch{ |
249 | struct sca_block *sca; | 252 | struct sca_block *sca; |
250 | debug_info_t *dbf; | 253 | debug_info_t *dbf; |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index cf3c0a91d046..17ad69d596fd 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -814,6 +814,16 @@ int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf) | |||
814 | return VM_FAULT_SIGBUS; | 814 | return VM_FAULT_SIGBUS; |
815 | } | 815 | } |
816 | 816 | ||
817 | void kvm_arch_free_memslot(struct kvm_memory_slot *free, | ||
818 | struct kvm_memory_slot *dont) | ||
819 | { | ||
820 | } | ||
821 | |||
822 | int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) | ||
823 | { | ||
824 | return 0; | ||
825 | } | ||
826 | |||
817 | /* Section: memory related */ | 827 | /* Section: memory related */ |
818 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 828 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
819 | struct kvm_memory_slot *memslot, | 829 | struct kvm_memory_slot *memslot, |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index c24125cd0c63..74c9edf2bb18 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -483,6 +483,15 @@ struct kvm_vcpu_arch { | |||
483 | } osvw; | 483 | } osvw; |
484 | }; | 484 | }; |
485 | 485 | ||
486 | struct kvm_lpage_info { | ||
487 | unsigned long rmap_pde; | ||
488 | int write_count; | ||
489 | }; | ||
490 | |||
491 | struct kvm_arch_memory_slot { | ||
492 | struct kvm_lpage_info *lpage_info[KVM_NR_PAGE_SIZES - 1]; | ||
493 | }; | ||
494 | |||
486 | struct kvm_arch { | 495 | struct kvm_arch { |
487 | unsigned int n_used_mmu_pages; | 496 | unsigned int n_used_mmu_pages; |
488 | unsigned int n_requested_mmu_pages; | 497 | unsigned int n_requested_mmu_pages; |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 37e7f100a0e0..ff053ca32303 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -689,7 +689,7 @@ static struct kvm_lpage_info *lpage_info_slot(gfn_t gfn, | |||
689 | unsigned long idx; | 689 | unsigned long idx; |
690 | 690 | ||
691 | idx = gfn_to_index(gfn, slot->base_gfn, level); | 691 | idx = gfn_to_index(gfn, slot->base_gfn, level); |
692 | return &slot->lpage_info[level - 2][idx]; | 692 | return &slot->arch.lpage_info[level - 2][idx]; |
693 | } | 693 | } |
694 | 694 | ||
695 | static void account_shadowed(struct kvm *kvm, gfn_t gfn) | 695 | static void account_shadowed(struct kvm *kvm, gfn_t gfn) |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 3df0b7a140b0..ca74c1dadf3a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -6239,6 +6239,65 @@ void kvm_arch_destroy_vm(struct kvm *kvm) | |||
6239 | put_page(kvm->arch.ept_identity_pagetable); | 6239 | put_page(kvm->arch.ept_identity_pagetable); |
6240 | } | 6240 | } |
6241 | 6241 | ||
6242 | void kvm_arch_free_memslot(struct kvm_memory_slot *free, | ||
6243 | struct kvm_memory_slot *dont) | ||
6244 | { | ||
6245 | int i; | ||
6246 | |||
6247 | for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) { | ||
6248 | if (!dont || free->arch.lpage_info[i] != dont->arch.lpage_info[i]) { | ||
6249 | vfree(free->arch.lpage_info[i]); | ||
6250 | free->arch.lpage_info[i] = NULL; | ||
6251 | } | ||
6252 | } | ||
6253 | } | ||
6254 | |||
6255 | int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) | ||
6256 | { | ||
6257 | int i; | ||
6258 | |||
6259 | for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) { | ||
6260 | unsigned long ugfn; | ||
6261 | int lpages; | ||
6262 | int level = i + 2; | ||
6263 | |||
6264 | lpages = gfn_to_index(slot->base_gfn + npages - 1, | ||
6265 | slot->base_gfn, level) + 1; | ||
6266 | |||
6267 | slot->arch.lpage_info[i] = | ||
6268 | vzalloc(lpages * sizeof(*slot->arch.lpage_info[i])); | ||
6269 | if (!slot->arch.lpage_info[i]) | ||
6270 | goto out_free; | ||
6271 | |||
6272 | if (slot->base_gfn & (KVM_PAGES_PER_HPAGE(level) - 1)) | ||
6273 | slot->arch.lpage_info[i][0].write_count = 1; | ||
6274 | if ((slot->base_gfn + npages) & (KVM_PAGES_PER_HPAGE(level) - 1)) | ||
6275 | slot->arch.lpage_info[i][lpages - 1].write_count = 1; | ||
6276 | ugfn = slot->userspace_addr >> PAGE_SHIFT; | ||
6277 | /* | ||
6278 | * If the gfn and userspace address are not aligned wrt each | ||
6279 | * other, or if explicitly asked to, disable large page | ||
6280 | * support for this slot | ||
6281 | */ | ||
6282 | if ((slot->base_gfn ^ ugfn) & (KVM_PAGES_PER_HPAGE(level) - 1) || | ||
6283 | !kvm_largepages_enabled()) { | ||
6284 | unsigned long j; | ||
6285 | |||
6286 | for (j = 0; j < lpages; ++j) | ||
6287 | slot->arch.lpage_info[i][j].write_count = 1; | ||
6288 | } | ||
6289 | } | ||
6290 | |||
6291 | return 0; | ||
6292 | |||
6293 | out_free: | ||
6294 | for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) { | ||
6295 | vfree(slot->arch.lpage_info[i]); | ||
6296 | slot->arch.lpage_info[i] = NULL; | ||
6297 | } | ||
6298 | return -ENOMEM; | ||
6299 | } | ||
6300 | |||
6242 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 6301 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
6243 | struct kvm_memory_slot *memslot, | 6302 | struct kvm_memory_slot *memslot, |
6244 | struct kvm_memory_slot old, | 6303 | struct kvm_memory_slot old, |