diff options
author | Radim Krčmář <rkrcmar@redhat.com> | 2018-09-07 12:38:25 -0400 |
---|---|---|
committer | Radim Krčmář <rkrcmar@redhat.com> | 2018-09-07 12:38:25 -0400 |
commit | 564ad0aa85b3202311c4c8744fd1fdab4568d529 (patch) | |
tree | b43699876b60c5aa0263bff581174fcf4288910c | |
parent | ed2ef29100644eabc6099cbf1a3aa9d938555ab8 (diff) | |
parent | df3190e22016abf74ef67c9691e9fa1012a66bd5 (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.h | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/kvm_host.h | 4 | ||||
-rw-r--r-- | arch/arm64/kvm/hyp/switch.c | 9 | ||||
-rw-r--r-- | arch/mips/include/asm/kvm_host.h | 1 | ||||
-rw-r--r-- | arch/mips/kvm/mmu.c | 10 | ||||
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/mmu.c | 5 | ||||
-rw-r--r-- | virt/kvm/arm/mmu.c | 21 | ||||
-rw-r--r-- | virt/kvm/arm/trace.h | 15 |
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 |
226 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); | ||
227 | int kvm_unmap_hva_range(struct kvm *kvm, | 226 | int kvm_unmap_hva_range(struct kvm *kvm, |
228 | unsigned long start, unsigned long end); | 227 | unsigned long start, unsigned long end); |
229 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); | 228 | void 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 |
360 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); | ||
361 | int kvm_unmap_hva_range(struct kvm *kvm, | 359 | int kvm_unmap_hva_range(struct kvm *kvm, |
362 | unsigned long start, unsigned long end); | 360 | unsigned long start, unsigned long end); |
363 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); | 361 | void 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 |
934 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); | ||
935 | int kvm_unmap_hva_range(struct kvm *kvm, | 934 | int kvm_unmap_hva_range(struct kvm *kvm, |
936 | unsigned long start, unsigned long end); | 935 | unsigned long start, unsigned long end); |
937 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); | 936 | void 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 | ||
515 | int 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 | |||
525 | int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) | 515 | int 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 |
1446 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); | ||
1447 | int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end); | 1446 | int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end); |
1448 | int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); | 1447 | int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); |
1449 | int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); | 1448 | int 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 | ||
1856 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) | ||
1857 | { | ||
1858 | return kvm_handle_hva(kvm, hva, 0, kvm_unmap_rmapp); | ||
1859 | } | ||
1860 | |||
1861 | int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) | 1856 | int 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 | ||
1820 | int 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 | |||
1832 | int kvm_unmap_hva_range(struct kvm *kvm, | 1820 | int 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 | |||
1860 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) | 1848 | void 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 | ||
137 | TRACE_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 | |||
152 | TRACE_EVENT(kvm_unmap_hva_range, | 137 | TRACE_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), |