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>
This commit is contained in:
committed by
Avi Kivity
parent
604b38ac03
commit
e930bffe95
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/mmu_notifier.h>
|
||||
|
||||
#include <linux/kvm.h>
|
||||
#include <linux/kvm_para.h>
|
||||
@@ -251,6 +252,7 @@ struct kvm_vcpu_arch {
|
||||
gfn_t gfn; /* presumed gfn during guest pte update */
|
||||
pfn_t pfn; /* pfn corresponding to that gfn */
|
||||
int largepage;
|
||||
unsigned long mmu_seq;
|
||||
} update_pte;
|
||||
|
||||
struct i387_fxsave_struct host_fx_image;
|
||||
@@ -729,4 +731,8 @@ asmlinkage void kvm_handle_fault_on_reboot(void);
|
||||
KVM_EX_ENTRY " 666b, 667b \n\t" \
|
||||
".popsection"
|
||||
|
||||
#define KVM_ARCH_WANT_MMU_NOTIFIER
|
||||
int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
|
||||
int kvm_age_hva(struct kvm *kvm, unsigned long hva);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -121,6 +121,12 @@ struct kvm {
|
||||
struct kvm_coalesced_mmio_dev *coalesced_mmio_dev;
|
||||
struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
|
||||
#endif
|
||||
|
||||
#ifdef KVM_ARCH_WANT_MMU_NOTIFIER
|
||||
struct mmu_notifier mmu_notifier;
|
||||
unsigned long mmu_notifier_seq;
|
||||
long mmu_notifier_count;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* The guest did something we don't support. */
|
||||
@@ -332,4 +338,22 @@ int kvm_trace_ioctl(unsigned int ioctl, unsigned long arg)
|
||||
#define kvm_trace_cleanup() ((void)0)
|
||||
#endif
|
||||
|
||||
#ifdef KVM_ARCH_WANT_MMU_NOTIFIER
|
||||
static inline int mmu_notifier_retry(struct kvm_vcpu *vcpu, unsigned long mmu_seq)
|
||||
{
|
||||
if (unlikely(vcpu->kvm->mmu_notifier_count))
|
||||
return 1;
|
||||
/*
|
||||
* Both reads happen under the mmu_lock and both values are
|
||||
* modified under mmu_lock, so there's no need of smb_rmb()
|
||||
* here in between, otherwise mmu_notifier_count should be
|
||||
* read before mmu_notifier_seq, see
|
||||
* mmu_notifier_invalidate_range_end write side.
|
||||
*/
|
||||
if (vcpu->kvm->mmu_notifier_seq != mmu_seq)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user