aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRadim Krčmář <rkrcmar@redhat.com>2018-09-07 12:38:25 -0400
committerRadim Krčmář <rkrcmar@redhat.com>2018-09-07 12:38:25 -0400
commit564ad0aa85b3202311c4c8744fd1fdab4568d529 (patch)
treeb43699876b60c5aa0263bff581174fcf4288910c
parented2ef29100644eabc6099cbf1a3aa9d938555ab8 (diff)
parentdf3190e22016abf74ef67c9691e9fa1012a66bd5 (diff)
Merge tag 'kvm-arm-fixes-for-v4.19-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm
Fixes for KVM/ARM for Linux v4.19 v2: - Fix a VFP corruption in 32-bit guest - Add missing cache invalidation for CoW pages - Two small cleanups
-rw-r--r--arch/arm/include/asm/kvm_host.h1
-rw-r--r--arch/arm64/include/asm/kvm_host.h4
-rw-r--r--arch/arm64/kvm/hyp/switch.c9
-rw-r--r--arch/mips/include/asm/kvm_host.h1
-rw-r--r--arch/mips/kvm/mmu.c10
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/kvm/mmu.c5
-rw-r--r--virt/kvm/arm/mmu.c21
-rw-r--r--virt/kvm/arm/trace.h15
9 files changed, 15 insertions, 52 deletions
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 79906cecb091..3ad482d2f1eb 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -223,7 +223,6 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
223 struct kvm_vcpu_events *events); 223 struct kvm_vcpu_events *events);
224 224
225#define KVM_ARCH_WANT_MMU_NOTIFIER 225#define KVM_ARCH_WANT_MMU_NOTIFIER
226int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
227int kvm_unmap_hva_range(struct kvm *kvm, 226int kvm_unmap_hva_range(struct kvm *kvm,
228 unsigned long start, unsigned long end); 227 unsigned long start, unsigned long end);
229void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); 228void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index f26055f2306e..3d6d7336f871 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -61,8 +61,7 @@ struct kvm_arch {
61 u64 vmid_gen; 61 u64 vmid_gen;
62 u32 vmid; 62 u32 vmid;
63 63
64 /* 1-level 2nd stage table and lock */ 64 /* 1-level 2nd stage table, protected by kvm->mmu_lock */
65 spinlock_t pgd_lock;
66 pgd_t *pgd; 65 pgd_t *pgd;
67 66
68 /* VTTBR value associated with above pgd and vmid */ 67 /* VTTBR value associated with above pgd and vmid */
@@ -357,7 +356,6 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
357 struct kvm_vcpu_events *events); 356 struct kvm_vcpu_events *events);
358 357
359#define KVM_ARCH_WANT_MMU_NOTIFIER 358#define KVM_ARCH_WANT_MMU_NOTIFIER
360int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
361int kvm_unmap_hva_range(struct kvm *kvm, 359int kvm_unmap_hva_range(struct kvm *kvm,
362 unsigned long start, unsigned long end); 360 unsigned long start, unsigned long end);
363void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); 361void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index d496ef579859..ca46153d7915 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -98,8 +98,10 @@ static void activate_traps_vhe(struct kvm_vcpu *vcpu)
98 val = read_sysreg(cpacr_el1); 98 val = read_sysreg(cpacr_el1);
99 val |= CPACR_EL1_TTA; 99 val |= CPACR_EL1_TTA;
100 val &= ~CPACR_EL1_ZEN; 100 val &= ~CPACR_EL1_ZEN;
101 if (!update_fp_enabled(vcpu)) 101 if (!update_fp_enabled(vcpu)) {
102 val &= ~CPACR_EL1_FPEN; 102 val &= ~CPACR_EL1_FPEN;
103 __activate_traps_fpsimd32(vcpu);
104 }
103 105
104 write_sysreg(val, cpacr_el1); 106 write_sysreg(val, cpacr_el1);
105 107
@@ -114,8 +116,10 @@ static void __hyp_text __activate_traps_nvhe(struct kvm_vcpu *vcpu)
114 116
115 val = CPTR_EL2_DEFAULT; 117 val = CPTR_EL2_DEFAULT;
116 val |= CPTR_EL2_TTA | CPTR_EL2_TZ; 118 val |= CPTR_EL2_TTA | CPTR_EL2_TZ;
117 if (!update_fp_enabled(vcpu)) 119 if (!update_fp_enabled(vcpu)) {
118 val |= CPTR_EL2_TFP; 120 val |= CPTR_EL2_TFP;
121 __activate_traps_fpsimd32(vcpu);
122 }
119 123
120 write_sysreg(val, cptr_el2); 124 write_sysreg(val, cptr_el2);
121} 125}
@@ -129,7 +133,6 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
129 if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (hcr & HCR_VSE)) 133 if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (hcr & HCR_VSE))
130 write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2); 134 write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2);
131 135
132 __activate_traps_fpsimd32(vcpu);
133 if (has_vhe()) 136 if (has_vhe())
134 activate_traps_vhe(vcpu); 137 activate_traps_vhe(vcpu);
135 else 138 else
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index a9af1d2dcd69..2c1c53d12179 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -931,7 +931,6 @@ enum kvm_mips_fault_result kvm_trap_emul_gva_fault(struct kvm_vcpu *vcpu,
931 bool write); 931 bool write);
932 932
933#define KVM_ARCH_WANT_MMU_NOTIFIER 933#define KVM_ARCH_WANT_MMU_NOTIFIER
934int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
935int kvm_unmap_hva_range(struct kvm *kvm, 934int kvm_unmap_hva_range(struct kvm *kvm,
936 unsigned long start, unsigned long end); 935 unsigned long start, unsigned long end);
937void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); 936void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
diff --git a/arch/mips/kvm/mmu.c b/arch/mips/kvm/mmu.c
index ee64db032793..d8dcdb350405 100644
--- a/arch/mips/kvm/mmu.c
+++ b/arch/mips/kvm/mmu.c
@@ -512,16 +512,6 @@ static int kvm_unmap_hva_handler(struct kvm *kvm, gfn_t gfn, gfn_t gfn_end,
512 return 1; 512 return 1;
513} 513}
514 514
515int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
516{
517 unsigned long end = hva + PAGE_SIZE;
518
519 handle_hva_to_gpa(kvm, hva, end, &kvm_unmap_hva_handler, NULL);
520
521 kvm_mips_callbacks->flush_shadow_all(kvm);
522 return 0;
523}
524
525int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) 515int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end)
526{ 516{
527 handle_hva_to_gpa(kvm, start, end, &kvm_unmap_hva_handler, NULL); 517 handle_hva_to_gpa(kvm, start, end, &kvm_unmap_hva_handler, NULL);
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index e12916e7c2fb..3ad10f634d4c 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1443,7 +1443,6 @@ asmlinkage void kvm_spurious_fault(void);
1443 ____kvm_handle_fault_on_reboot(insn, "") 1443 ____kvm_handle_fault_on_reboot(insn, "")
1444 1444
1445#define KVM_ARCH_WANT_MMU_NOTIFIER 1445#define KVM_ARCH_WANT_MMU_NOTIFIER
1446int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
1447int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end); 1446int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end);
1448int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); 1447int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
1449int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); 1448int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index f7e83b1e0eb2..e24ea7067373 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1853,11 +1853,6 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
1853 return kvm_handle_hva_range(kvm, hva, hva + 1, data, handler); 1853 return kvm_handle_hva_range(kvm, hva, hva + 1, data, handler);
1854} 1854}
1855 1855
1856int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
1857{
1858 return kvm_handle_hva(kvm, hva, 0, kvm_unmap_rmapp);
1859}
1860
1861int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) 1856int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end)
1862{ 1857{
1863 return kvm_handle_hva_range(kvm, start, end, 0, kvm_unmap_rmapp); 1858 return kvm_handle_hva_range(kvm, start, end, 0, kvm_unmap_rmapp);
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index 91aaf73b00df..ed162a6c57c5 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1817,18 +1817,6 @@ static int kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *dat
1817 return 0; 1817 return 0;
1818} 1818}
1819 1819
1820int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
1821{
1822 unsigned long end = hva + PAGE_SIZE;
1823
1824 if (!kvm->arch.pgd)
1825 return 0;
1826
1827 trace_kvm_unmap_hva(hva);
1828 handle_hva_to_gpa(kvm, hva, end, &kvm_unmap_hva_handler, NULL);
1829 return 0;
1830}
1831
1832int kvm_unmap_hva_range(struct kvm *kvm, 1820int kvm_unmap_hva_range(struct kvm *kvm,
1833 unsigned long start, unsigned long end) 1821 unsigned long start, unsigned long end)
1834{ 1822{
@@ -1860,13 +1848,20 @@ static int kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *data
1860void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) 1848void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
1861{ 1849{
1862 unsigned long end = hva + PAGE_SIZE; 1850 unsigned long end = hva + PAGE_SIZE;
1851 kvm_pfn_t pfn = pte_pfn(pte);
1863 pte_t stage2_pte; 1852 pte_t stage2_pte;
1864 1853
1865 if (!kvm->arch.pgd) 1854 if (!kvm->arch.pgd)
1866 return; 1855 return;
1867 1856
1868 trace_kvm_set_spte_hva(hva); 1857 trace_kvm_set_spte_hva(hva);
1869 stage2_pte = pfn_pte(pte_pfn(pte), PAGE_S2); 1858
1859 /*
1860 * We've moved a page around, probably through CoW, so let's treat it
1861 * just like a translation fault and clean the cache to the PoC.
1862 */
1863 clean_dcache_guest_page(pfn, PAGE_SIZE);
1864 stage2_pte = pfn_pte(pfn, PAGE_S2);
1870 handle_hva_to_gpa(kvm, hva, end, &kvm_set_spte_handler, &stage2_pte); 1865 handle_hva_to_gpa(kvm, hva, end, &kvm_set_spte_handler, &stage2_pte);
1871} 1866}
1872 1867
diff --git a/virt/kvm/arm/trace.h b/virt/kvm/arm/trace.h
index e53b596f483b..57b3edebbb40 100644
--- a/virt/kvm/arm/trace.h
+++ b/virt/kvm/arm/trace.h
@@ -134,21 +134,6 @@ TRACE_EVENT(kvm_mmio_emulate,
134 __entry->vcpu_pc, __entry->instr, __entry->cpsr) 134 __entry->vcpu_pc, __entry->instr, __entry->cpsr)
135); 135);
136 136
137TRACE_EVENT(kvm_unmap_hva,
138 TP_PROTO(unsigned long hva),
139 TP_ARGS(hva),
140
141 TP_STRUCT__entry(
142 __field( unsigned long, hva )
143 ),
144
145 TP_fast_assign(
146 __entry->hva = hva;
147 ),
148
149 TP_printk("mmu notifier unmap hva: %#08lx", __entry->hva)
150);
151
152TRACE_EVENT(kvm_unmap_hva_range, 137TRACE_EVENT(kvm_unmap_hva_range,
153 TP_PROTO(unsigned long start, unsigned long end), 138 TP_PROTO(unsigned long start, unsigned long end),
154 TP_ARGS(start, end), 139 TP_ARGS(start, end),