diff options
author | Andrea Arcangeli <andrea@qumranet.com> | 2008-07-25 10:24:52 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-07-29 05:33:53 -0400 |
commit | e930bffe95e1e886a1ede80726ea38df5838d067 (patch) | |
tree | d39227c3de8e7d4a70737c78693f6d7f458066af /include | |
parent | 604b38ac0369bd50fcbb33344aa5553c071009f7 (diff) |
KVM: Synchronize guest physical memory map to host virtual memory map
Synchronize changes to host virtual addresses which are part of
a KVM memory slot to the KVM shadow mmu. This allows pte operations
like swapping, page migration, and madvise() to transparently work
with KVM.
Signed-off-by: Andrea Arcangeli <andrea@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-x86/kvm_host.h | 6 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 24 |
2 files changed, 30 insertions, 0 deletions
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index bc34dc21f178..0f3c53114614 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/mmu_notifier.h> | ||
16 | 17 | ||
17 | #include <linux/kvm.h> | 18 | #include <linux/kvm.h> |
18 | #include <linux/kvm_para.h> | 19 | #include <linux/kvm_para.h> |
@@ -251,6 +252,7 @@ struct kvm_vcpu_arch { | |||
251 | gfn_t gfn; /* presumed gfn during guest pte update */ | 252 | gfn_t gfn; /* presumed gfn during guest pte update */ |
252 | pfn_t pfn; /* pfn corresponding to that gfn */ | 253 | pfn_t pfn; /* pfn corresponding to that gfn */ |
253 | int largepage; | 254 | int largepage; |
255 | unsigned long mmu_seq; | ||
254 | } update_pte; | 256 | } update_pte; |
255 | 257 | ||
256 | struct i387_fxsave_struct host_fx_image; | 258 | struct i387_fxsave_struct host_fx_image; |
@@ -729,4 +731,8 @@ asmlinkage void kvm_handle_fault_on_reboot(void); | |||
729 | KVM_EX_ENTRY " 666b, 667b \n\t" \ | 731 | KVM_EX_ENTRY " 666b, 667b \n\t" \ |
730 | ".popsection" | 732 | ".popsection" |
731 | 733 | ||
734 | #define KVM_ARCH_WANT_MMU_NOTIFIER | ||
735 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); | ||
736 | int kvm_age_hva(struct kvm *kvm, unsigned long hva); | ||
737 | |||
732 | #endif | 738 | #endif |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 07d68a8ae8e9..8525afc53107 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -121,6 +121,12 @@ struct kvm { | |||
121 | struct kvm_coalesced_mmio_dev *coalesced_mmio_dev; | 121 | struct kvm_coalesced_mmio_dev *coalesced_mmio_dev; |
122 | struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; | 122 | struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; |
123 | #endif | 123 | #endif |
124 | |||
125 | #ifdef KVM_ARCH_WANT_MMU_NOTIFIER | ||
126 | struct mmu_notifier mmu_notifier; | ||
127 | unsigned long mmu_notifier_seq; | ||
128 | long mmu_notifier_count; | ||
129 | #endif | ||
124 | }; | 130 | }; |
125 | 131 | ||
126 | /* The guest did something we don't support. */ | 132 | /* The guest did something we don't support. */ |
@@ -332,4 +338,22 @@ int kvm_trace_ioctl(unsigned int ioctl, unsigned long arg) | |||
332 | #define kvm_trace_cleanup() ((void)0) | 338 | #define kvm_trace_cleanup() ((void)0) |
333 | #endif | 339 | #endif |
334 | 340 | ||
341 | #ifdef KVM_ARCH_WANT_MMU_NOTIFIER | ||
342 | static inline int mmu_notifier_retry(struct kvm_vcpu *vcpu, unsigned long mmu_seq) | ||
343 | { | ||
344 | if (unlikely(vcpu->kvm->mmu_notifier_count)) | ||
345 | return 1; | ||
346 | /* | ||
347 | * Both reads happen under the mmu_lock and both values are | ||
348 | * modified under mmu_lock, so there's no need of smb_rmb() | ||
349 | * here in between, otherwise mmu_notifier_count should be | ||
350 | * read before mmu_notifier_seq, see | ||
351 | * mmu_notifier_invalidate_range_end write side. | ||
352 | */ | ||
353 | if (vcpu->kvm->mmu_notifier_seq != mmu_seq) | ||
354 | return 1; | ||
355 | return 0; | ||
356 | } | ||
357 | #endif | ||
358 | |||
335 | #endif | 359 | #endif |