#endif
#ifdef KVM_ARCH_WANT_MMU_NOTIFIER
-#ifdef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
struct kvm_gfn_range {
struct kvm_memory_slot *slot;
gfn_t start;
bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range);
bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range);
bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range);
-#else
-int kvm_unmap_hva_range(struct kvm *kvm,
- unsigned long start, unsigned long end, unsigned flags);
-int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
-int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
-int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
-#endif /* KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS */
#endif
enum {
srcu_read_unlock(&kvm->srcu, idx);
}
-#ifdef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
-
typedef bool (*hva_handler_t)(struct kvm *kvm, struct kvm_gfn_range *range);
struct kvm_hva_range {
return ret;
}
-#endif /* KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS */
-
static void kvm_mmu_notifier_change_pte(struct mmu_notifier *mn,
struct mm_struct *mm,
unsigned long address,
{
struct kvm *kvm = mmu_notifier_to_kvm(mn);
-#ifndef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
- int idx;
-#endif
trace_kvm_set_spte_hva(address);
/*
*/
WARN_ON_ONCE(!kvm->mmu_notifier_count);
-#ifdef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
kvm_handle_hva_range(mn, address, address + 1, pte, kvm_set_spte_gfn);
-#else
- idx = srcu_read_lock(&kvm->srcu);
-
- KVM_MMU_LOCK(kvm);
-
- if (kvm_set_spte_hva(kvm, address, pte))
- kvm_flush_remote_tlbs(kvm);
-
- KVM_MMU_UNLOCK(kvm);
- srcu_read_unlock(&kvm->srcu, idx);
-#endif
}
static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
const struct mmu_notifier_range *range)
{
struct kvm *kvm = mmu_notifier_to_kvm(mn);
-#ifdef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
const struct kvm_hva_range hva_range = {
.start = range->start,
.end = range->end,
.flush_on_ret = true,
.may_block = mmu_notifier_range_blockable(range),
};
-#else
- int need_tlb_flush = 0, idx;
-#endif
trace_kvm_unmap_hva_range(range->start, range->end);
-#ifndef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
- idx = srcu_read_lock(&kvm->srcu);
-#endif
-
KVM_MMU_LOCK(kvm);
/*
* The count increase must become visible at unlock time as no
max(kvm->mmu_notifier_range_end, range->end);
}
-#ifdef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
__kvm_handle_hva_range(kvm, &hva_range);
-#else
- need_tlb_flush = kvm_unmap_hva_range(kvm, range->start, range->end,
- range->flags);
- /* we've to flush the tlb before the pages can be freed */
- if (need_tlb_flush || kvm->tlbs_dirty)
- kvm_flush_remote_tlbs(kvm);
-#endif
KVM_MMU_UNLOCK(kvm);
-#ifndef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
- srcu_read_unlock(&kvm->srcu, idx);
-#endif
return 0;
}
unsigned long start,
unsigned long end)
{
-#ifndef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
- struct kvm *kvm = mmu_notifier_to_kvm(mn);
- int young, idx;
-#endif
trace_kvm_age_hva(start, end);
-#ifdef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
return kvm_handle_hva_range(mn, start, end, __pte(0), kvm_age_gfn);
-#else
- idx = srcu_read_lock(&kvm->srcu);
- KVM_MMU_LOCK(kvm);
-
- young = kvm_age_hva(kvm, start, end);
- if (young)
- kvm_flush_remote_tlbs(kvm);
-
- KVM_MMU_UNLOCK(kvm);
- srcu_read_unlock(&kvm->srcu, idx);
-
- return young;
-#endif
}
static int kvm_mmu_notifier_clear_young(struct mmu_notifier *mn,
unsigned long start,
unsigned long end)
{
-#ifndef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
- struct kvm *kvm = mmu_notifier_to_kvm(mn);
- int young, idx;
-#endif
-
trace_kvm_age_hva(start, end);
/*
* cadence. If we find this inaccurate, we might come up with a
* more sophisticated heuristic later.
*/
-#ifdef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
return kvm_handle_hva_range_no_flush(mn, start, end, kvm_age_gfn);
-#else
- idx = srcu_read_lock(&kvm->srcu);
- KVM_MMU_LOCK(kvm);
- young = kvm_age_hva(kvm, start, end);
- KVM_MMU_UNLOCK(kvm);
- srcu_read_unlock(&kvm->srcu, idx);
-
- return young;
-#endif
}
static int kvm_mmu_notifier_test_young(struct mmu_notifier *mn,
struct mm_struct *mm,
unsigned long address)
{
-#ifndef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
- struct kvm *kvm = mmu_notifier_to_kvm(mn);
- int young, idx;
-#endif
trace_kvm_test_age_hva(address);
-#ifdef KVM_ARCH_WANT_NEW_MMU_NOTIFIER_APIS
return kvm_handle_hva_range_no_flush(mn, address, address + 1,
kvm_test_age_gfn);
-#else
- idx = srcu_read_lock(&kvm->srcu);
- KVM_MMU_LOCK(kvm);
- young = kvm_test_age_hva(kvm, address);
- KVM_MMU_UNLOCK(kvm);
- srcu_read_unlock(&kvm->srcu, idx);
-
- return young;
-#endif
}
static void kvm_mmu_notifier_release(struct mmu_notifier *mn,