a70918fbbc
rebase on Ubuntu-4.13.0-32.35 the effective kernel tree which gets compiled after patches have been applied is functionally identical (modulo parts for architectures which we don't care about and Ubuntu build files)
91 lines
3.0 KiB
Diff
91 lines
3.0 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= <rkrcmar@redhat.com>
|
|
Date: Thu, 30 Nov 2017 19:05:45 +0100
|
|
Subject: [PATCH] KVM: x86: fix APIC page invalidation
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Implementation of the unpinned APIC page didn't update the VMCS address
|
|
cache when invalidation was done through range mmu notifiers.
|
|
This became a problem when the page notifier was removed.
|
|
|
|
Re-introduce the arch-specific helper and call it from ...range_start.
|
|
|
|
Fixes: 38b9917350cb ("kvm: vmx: Implement set_apic_access_page_addr")
|
|
Fixes: 369ea8242c0f ("mm/rmap: update to new mmu_notifier semantic v2")
|
|
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
|
|
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
|
---
|
|
arch/x86/include/asm/kvm_host.h | 3 +++
|
|
arch/x86/kvm/x86.c | 14 ++++++++++++++
|
|
virt/kvm/kvm_main.c | 8 ++++++++
|
|
3 files changed, 25 insertions(+)
|
|
|
|
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
|
|
index 066b51796695..f39bc68efa56 100644
|
|
--- a/arch/x86/include/asm/kvm_host.h
|
|
+++ b/arch/x86/include/asm/kvm_host.h
|
|
@@ -1546,4 +1546,7 @@ static inline int kvm_cpu_get_apicid(int mps_cpu)
|
|
#endif
|
|
}
|
|
|
|
+void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
|
|
+ unsigned long start, unsigned long end);
|
|
+
|
|
#endif /* _ASM_X86_KVM_HOST_H */
|
|
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
|
|
index f896c441fc2c..eae4aecf3cfe 100644
|
|
--- a/arch/x86/kvm/x86.c
|
|
+++ b/arch/x86/kvm/x86.c
|
|
@@ -6711,6 +6711,20 @@ static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu)
|
|
kvm_x86_ops->tlb_flush(vcpu);
|
|
}
|
|
|
|
+void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
|
|
+ unsigned long start, unsigned long end)
|
|
+{
|
|
+ unsigned long apic_address;
|
|
+
|
|
+ /*
|
|
+ * The physical address of apic access page is stored in the VMCS.
|
|
+ * Update it when it becomes invalid.
|
|
+ */
|
|
+ apic_address = gfn_to_hva(kvm, APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT);
|
|
+ if (start <= apic_address && apic_address < end)
|
|
+ kvm_make_all_cpus_request(kvm, KVM_REQ_APIC_PAGE_RELOAD);
|
|
+}
|
|
+
|
|
void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
|
|
{
|
|
struct page *page = NULL;
|
|
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
|
|
index bfa9c4d34102..d0085c9d6297 100644
|
|
--- a/virt/kvm/kvm_main.c
|
|
+++ b/virt/kvm/kvm_main.c
|
|
@@ -136,6 +136,11 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm);
|
|
static unsigned long long kvm_createvm_count;
|
|
static unsigned long long kvm_active_vms;
|
|
|
|
+__weak void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
|
|
+ unsigned long start, unsigned long end)
|
|
+{
|
|
+}
|
|
+
|
|
bool kvm_is_reserved_pfn(kvm_pfn_t pfn)
|
|
{
|
|
if (pfn_valid(pfn))
|
|
@@ -361,6 +366,9 @@ static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
|
|
kvm_flush_remote_tlbs(kvm);
|
|
|
|
spin_unlock(&kvm->mmu_lock);
|
|
+
|
|
+ kvm_arch_mmu_notifier_invalidate_range(kvm, start, end);
|
|
+
|
|
srcu_read_unlock(&kvm->srcu, idx);
|
|
}
|
|
|
|
--
|
|
2.14.2
|
|
|