diff options
38 files changed, 239 insertions, 201 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index f670e4b9e7f3..57d3ee9e4bde 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
@@ -2901,14 +2901,19 @@ userspace buffer and its length: | |||
2901 | 2901 | ||
2902 | struct kvm_s390_irq_state { | 2902 | struct kvm_s390_irq_state { |
2903 | __u64 buf; | 2903 | __u64 buf; |
2904 | __u32 flags; | 2904 | __u32 flags; /* will stay unused for compatibility reasons */ |
2905 | __u32 len; | 2905 | __u32 len; |
2906 | __u32 reserved[4]; | 2906 | __u32 reserved[4]; /* will stay unused for compatibility reasons */ |
2907 | }; | 2907 | }; |
2908 | 2908 | ||
2909 | Userspace passes in the above struct and for each pending interrupt a | 2909 | Userspace passes in the above struct and for each pending interrupt a |
2910 | struct kvm_s390_irq is copied to the provided buffer. | 2910 | struct kvm_s390_irq is copied to the provided buffer. |
2911 | 2911 | ||
2912 | The structure contains a flags and a reserved field for future extensions. As | ||
2913 | the kernel never checked for flags == 0 and QEMU never pre-zeroed flags and | ||
2914 | reserved, these fields can not be used in the future without breaking | ||
2915 | compatibility. | ||
2916 | |||
2912 | If -ENOBUFS is returned the buffer provided was too small and userspace | 2917 | If -ENOBUFS is returned the buffer provided was too small and userspace |
2913 | may retry with a bigger buffer. | 2918 | may retry with a bigger buffer. |
2914 | 2919 | ||
@@ -2932,10 +2937,14 @@ containing a struct kvm_s390_irq_state: | |||
2932 | 2937 | ||
2933 | struct kvm_s390_irq_state { | 2938 | struct kvm_s390_irq_state { |
2934 | __u64 buf; | 2939 | __u64 buf; |
2940 | __u32 flags; /* will stay unused for compatibility reasons */ | ||
2935 | __u32 len; | 2941 | __u32 len; |
2936 | __u32 pad; | 2942 | __u32 reserved[4]; /* will stay unused for compatibility reasons */ |
2937 | }; | 2943 | }; |
2938 | 2944 | ||
2945 | The restrictions for flags and reserved apply as well. | ||
2946 | (see KVM_S390_GET_IRQ_STATE) | ||
2947 | |||
2939 | The userspace memory referenced by buf contains a struct kvm_s390_irq | 2948 | The userspace memory referenced by buf contains a struct kvm_s390_irq |
2940 | for each interrupt to be injected into the guest. | 2949 | for each interrupt to be injected into the guest. |
2941 | If one of the interrupts could not be injected for some reason the | 2950 | If one of the interrupts could not be injected for some reason the |
diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index c8781450905b..3ab8b3781bfe 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h | |||
@@ -161,8 +161,7 @@ | |||
161 | #else | 161 | #else |
162 | #define VTTBR_X (5 - KVM_T0SZ) | 162 | #define VTTBR_X (5 - KVM_T0SZ) |
163 | #endif | 163 | #endif |
164 | #define VTTBR_BADDR_SHIFT (VTTBR_X - 1) | 164 | #define VTTBR_BADDR_MASK (((_AC(1, ULL) << (40 - VTTBR_X)) - 1) << VTTBR_X) |
165 | #define VTTBR_BADDR_MASK (((_AC(1, ULL) << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT) | ||
166 | #define VTTBR_VMID_SHIFT _AC(48, ULL) | 165 | #define VTTBR_VMID_SHIFT _AC(48, ULL) |
167 | #define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT) | 166 | #define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT) |
168 | 167 | ||
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 242151ea6908..a9f7d3f47134 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h | |||
@@ -285,6 +285,11 @@ static inline void kvm_arm_init_debug(void) {} | |||
285 | static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {} | 285 | static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {} |
286 | static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {} | 286 | static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {} |
287 | static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {} | 287 | static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {} |
288 | static inline bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu, | ||
289 | struct kvm_run *run) | ||
290 | { | ||
291 | return false; | ||
292 | } | ||
288 | 293 | ||
289 | int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu, | 294 | int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu, |
290 | struct kvm_device_attr *attr); | 295 | struct kvm_device_attr *attr); |
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 7f069ff37f06..715d395ef45b 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h | |||
@@ -170,8 +170,7 @@ | |||
170 | #define VTCR_EL2_FLAGS (VTCR_EL2_COMMON_BITS | VTCR_EL2_TGRAN_FLAGS) | 170 | #define VTCR_EL2_FLAGS (VTCR_EL2_COMMON_BITS | VTCR_EL2_TGRAN_FLAGS) |
171 | #define VTTBR_X (VTTBR_X_TGRAN_MAGIC - VTCR_EL2_T0SZ_IPA) | 171 | #define VTTBR_X (VTTBR_X_TGRAN_MAGIC - VTCR_EL2_T0SZ_IPA) |
172 | 172 | ||
173 | #define VTTBR_BADDR_SHIFT (VTTBR_X - 1) | 173 | #define VTTBR_BADDR_MASK (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_X) |
174 | #define VTTBR_BADDR_MASK (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT) | ||
175 | #define VTTBR_VMID_SHIFT (UL(48)) | 174 | #define VTTBR_VMID_SHIFT (UL(48)) |
176 | #define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT) | 175 | #define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT) |
177 | 176 | ||
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 674912d7a571..ea6cb5b24258 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h | |||
@@ -370,6 +370,7 @@ void kvm_arm_init_debug(void); | |||
370 | void kvm_arm_setup_debug(struct kvm_vcpu *vcpu); | 370 | void kvm_arm_setup_debug(struct kvm_vcpu *vcpu); |
371 | void kvm_arm_clear_debug(struct kvm_vcpu *vcpu); | 371 | void kvm_arm_clear_debug(struct kvm_vcpu *vcpu); |
372 | void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu); | 372 | void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu); |
373 | bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu, struct kvm_run *run); | ||
373 | int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu, | 374 | int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu, |
374 | struct kvm_device_attr *attr); | 375 | struct kvm_device_attr *attr); |
375 | int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu, | 376 | int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu, |
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c index dbadfaf850a7..fa63b28c65e0 100644 --- a/arch/arm64/kvm/debug.c +++ b/arch/arm64/kvm/debug.c | |||
@@ -221,3 +221,24 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) | |||
221 | } | 221 | } |
222 | } | 222 | } |
223 | } | 223 | } |
224 | |||
225 | |||
226 | /* | ||
227 | * After successfully emulating an instruction, we might want to | ||
228 | * return to user space with a KVM_EXIT_DEBUG. We can only do this | ||
229 | * once the emulation is complete, though, so for userspace emulations | ||
230 | * we have to wait until we have re-entered KVM before calling this | ||
231 | * helper. | ||
232 | * | ||
233 | * Return true (and set exit_reason) to return to userspace or false | ||
234 | * if no further action is required. | ||
235 | */ | ||
236 | bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu, struct kvm_run *run) | ||
237 | { | ||
238 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { | ||
239 | run->exit_reason = KVM_EXIT_DEBUG; | ||
240 | run->debug.arch.hsr = ESR_ELx_EC_SOFTSTP_LOW << ESR_ELx_EC_SHIFT; | ||
241 | return true; | ||
242 | } | ||
243 | return false; | ||
244 | } | ||
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index b71247995469..304203fa9e33 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/kvm_emulate.h> | 28 | #include <asm/kvm_emulate.h> |
29 | #include <asm/kvm_mmu.h> | 29 | #include <asm/kvm_mmu.h> |
30 | #include <asm/kvm_psci.h> | 30 | #include <asm/kvm_psci.h> |
31 | #include <asm/debug-monitors.h> | ||
31 | 32 | ||
32 | #define CREATE_TRACE_POINTS | 33 | #define CREATE_TRACE_POINTS |
33 | #include "trace.h" | 34 | #include "trace.h" |
@@ -187,14 +188,46 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu) | |||
187 | } | 188 | } |
188 | 189 | ||
189 | /* | 190 | /* |
191 | * We may be single-stepping an emulated instruction. If the emulation | ||
192 | * has been completed in the kernel, we can return to userspace with a | ||
193 | * KVM_EXIT_DEBUG, otherwise userspace needs to complete its | ||
194 | * emulation first. | ||
195 | */ | ||
196 | static int handle_trap_exceptions(struct kvm_vcpu *vcpu, struct kvm_run *run) | ||
197 | { | ||
198 | int handled; | ||
199 | |||
200 | /* | ||
201 | * See ARM ARM B1.14.1: "Hyp traps on instructions | ||
202 | * that fail their condition code check" | ||
203 | */ | ||
204 | if (!kvm_condition_valid(vcpu)) { | ||
205 | kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); | ||
206 | handled = 1; | ||
207 | } else { | ||
208 | exit_handle_fn exit_handler; | ||
209 | |||
210 | exit_handler = kvm_get_exit_handler(vcpu); | ||
211 | handled = exit_handler(vcpu, run); | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * kvm_arm_handle_step_debug() sets the exit_reason on the kvm_run | ||
216 | * structure if we need to return to userspace. | ||
217 | */ | ||
218 | if (handled > 0 && kvm_arm_handle_step_debug(vcpu, run)) | ||
219 | handled = 0; | ||
220 | |||
221 | return handled; | ||
222 | } | ||
223 | |||
224 | /* | ||
190 | * Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on | 225 | * Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on |
191 | * proper exit to userspace. | 226 | * proper exit to userspace. |
192 | */ | 227 | */ |
193 | int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, | 228 | int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, |
194 | int exception_index) | 229 | int exception_index) |
195 | { | 230 | { |
196 | exit_handle_fn exit_handler; | ||
197 | |||
198 | if (ARM_SERROR_PENDING(exception_index)) { | 231 | if (ARM_SERROR_PENDING(exception_index)) { |
199 | u8 hsr_ec = ESR_ELx_EC(kvm_vcpu_get_hsr(vcpu)); | 232 | u8 hsr_ec = ESR_ELx_EC(kvm_vcpu_get_hsr(vcpu)); |
200 | 233 | ||
@@ -220,20 +253,14 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, | |||
220 | return 1; | 253 | return 1; |
221 | case ARM_EXCEPTION_EL1_SERROR: | 254 | case ARM_EXCEPTION_EL1_SERROR: |
222 | kvm_inject_vabt(vcpu); | 255 | kvm_inject_vabt(vcpu); |
223 | return 1; | 256 | /* We may still need to return for single-step */ |
224 | case ARM_EXCEPTION_TRAP: | 257 | if (!(*vcpu_cpsr(vcpu) & DBG_SPSR_SS) |
225 | /* | 258 | && kvm_arm_handle_step_debug(vcpu, run)) |
226 | * See ARM ARM B1.14.1: "Hyp traps on instructions | 259 | return 0; |
227 | * that fail their condition code check" | 260 | else |
228 | */ | ||
229 | if (!kvm_condition_valid(vcpu)) { | ||
230 | kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); | ||
231 | return 1; | 261 | return 1; |
232 | } | 262 | case ARM_EXCEPTION_TRAP: |
233 | 263 | return handle_trap_exceptions(vcpu, run); | |
234 | exit_handler = kvm_get_exit_handler(vcpu); | ||
235 | |||
236 | return exit_handler(vcpu, run); | ||
237 | case ARM_EXCEPTION_HYP_GONE: | 264 | case ARM_EXCEPTION_HYP_GONE: |
238 | /* | 265 | /* |
239 | * EL2 has been reset to the hyp-stub. This happens when a guest | 266 | * EL2 has been reset to the hyp-stub. This happens when a guest |
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c index 525c01f48867..f7c651f3a8c0 100644 --- a/arch/arm64/kvm/hyp/switch.c +++ b/arch/arm64/kvm/hyp/switch.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/kvm_emulate.h> | 22 | #include <asm/kvm_emulate.h> |
23 | #include <asm/kvm_hyp.h> | 23 | #include <asm/kvm_hyp.h> |
24 | #include <asm/fpsimd.h> | 24 | #include <asm/fpsimd.h> |
25 | #include <asm/debug-monitors.h> | ||
25 | 26 | ||
26 | static bool __hyp_text __fpsimd_enabled_nvhe(void) | 27 | static bool __hyp_text __fpsimd_enabled_nvhe(void) |
27 | { | 28 | { |
@@ -269,7 +270,11 @@ static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu) | |||
269 | return true; | 270 | return true; |
270 | } | 271 | } |
271 | 272 | ||
272 | static void __hyp_text __skip_instr(struct kvm_vcpu *vcpu) | 273 | /* Skip an instruction which has been emulated. Returns true if |
274 | * execution can continue or false if we need to exit hyp mode because | ||
275 | * single-step was in effect. | ||
276 | */ | ||
277 | static bool __hyp_text __skip_instr(struct kvm_vcpu *vcpu) | ||
273 | { | 278 | { |
274 | *vcpu_pc(vcpu) = read_sysreg_el2(elr); | 279 | *vcpu_pc(vcpu) = read_sysreg_el2(elr); |
275 | 280 | ||
@@ -282,6 +287,14 @@ static void __hyp_text __skip_instr(struct kvm_vcpu *vcpu) | |||
282 | } | 287 | } |
283 | 288 | ||
284 | write_sysreg_el2(*vcpu_pc(vcpu), elr); | 289 | write_sysreg_el2(*vcpu_pc(vcpu), elr); |
290 | |||
291 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { | ||
292 | vcpu->arch.fault.esr_el2 = | ||
293 | (ESR_ELx_EC_SOFTSTP_LOW << ESR_ELx_EC_SHIFT) | 0x22; | ||
294 | return false; | ||
295 | } else { | ||
296 | return true; | ||
297 | } | ||
285 | } | 298 | } |
286 | 299 | ||
287 | int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu) | 300 | int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu) |
@@ -342,13 +355,21 @@ again: | |||
342 | int ret = __vgic_v2_perform_cpuif_access(vcpu); | 355 | int ret = __vgic_v2_perform_cpuif_access(vcpu); |
343 | 356 | ||
344 | if (ret == 1) { | 357 | if (ret == 1) { |
345 | __skip_instr(vcpu); | 358 | if (__skip_instr(vcpu)) |
346 | goto again; | 359 | goto again; |
360 | else | ||
361 | exit_code = ARM_EXCEPTION_TRAP; | ||
347 | } | 362 | } |
348 | 363 | ||
349 | if (ret == -1) { | 364 | if (ret == -1) { |
350 | /* Promote an illegal access to an SError */ | 365 | /* Promote an illegal access to an |
351 | __skip_instr(vcpu); | 366 | * SError. If we would be returning |
367 | * due to single-step clear the SS | ||
368 | * bit so handle_exit knows what to | ||
369 | * do after dealing with the error. | ||
370 | */ | ||
371 | if (!__skip_instr(vcpu)) | ||
372 | *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; | ||
352 | exit_code = ARM_EXCEPTION_EL1_SERROR; | 373 | exit_code = ARM_EXCEPTION_EL1_SERROR; |
353 | } | 374 | } |
354 | 375 | ||
@@ -363,8 +384,10 @@ again: | |||
363 | int ret = __vgic_v3_perform_cpuif_access(vcpu); | 384 | int ret = __vgic_v3_perform_cpuif_access(vcpu); |
364 | 385 | ||
365 | if (ret == 1) { | 386 | if (ret == 1) { |
366 | __skip_instr(vcpu); | 387 | if (__skip_instr(vcpu)) |
367 | goto again; | 388 | goto again; |
389 | else | ||
390 | exit_code = ARM_EXCEPTION_TRAP; | ||
368 | } | 391 | } |
369 | 392 | ||
370 | /* 0 falls through to be handled out of EL2 */ | 393 | /* 0 falls through to be handled out of EL2 */ |
diff --git a/arch/s390/kvm/Makefile b/arch/s390/kvm/Makefile index 6048b1c6e580..05ee90a5ea08 100644 --- a/arch/s390/kvm/Makefile +++ b/arch/s390/kvm/Makefile | |||
@@ -1,10 +1,7 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
1 | # Makefile for kernel virtual machines on s390 | 2 | # Makefile for kernel virtual machines on s390 |
2 | # | 3 | # |
3 | # Copyright IBM Corp. 2008 | 4 | # Copyright IBM Corp. 2008 |
4 | # | ||
5 | # This program is free software; you can redistribute it and/or modify | ||
6 | # it under the terms of the GNU General Public License (version 2 only) | ||
7 | # as published by the Free Software Foundation. | ||
8 | 5 | ||
9 | KVM := ../../../virt/kvm | 6 | KVM := ../../../virt/kvm |
10 | common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o $(KVM)/irqchip.o $(KVM)/vfio.o | 7 | common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o $(KVM)/irqchip.o $(KVM)/vfio.o |
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index d93a2c0474bf..89aa114a2cba 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c | |||
@@ -1,12 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * handling diagnose instructions | 3 | * handling diagnose instructions |
3 | * | 4 | * |
4 | * Copyright IBM Corp. 2008, 2011 | 5 | * Copyright IBM Corp. 2008, 2011 |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 7 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
11 | * Christian Borntraeger <borntraeger@de.ibm.com> | 8 | * Christian Borntraeger <borntraeger@de.ibm.com> |
12 | */ | 9 | */ |
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h index bec42b852246..f4c51756c462 100644 --- a/arch/s390/kvm/gaccess.h +++ b/arch/s390/kvm/gaccess.h | |||
@@ -1,12 +1,9 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
1 | /* | 2 | /* |
2 | * access guest memory | 3 | * access guest memory |
3 | * | 4 | * |
4 | * Copyright IBM Corp. 2008, 2014 | 5 | * Copyright IBM Corp. 2008, 2014 |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 7 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
11 | */ | 8 | */ |
12 | 9 | ||
diff --git a/arch/s390/kvm/guestdbg.c b/arch/s390/kvm/guestdbg.c index bcbd86621d01..b5f3e82006d0 100644 --- a/arch/s390/kvm/guestdbg.c +++ b/arch/s390/kvm/guestdbg.c | |||
@@ -1,12 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * kvm guest debug support | 3 | * kvm guest debug support |
3 | * | 4 | * |
4 | * Copyright IBM Corp. 2014 | 5 | * Copyright IBM Corp. 2014 |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com> | 7 | * Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com> |
11 | */ | 8 | */ |
12 | #include <linux/kvm_host.h> | 9 | #include <linux/kvm_host.h> |
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 8fe034beb623..9c7d70715862 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c | |||
@@ -1,12 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * in-kernel handling for sie intercepts | 3 | * in-kernel handling for sie intercepts |
3 | * | 4 | * |
4 | * Copyright IBM Corp. 2008, 2014 | 5 | * Copyright IBM Corp. 2008, 2014 |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 7 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
11 | * Christian Borntraeger <borntraeger@de.ibm.com> | 8 | * Christian Borntraeger <borntraeger@de.ibm.com> |
12 | */ | 9 | */ |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index fa557372d600..024ad8bcc516 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
@@ -1,12 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * handling kvm guest interrupts | 3 | * handling kvm guest interrupts |
3 | * | 4 | * |
4 | * Copyright IBM Corp. 2008, 2015 | 5 | * Copyright IBM Corp. 2008, 2015 |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 7 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
11 | */ | 8 | */ |
12 | 9 | ||
diff --git a/arch/s390/kvm/irq.h b/arch/s390/kvm/irq.h index d98e4159643d..484608c71dd0 100644 --- a/arch/s390/kvm/irq.h +++ b/arch/s390/kvm/irq.h | |||
@@ -1,12 +1,9 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
1 | /* | 2 | /* |
2 | * s390 irqchip routines | 3 | * s390 irqchip routines |
3 | * | 4 | * |
4 | * Copyright IBM Corp. 2014 | 5 | * Copyright IBM Corp. 2014 |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> | 7 | * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> |
11 | */ | 8 | */ |
12 | #ifndef __KVM_IRQ_H | 9 | #ifndef __KVM_IRQ_H |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 9614aea5839b..ec8b68e97d3c 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -1,11 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * hosting zSeries kernel virtual machines | 3 | * hosting IBM Z kernel virtual machines (s390x) |
3 | * | 4 | * |
4 | * Copyright IBM Corp. 2008, 2009 | 5 | * Copyright IBM Corp. 2008, 2017 |
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | 6 | * |
10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 7 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
11 | * Christian Borntraeger <borntraeger@de.ibm.com> | 8 | * Christian Borntraeger <borntraeger@de.ibm.com> |
@@ -3808,6 +3805,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
3808 | r = -EINVAL; | 3805 | r = -EINVAL; |
3809 | break; | 3806 | break; |
3810 | } | 3807 | } |
3808 | /* do not use irq_state.flags, it will break old QEMUs */ | ||
3811 | r = kvm_s390_set_irq_state(vcpu, | 3809 | r = kvm_s390_set_irq_state(vcpu, |
3812 | (void __user *) irq_state.buf, | 3810 | (void __user *) irq_state.buf, |
3813 | irq_state.len); | 3811 | irq_state.len); |
@@ -3823,6 +3821,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
3823 | r = -EINVAL; | 3821 | r = -EINVAL; |
3824 | break; | 3822 | break; |
3825 | } | 3823 | } |
3824 | /* do not use irq_state.flags, it will break old QEMUs */ | ||
3826 | r = kvm_s390_get_irq_state(vcpu, | 3825 | r = kvm_s390_get_irq_state(vcpu, |
3827 | (__u8 __user *) irq_state.buf, | 3826 | (__u8 __user *) irq_state.buf, |
3828 | irq_state.len); | 3827 | irq_state.len); |
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 10d65dfbc306..5e46ba429bcb 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h | |||
@@ -1,12 +1,9 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
1 | /* | 2 | /* |
2 | * definition for kvm on s390 | 3 | * definition for kvm on s390 |
3 | * | 4 | * |
4 | * Copyright IBM Corp. 2008, 2009 | 5 | * Copyright IBM Corp. 2008, 2009 |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 7 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
11 | * Christian Borntraeger <borntraeger@de.ibm.com> | 8 | * Christian Borntraeger <borntraeger@de.ibm.com> |
12 | * Christian Ehrhardt <ehrhardt@de.ibm.com> | 9 | * Christian Ehrhardt <ehrhardt@de.ibm.com> |
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index c954ac49eee4..572496c688cc 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
@@ -1,12 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * handling privileged instructions | 3 | * handling privileged instructions |
3 | * | 4 | * |
4 | * Copyright IBM Corp. 2008, 2013 | 5 | * Copyright IBM Corp. 2008, 2013 |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 7 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
11 | * Christian Borntraeger <borntraeger@de.ibm.com> | 8 | * Christian Borntraeger <borntraeger@de.ibm.com> |
12 | */ | 9 | */ |
@@ -235,8 +232,6 @@ static int try_handle_skey(struct kvm_vcpu *vcpu) | |||
235 | VCPU_EVENT(vcpu, 4, "%s", "retrying storage key operation"); | 232 | VCPU_EVENT(vcpu, 4, "%s", "retrying storage key operation"); |
236 | return -EAGAIN; | 233 | return -EAGAIN; |
237 | } | 234 | } |
238 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | ||
239 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | ||
240 | return 0; | 235 | return 0; |
241 | } | 236 | } |
242 | 237 | ||
@@ -247,6 +242,9 @@ static int handle_iske(struct kvm_vcpu *vcpu) | |||
247 | int reg1, reg2; | 242 | int reg1, reg2; |
248 | int rc; | 243 | int rc; |
249 | 244 | ||
245 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | ||
246 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | ||
247 | |||
250 | rc = try_handle_skey(vcpu); | 248 | rc = try_handle_skey(vcpu); |
251 | if (rc) | 249 | if (rc) |
252 | return rc != -EAGAIN ? rc : 0; | 250 | return rc != -EAGAIN ? rc : 0; |
@@ -276,6 +274,9 @@ static int handle_rrbe(struct kvm_vcpu *vcpu) | |||
276 | int reg1, reg2; | 274 | int reg1, reg2; |
277 | int rc; | 275 | int rc; |
278 | 276 | ||
277 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | ||
278 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | ||
279 | |||
279 | rc = try_handle_skey(vcpu); | 280 | rc = try_handle_skey(vcpu); |
280 | if (rc) | 281 | if (rc) |
281 | return rc != -EAGAIN ? rc : 0; | 282 | return rc != -EAGAIN ? rc : 0; |
@@ -311,6 +312,9 @@ static int handle_sske(struct kvm_vcpu *vcpu) | |||
311 | int reg1, reg2; | 312 | int reg1, reg2; |
312 | int rc; | 313 | int rc; |
313 | 314 | ||
315 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | ||
316 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | ||
317 | |||
314 | rc = try_handle_skey(vcpu); | 318 | rc = try_handle_skey(vcpu); |
315 | if (rc) | 319 | if (rc) |
316 | return rc != -EAGAIN ? rc : 0; | 320 | return rc != -EAGAIN ? rc : 0; |
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 9d592ef4104b..c1f5cde2c878 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
@@ -1,12 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * handling interprocessor communication | 3 | * handling interprocessor communication |
3 | * | 4 | * |
4 | * Copyright IBM Corp. 2008, 2013 | 5 | * Copyright IBM Corp. 2008, 2013 |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 7 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
11 | * Christian Borntraeger <borntraeger@de.ibm.com> | 8 | * Christian Borntraeger <borntraeger@de.ibm.com> |
12 | * Christian Ehrhardt <ehrhardt@de.ibm.com> | 9 | * Christian Ehrhardt <ehrhardt@de.ibm.com> |
diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index a311938b63b3..5d6ae0326d9e 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c | |||
@@ -1,12 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * kvm nested virtualization support for s390x | 3 | * kvm nested virtualization support for s390x |
3 | * | 4 | * |
4 | * Copyright IBM Corp. 2016 | 5 | * Copyright IBM Corp. 2016 |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com> | 7 | * Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com> |
11 | */ | 8 | */ |
12 | #include <linux/vmalloc.h> | 9 | #include <linux/vmalloc.h> |
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 034caa1a084e..b24b1c8b3979 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h | |||
@@ -214,8 +214,6 @@ struct x86_emulate_ops { | |||
214 | void (*halt)(struct x86_emulate_ctxt *ctxt); | 214 | void (*halt)(struct x86_emulate_ctxt *ctxt); |
215 | void (*wbinvd)(struct x86_emulate_ctxt *ctxt); | 215 | void (*wbinvd)(struct x86_emulate_ctxt *ctxt); |
216 | int (*fix_hypercall)(struct x86_emulate_ctxt *ctxt); | 216 | int (*fix_hypercall)(struct x86_emulate_ctxt *ctxt); |
217 | void (*get_fpu)(struct x86_emulate_ctxt *ctxt); /* disables preempt */ | ||
218 | void (*put_fpu)(struct x86_emulate_ctxt *ctxt); /* reenables preempt */ | ||
219 | int (*intercept)(struct x86_emulate_ctxt *ctxt, | 217 | int (*intercept)(struct x86_emulate_ctxt *ctxt, |
220 | struct x86_instruction_info *info, | 218 | struct x86_instruction_info *info, |
221 | enum x86_intercept_stage stage); | 219 | enum x86_intercept_stage stage); |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 977de5fb968b..516798431328 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -536,7 +536,20 @@ struct kvm_vcpu_arch { | |||
536 | struct kvm_mmu_memory_cache mmu_page_cache; | 536 | struct kvm_mmu_memory_cache mmu_page_cache; |
537 | struct kvm_mmu_memory_cache mmu_page_header_cache; | 537 | struct kvm_mmu_memory_cache mmu_page_header_cache; |
538 | 538 | ||
539 | /* | ||
540 | * QEMU userspace and the guest each have their own FPU state. | ||
541 | * In vcpu_run, we switch between the user and guest FPU contexts. | ||
542 | * While running a VCPU, the VCPU thread will have the guest FPU | ||
543 | * context. | ||
544 | * | ||
545 | * Note that while the PKRU state lives inside the fpu registers, | ||
546 | * it is switched out separately at VMENTER and VMEXIT time. The | ||
547 | * "guest_fpu" state here contains the guest FPU context, with the | ||
548 | * host PRKU bits. | ||
549 | */ | ||
550 | struct fpu user_fpu; | ||
539 | struct fpu guest_fpu; | 551 | struct fpu guest_fpu; |
552 | |||
540 | u64 xcr0; | 553 | u64 xcr0; |
541 | u64 guest_supported_xcr0; | 554 | u64 guest_supported_xcr0; |
542 | u32 guest_xstate_size; | 555 | u32 guest_xstate_size; |
@@ -1435,4 +1448,7 @@ static inline int kvm_cpu_get_apicid(int mps_cpu) | |||
1435 | #define put_smstate(type, buf, offset, val) \ | 1448 | #define put_smstate(type, buf, offset, val) \ |
1436 | *(type *)((buf) + (offset) - 0x7e00) = val | 1449 | *(type *)((buf) + (offset) - 0x7e00) = val |
1437 | 1450 | ||
1451 | void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm, | ||
1452 | unsigned long start, unsigned long end); | ||
1453 | |||
1438 | #endif /* _ASM_X86_KVM_HOST_H */ | 1454 | #endif /* _ASM_X86_KVM_HOST_H */ |
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index e7d04d0c8008..abe74f779f9d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -1046,7 +1046,6 @@ static void fetch_register_operand(struct operand *op) | |||
1046 | 1046 | ||
1047 | static void read_sse_reg(struct x86_emulate_ctxt *ctxt, sse128_t *data, int reg) | 1047 | static void read_sse_reg(struct x86_emulate_ctxt *ctxt, sse128_t *data, int reg) |
1048 | { | 1048 | { |
1049 | ctxt->ops->get_fpu(ctxt); | ||
1050 | switch (reg) { | 1049 | switch (reg) { |
1051 | case 0: asm("movdqa %%xmm0, %0" : "=m"(*data)); break; | 1050 | case 0: asm("movdqa %%xmm0, %0" : "=m"(*data)); break; |
1052 | case 1: asm("movdqa %%xmm1, %0" : "=m"(*data)); break; | 1051 | case 1: asm("movdqa %%xmm1, %0" : "=m"(*data)); break; |
@@ -1068,13 +1067,11 @@ static void read_sse_reg(struct x86_emulate_ctxt *ctxt, sse128_t *data, int reg) | |||
1068 | #endif | 1067 | #endif |
1069 | default: BUG(); | 1068 | default: BUG(); |
1070 | } | 1069 | } |
1071 | ctxt->ops->put_fpu(ctxt); | ||
1072 | } | 1070 | } |
1073 | 1071 | ||
1074 | static void write_sse_reg(struct x86_emulate_ctxt *ctxt, sse128_t *data, | 1072 | static void write_sse_reg(struct x86_emulate_ctxt *ctxt, sse128_t *data, |
1075 | int reg) | 1073 | int reg) |
1076 | { | 1074 | { |
1077 | ctxt->ops->get_fpu(ctxt); | ||
1078 | switch (reg) { | 1075 | switch (reg) { |
1079 | case 0: asm("movdqa %0, %%xmm0" : : "m"(*data)); break; | 1076 | case 0: asm("movdqa %0, %%xmm0" : : "m"(*data)); break; |
1080 | case 1: asm("movdqa %0, %%xmm1" : : "m"(*data)); break; | 1077 | case 1: asm("movdqa %0, %%xmm1" : : "m"(*data)); break; |
@@ -1096,12 +1093,10 @@ static void write_sse_reg(struct x86_emulate_ctxt *ctxt, sse128_t *data, | |||
1096 | #endif | 1093 | #endif |
1097 | default: BUG(); | 1094 | default: BUG(); |
1098 | } | 1095 | } |
1099 | ctxt->ops->put_fpu(ctxt); | ||
1100 | } | 1096 | } |
1101 | 1097 | ||
1102 | static void read_mmx_reg(struct x86_emulate_ctxt *ctxt, u64 *data, int reg) | 1098 | static void read_mmx_reg(struct x86_emulate_ctxt *ctxt, u64 *data, int reg) |
1103 | { | 1099 | { |
1104 | ctxt->ops->get_fpu(ctxt); | ||
1105 | switch (reg) { | 1100 | switch (reg) { |
1106 | case 0: asm("movq %%mm0, %0" : "=m"(*data)); break; | 1101 | case 0: asm("movq %%mm0, %0" : "=m"(*data)); break; |
1107 | case 1: asm("movq %%mm1, %0" : "=m"(*data)); break; | 1102 | case 1: asm("movq %%mm1, %0" : "=m"(*data)); break; |
@@ -1113,12 +1108,10 @@ static void read_mmx_reg(struct x86_emulate_ctxt *ctxt, u64 *data, int reg) | |||
1113 | case 7: asm("movq %%mm7, %0" : "=m"(*data)); break; | 1108 | case 7: asm("movq %%mm7, %0" : "=m"(*data)); break; |
1114 | default: BUG(); | 1109 | default: BUG(); |
1115 | } | 1110 | } |
1116 | ctxt->ops->put_fpu(ctxt); | ||
1117 | } | 1111 | } |
1118 | 1112 | ||
1119 | static void write_mmx_reg(struct x86_emulate_ctxt *ctxt, u64 *data, int reg) | 1113 | static void write_mmx_reg(struct x86_emulate_ctxt *ctxt, u64 *data, int reg) |
1120 | { | 1114 | { |
1121 | ctxt->ops->get_fpu(ctxt); | ||
1122 | switch (reg) { | 1115 | switch (reg) { |
1123 | case 0: asm("movq %0, %%mm0" : : "m"(*data)); break; | 1116 | case 0: asm("movq %0, %%mm0" : : "m"(*data)); break; |
1124 | case 1: asm("movq %0, %%mm1" : : "m"(*data)); break; | 1117 | case 1: asm("movq %0, %%mm1" : : "m"(*data)); break; |
@@ -1130,7 +1123,6 @@ static void write_mmx_reg(struct x86_emulate_ctxt *ctxt, u64 *data, int reg) | |||
1130 | case 7: asm("movq %0, %%mm7" : : "m"(*data)); break; | 1123 | case 7: asm("movq %0, %%mm7" : : "m"(*data)); break; |
1131 | default: BUG(); | 1124 | default: BUG(); |
1132 | } | 1125 | } |
1133 | ctxt->ops->put_fpu(ctxt); | ||
1134 | } | 1126 | } |
1135 | 1127 | ||
1136 | static int em_fninit(struct x86_emulate_ctxt *ctxt) | 1128 | static int em_fninit(struct x86_emulate_ctxt *ctxt) |
@@ -1138,9 +1130,7 @@ static int em_fninit(struct x86_emulate_ctxt *ctxt) | |||
1138 | if (ctxt->ops->get_cr(ctxt, 0) & (X86_CR0_TS | X86_CR0_EM)) | 1130 | if (ctxt->ops->get_cr(ctxt, 0) & (X86_CR0_TS | X86_CR0_EM)) |
1139 | return emulate_nm(ctxt); | 1131 | return emulate_nm(ctxt); |
1140 | 1132 | ||
1141 | ctxt->ops->get_fpu(ctxt); | ||
1142 | asm volatile("fninit"); | 1133 | asm volatile("fninit"); |
1143 | ctxt->ops->put_fpu(ctxt); | ||
1144 | return X86EMUL_CONTINUE; | 1134 | return X86EMUL_CONTINUE; |
1145 | } | 1135 | } |
1146 | 1136 | ||
@@ -1151,9 +1141,7 @@ static int em_fnstcw(struct x86_emulate_ctxt *ctxt) | |||
1151 | if (ctxt->ops->get_cr(ctxt, 0) & (X86_CR0_TS | X86_CR0_EM)) | 1141 | if (ctxt->ops->get_cr(ctxt, 0) & (X86_CR0_TS | X86_CR0_EM)) |
1152 | return emulate_nm(ctxt); | 1142 | return emulate_nm(ctxt); |
1153 | 1143 | ||
1154 | ctxt->ops->get_fpu(ctxt); | ||
1155 | asm volatile("fnstcw %0": "+m"(fcw)); | 1144 | asm volatile("fnstcw %0": "+m"(fcw)); |
1156 | ctxt->ops->put_fpu(ctxt); | ||
1157 | 1145 | ||
1158 | ctxt->dst.val = fcw; | 1146 | ctxt->dst.val = fcw; |
1159 | 1147 | ||
@@ -1167,9 +1155,7 @@ static int em_fnstsw(struct x86_emulate_ctxt *ctxt) | |||
1167 | if (ctxt->ops->get_cr(ctxt, 0) & (X86_CR0_TS | X86_CR0_EM)) | 1155 | if (ctxt->ops->get_cr(ctxt, 0) & (X86_CR0_TS | X86_CR0_EM)) |
1168 | return emulate_nm(ctxt); | 1156 | return emulate_nm(ctxt); |
1169 | 1157 | ||
1170 | ctxt->ops->get_fpu(ctxt); | ||
1171 | asm volatile("fnstsw %0": "+m"(fsw)); | 1158 | asm volatile("fnstsw %0": "+m"(fsw)); |
1172 | ctxt->ops->put_fpu(ctxt); | ||
1173 | 1159 | ||
1174 | ctxt->dst.val = fsw; | 1160 | ctxt->dst.val = fsw; |
1175 | 1161 | ||
@@ -4001,12 +3987,8 @@ static int em_fxsave(struct x86_emulate_ctxt *ctxt) | |||
4001 | if (rc != X86EMUL_CONTINUE) | 3987 | if (rc != X86EMUL_CONTINUE) |
4002 | return rc; | 3988 | return rc; |
4003 | 3989 | ||
4004 | ctxt->ops->get_fpu(ctxt); | ||
4005 | |||
4006 | rc = asm_safe("fxsave %[fx]", , [fx] "+m"(fx_state)); | 3990 | rc = asm_safe("fxsave %[fx]", , [fx] "+m"(fx_state)); |
4007 | 3991 | ||
4008 | ctxt->ops->put_fpu(ctxt); | ||
4009 | |||
4010 | if (rc != X86EMUL_CONTINUE) | 3992 | if (rc != X86EMUL_CONTINUE) |
4011 | return rc; | 3993 | return rc; |
4012 | 3994 | ||
@@ -4049,8 +4031,6 @@ static int em_fxrstor(struct x86_emulate_ctxt *ctxt) | |||
4049 | if (rc != X86EMUL_CONTINUE) | 4031 | if (rc != X86EMUL_CONTINUE) |
4050 | return rc; | 4032 | return rc; |
4051 | 4033 | ||
4052 | ctxt->ops->get_fpu(ctxt); | ||
4053 | |||
4054 | if (size < __fxstate_size(16)) { | 4034 | if (size < __fxstate_size(16)) { |
4055 | rc = fxregs_fixup(&fx_state, size); | 4035 | rc = fxregs_fixup(&fx_state, size); |
4056 | if (rc != X86EMUL_CONTINUE) | 4036 | if (rc != X86EMUL_CONTINUE) |
@@ -4066,8 +4046,6 @@ static int em_fxrstor(struct x86_emulate_ctxt *ctxt) | |||
4066 | rc = asm_safe("fxrstor %[fx]", : [fx] "m"(fx_state)); | 4046 | rc = asm_safe("fxrstor %[fx]", : [fx] "m"(fx_state)); |
4067 | 4047 | ||
4068 | out: | 4048 | out: |
4069 | ctxt->ops->put_fpu(ctxt); | ||
4070 | |||
4071 | return rc; | 4049 | return rc; |
4072 | } | 4050 | } |
4073 | 4051 | ||
@@ -5317,9 +5295,7 @@ static int flush_pending_x87_faults(struct x86_emulate_ctxt *ctxt) | |||
5317 | { | 5295 | { |
5318 | int rc; | 5296 | int rc; |
5319 | 5297 | ||
5320 | ctxt->ops->get_fpu(ctxt); | ||
5321 | rc = asm_safe("fwait"); | 5298 | rc = asm_safe("fwait"); |
5322 | ctxt->ops->put_fpu(ctxt); | ||
5323 | 5299 | ||
5324 | if (unlikely(rc != X86EMUL_CONTINUE)) | 5300 | if (unlikely(rc != X86EMUL_CONTINUE)) |
5325 | return emulate_exception(ctxt, MF_VECTOR, 0, false); | 5301 | return emulate_exception(ctxt, MF_VECTOR, 0, false); |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 4704aaf6d19e..8eba631c4dbd 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -6751,16 +6751,10 @@ static __init int hardware_setup(void) | |||
6751 | goto out; | 6751 | goto out; |
6752 | } | 6752 | } |
6753 | 6753 | ||
6754 | vmx_io_bitmap_b = (unsigned long *)__get_free_page(GFP_KERNEL); | ||
6755 | memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); | 6754 | memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); |
6756 | memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); | 6755 | memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); |
6757 | 6756 | ||
6758 | /* | ||
6759 | * Allow direct access to the PC debug port (it is often used for I/O | ||
6760 | * delays, but the vmexits simply slow things down). | ||
6761 | */ | ||
6762 | memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE); | 6757 | memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE); |
6763 | clear_bit(0x80, vmx_io_bitmap_a); | ||
6764 | 6758 | ||
6765 | memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE); | 6759 | memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE); |
6766 | 6760 | ||
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index eee8e7faf1af..faf843c9b916 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2937,7 +2937,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | |||
2937 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | 2937 | srcu_read_unlock(&vcpu->kvm->srcu, idx); |
2938 | pagefault_enable(); | 2938 | pagefault_enable(); |
2939 | kvm_x86_ops->vcpu_put(vcpu); | 2939 | kvm_x86_ops->vcpu_put(vcpu); |
2940 | kvm_put_guest_fpu(vcpu); | ||
2941 | vcpu->arch.last_host_tsc = rdtsc(); | 2940 | vcpu->arch.last_host_tsc = rdtsc(); |
2942 | } | 2941 | } |
2943 | 2942 | ||
@@ -5252,17 +5251,6 @@ static void emulator_halt(struct x86_emulate_ctxt *ctxt) | |||
5252 | emul_to_vcpu(ctxt)->arch.halt_request = 1; | 5251 | emul_to_vcpu(ctxt)->arch.halt_request = 1; |
5253 | } | 5252 | } |
5254 | 5253 | ||
5255 | static void emulator_get_fpu(struct x86_emulate_ctxt *ctxt) | ||
5256 | { | ||
5257 | preempt_disable(); | ||
5258 | kvm_load_guest_fpu(emul_to_vcpu(ctxt)); | ||
5259 | } | ||
5260 | |||
5261 | static void emulator_put_fpu(struct x86_emulate_ctxt *ctxt) | ||
5262 | { | ||
5263 | preempt_enable(); | ||
5264 | } | ||
5265 | |||
5266 | static int emulator_intercept(struct x86_emulate_ctxt *ctxt, | 5254 | static int emulator_intercept(struct x86_emulate_ctxt *ctxt, |
5267 | struct x86_instruction_info *info, | 5255 | struct x86_instruction_info *info, |
5268 | enum x86_intercept_stage stage) | 5256 | enum x86_intercept_stage stage) |
@@ -5340,8 +5328,6 @@ static const struct x86_emulate_ops emulate_ops = { | |||
5340 | .halt = emulator_halt, | 5328 | .halt = emulator_halt, |
5341 | .wbinvd = emulator_wbinvd, | 5329 | .wbinvd = emulator_wbinvd, |
5342 | .fix_hypercall = emulator_fix_hypercall, | 5330 | .fix_hypercall = emulator_fix_hypercall, |
5343 | .get_fpu = emulator_get_fpu, | ||
5344 | .put_fpu = emulator_put_fpu, | ||
5345 | .intercept = emulator_intercept, | 5331 | .intercept = emulator_intercept, |
5346 | .get_cpuid = emulator_get_cpuid, | 5332 | .get_cpuid = emulator_get_cpuid, |
5347 | .set_nmi_mask = emulator_set_nmi_mask, | 5333 | .set_nmi_mask = emulator_set_nmi_mask, |
@@ -6778,6 +6764,20 @@ static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu) | |||
6778 | kvm_x86_ops->tlb_flush(vcpu); | 6764 | kvm_x86_ops->tlb_flush(vcpu); |
6779 | } | 6765 | } |
6780 | 6766 | ||
6767 | void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm, | ||
6768 | unsigned long start, unsigned long end) | ||
6769 | { | ||
6770 | unsigned long apic_address; | ||
6771 | |||
6772 | /* | ||
6773 | * The physical address of apic access page is stored in the VMCS. | ||
6774 | * Update it when it becomes invalid. | ||
6775 | */ | ||
6776 | apic_address = gfn_to_hva(kvm, APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT); | ||
6777 | if (start <= apic_address && apic_address < end) | ||
6778 | kvm_make_all_cpus_request(kvm, KVM_REQ_APIC_PAGE_RELOAD); | ||
6779 | } | ||
6780 | |||
6781 | void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu) | 6781 | void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu) |
6782 | { | 6782 | { |
6783 | struct page *page = NULL; | 6783 | struct page *page = NULL; |
@@ -6952,7 +6952,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) | |||
6952 | preempt_disable(); | 6952 | preempt_disable(); |
6953 | 6953 | ||
6954 | kvm_x86_ops->prepare_guest_switch(vcpu); | 6954 | kvm_x86_ops->prepare_guest_switch(vcpu); |
6955 | kvm_load_guest_fpu(vcpu); | ||
6956 | 6955 | ||
6957 | /* | 6956 | /* |
6958 | * Disable IRQs before setting IN_GUEST_MODE. Posted interrupt | 6957 | * Disable IRQs before setting IN_GUEST_MODE. Posted interrupt |
@@ -7297,12 +7296,14 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
7297 | } | 7296 | } |
7298 | } | 7297 | } |
7299 | 7298 | ||
7299 | kvm_load_guest_fpu(vcpu); | ||
7300 | |||
7300 | if (unlikely(vcpu->arch.complete_userspace_io)) { | 7301 | if (unlikely(vcpu->arch.complete_userspace_io)) { |
7301 | int (*cui)(struct kvm_vcpu *) = vcpu->arch.complete_userspace_io; | 7302 | int (*cui)(struct kvm_vcpu *) = vcpu->arch.complete_userspace_io; |
7302 | vcpu->arch.complete_userspace_io = NULL; | 7303 | vcpu->arch.complete_userspace_io = NULL; |
7303 | r = cui(vcpu); | 7304 | r = cui(vcpu); |
7304 | if (r <= 0) | 7305 | if (r <= 0) |
7305 | goto out; | 7306 | goto out_fpu; |
7306 | } else | 7307 | } else |
7307 | WARN_ON(vcpu->arch.pio.count || vcpu->mmio_needed); | 7308 | WARN_ON(vcpu->arch.pio.count || vcpu->mmio_needed); |
7308 | 7309 | ||
@@ -7311,6 +7312,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
7311 | else | 7312 | else |
7312 | r = vcpu_run(vcpu); | 7313 | r = vcpu_run(vcpu); |
7313 | 7314 | ||
7315 | out_fpu: | ||
7316 | kvm_put_guest_fpu(vcpu); | ||
7314 | out: | 7317 | out: |
7315 | post_kvm_run_save(vcpu); | 7318 | post_kvm_run_save(vcpu); |
7316 | kvm_sigset_deactivate(vcpu); | 7319 | kvm_sigset_deactivate(vcpu); |
@@ -7704,32 +7707,25 @@ static void fx_init(struct kvm_vcpu *vcpu) | |||
7704 | vcpu->arch.cr0 |= X86_CR0_ET; | 7707 | vcpu->arch.cr0 |= X86_CR0_ET; |
7705 | } | 7708 | } |
7706 | 7709 | ||
7710 | /* Swap (qemu) user FPU context for the guest FPU context. */ | ||
7707 | void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) | 7711 | void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) |
7708 | { | 7712 | { |
7709 | if (vcpu->guest_fpu_loaded) | 7713 | preempt_disable(); |
7710 | return; | 7714 | copy_fpregs_to_fpstate(&vcpu->arch.user_fpu); |
7711 | |||
7712 | /* | ||
7713 | * Restore all possible states in the guest, | ||
7714 | * and assume host would use all available bits. | ||
7715 | * Guest xcr0 would be loaded later. | ||
7716 | */ | ||
7717 | vcpu->guest_fpu_loaded = 1; | ||
7718 | __kernel_fpu_begin(); | ||
7719 | /* PKRU is separately restored in kvm_x86_ops->run. */ | 7715 | /* PKRU is separately restored in kvm_x86_ops->run. */ |
7720 | __copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state, | 7716 | __copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state, |
7721 | ~XFEATURE_MASK_PKRU); | 7717 | ~XFEATURE_MASK_PKRU); |
7718 | preempt_enable(); | ||
7722 | trace_kvm_fpu(1); | 7719 | trace_kvm_fpu(1); |
7723 | } | 7720 | } |
7724 | 7721 | ||
7722 | /* When vcpu_run ends, restore user space FPU context. */ | ||
7725 | void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) | 7723 | void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) |
7726 | { | 7724 | { |
7727 | if (!vcpu->guest_fpu_loaded) | 7725 | preempt_disable(); |
7728 | return; | ||
7729 | |||
7730 | vcpu->guest_fpu_loaded = 0; | ||
7731 | copy_fpregs_to_fpstate(&vcpu->arch.guest_fpu); | 7726 | copy_fpregs_to_fpstate(&vcpu->arch.guest_fpu); |
7732 | __kernel_fpu_end(); | 7727 | copy_kernel_to_fpregs(&vcpu->arch.user_fpu.state); |
7728 | preempt_enable(); | ||
7733 | ++vcpu->stat.fpu_reload; | 7729 | ++vcpu->stat.fpu_reload; |
7734 | trace_kvm_fpu(0); | 7730 | trace_kvm_fpu(0); |
7735 | } | 7731 | } |
@@ -7846,7 +7842,8 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) | |||
7846 | * To avoid have the INIT path from kvm_apic_has_events() that be | 7842 | * To avoid have the INIT path from kvm_apic_has_events() that be |
7847 | * called with loaded FPU and does not let userspace fix the state. | 7843 | * called with loaded FPU and does not let userspace fix the state. |
7848 | */ | 7844 | */ |
7849 | kvm_put_guest_fpu(vcpu); | 7845 | if (init_event) |
7846 | kvm_put_guest_fpu(vcpu); | ||
7850 | mpx_state_buffer = get_xsave_addr(&vcpu->arch.guest_fpu.state.xsave, | 7847 | mpx_state_buffer = get_xsave_addr(&vcpu->arch.guest_fpu.state.xsave, |
7851 | XFEATURE_MASK_BNDREGS); | 7848 | XFEATURE_MASK_BNDREGS); |
7852 | if (mpx_state_buffer) | 7849 | if (mpx_state_buffer) |
@@ -7855,6 +7852,8 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) | |||
7855 | XFEATURE_MASK_BNDCSR); | 7852 | XFEATURE_MASK_BNDCSR); |
7856 | if (mpx_state_buffer) | 7853 | if (mpx_state_buffer) |
7857 | memset(mpx_state_buffer, 0, sizeof(struct mpx_bndcsr)); | 7854 | memset(mpx_state_buffer, 0, sizeof(struct mpx_bndcsr)); |
7855 | if (init_event) | ||
7856 | kvm_load_guest_fpu(vcpu); | ||
7858 | } | 7857 | } |
7859 | 7858 | ||
7860 | if (!init_event) { | 7859 | if (!init_event) { |
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index 01ee473517e2..6e45608b2399 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h | |||
@@ -93,7 +93,4 @@ void kvm_timer_init_vhe(void); | |||
93 | #define vcpu_vtimer(v) (&(v)->arch.timer_cpu.vtimer) | 93 | #define vcpu_vtimer(v) (&(v)->arch.timer_cpu.vtimer) |
94 | #define vcpu_ptimer(v) (&(v)->arch.timer_cpu.ptimer) | 94 | #define vcpu_ptimer(v) (&(v)->arch.timer_cpu.ptimer) |
95 | 95 | ||
96 | void enable_el1_phys_timer_access(void); | ||
97 | void disable_el1_phys_timer_access(void); | ||
98 | |||
99 | #endif | 96 | #endif |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 893d6d606cd0..6bdd4b9f6611 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -232,7 +232,7 @@ struct kvm_vcpu { | |||
232 | struct mutex mutex; | 232 | struct mutex mutex; |
233 | struct kvm_run *run; | 233 | struct kvm_run *run; |
234 | 234 | ||
235 | int guest_fpu_loaded, guest_xcr0_loaded; | 235 | int guest_xcr0_loaded; |
236 | struct swait_queue_head wq; | 236 | struct swait_queue_head wq; |
237 | struct pid __rcu *pid; | 237 | struct pid __rcu *pid; |
238 | int sigset_active; | 238 | int sigset_active; |
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 282d7613fce8..496e59a2738b 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h | |||
@@ -630,9 +630,9 @@ struct kvm_s390_irq { | |||
630 | 630 | ||
631 | struct kvm_s390_irq_state { | 631 | struct kvm_s390_irq_state { |
632 | __u64 buf; | 632 | __u64 buf; |
633 | __u32 flags; | 633 | __u32 flags; /* will stay unused for compatibility reasons */ |
634 | __u32 len; | 634 | __u32 len; |
635 | __u32 reserved[4]; | 635 | __u32 reserved[4]; /* will stay unused for compatibility reasons */ |
636 | }; | 636 | }; |
637 | 637 | ||
638 | /* for KVM_SET_GUEST_DEBUG */ | 638 | /* for KVM_SET_GUEST_DEBUG */ |
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 4151250ce8da..f9555b1e7f15 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c | |||
@@ -479,9 +479,6 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu) | |||
479 | 479 | ||
480 | vtimer_restore_state(vcpu); | 480 | vtimer_restore_state(vcpu); |
481 | 481 | ||
482 | if (has_vhe()) | ||
483 | disable_el1_phys_timer_access(); | ||
484 | |||
485 | /* Set the background timer for the physical timer emulation. */ | 482 | /* Set the background timer for the physical timer emulation. */ |
486 | phys_timer_emulate(vcpu); | 483 | phys_timer_emulate(vcpu); |
487 | } | 484 | } |
@@ -510,9 +507,6 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu) | |||
510 | if (unlikely(!timer->enabled)) | 507 | if (unlikely(!timer->enabled)) |
511 | return; | 508 | return; |
512 | 509 | ||
513 | if (has_vhe()) | ||
514 | enable_el1_phys_timer_access(); | ||
515 | |||
516 | vtimer_save_state(vcpu); | 510 | vtimer_save_state(vcpu); |
517 | 511 | ||
518 | /* | 512 | /* |
@@ -841,7 +835,10 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) | |||
841 | no_vgic: | 835 | no_vgic: |
842 | preempt_disable(); | 836 | preempt_disable(); |
843 | timer->enabled = 1; | 837 | timer->enabled = 1; |
844 | kvm_timer_vcpu_load_vgic(vcpu); | 838 | if (!irqchip_in_kernel(vcpu->kvm)) |
839 | kvm_timer_vcpu_load_user(vcpu); | ||
840 | else | ||
841 | kvm_timer_vcpu_load_vgic(vcpu); | ||
845 | preempt_enable(); | 842 | preempt_enable(); |
846 | 843 | ||
847 | return 0; | 844 | return 0; |
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c index a67c106d73f5..6b60c98a6e22 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c | |||
@@ -188,6 +188,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) | |||
188 | kvm->vcpus[i] = NULL; | 188 | kvm->vcpus[i] = NULL; |
189 | } | 189 | } |
190 | } | 190 | } |
191 | atomic_set(&kvm->online_vcpus, 0); | ||
191 | } | 192 | } |
192 | 193 | ||
193 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | 194 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
@@ -296,7 +297,6 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) | |||
296 | { | 297 | { |
297 | kvm_mmu_free_memory_caches(vcpu); | 298 | kvm_mmu_free_memory_caches(vcpu); |
298 | kvm_timer_vcpu_terminate(vcpu); | 299 | kvm_timer_vcpu_terminate(vcpu); |
299 | kvm_vgic_vcpu_destroy(vcpu); | ||
300 | kvm_pmu_vcpu_destroy(vcpu); | 300 | kvm_pmu_vcpu_destroy(vcpu); |
301 | kvm_vcpu_uninit(vcpu); | 301 | kvm_vcpu_uninit(vcpu); |
302 | kmem_cache_free(kvm_vcpu_cache, vcpu); | 302 | kmem_cache_free(kvm_vcpu_cache, vcpu); |
@@ -627,6 +627,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
627 | ret = kvm_handle_mmio_return(vcpu, vcpu->run); | 627 | ret = kvm_handle_mmio_return(vcpu, vcpu->run); |
628 | if (ret) | 628 | if (ret) |
629 | return ret; | 629 | return ret; |
630 | if (kvm_arm_handle_step_debug(vcpu, vcpu->run)) | ||
631 | return 0; | ||
632 | |||
630 | } | 633 | } |
631 | 634 | ||
632 | if (run->immediate_exit) | 635 | if (run->immediate_exit) |
@@ -1502,7 +1505,7 @@ int kvm_arch_init(void *opaque) | |||
1502 | bool in_hyp_mode; | 1505 | bool in_hyp_mode; |
1503 | 1506 | ||
1504 | if (!is_hyp_mode_available()) { | 1507 | if (!is_hyp_mode_available()) { |
1505 | kvm_err("HYP mode not available\n"); | 1508 | kvm_info("HYP mode not available\n"); |
1506 | return -ENODEV; | 1509 | return -ENODEV; |
1507 | } | 1510 | } |
1508 | 1511 | ||
diff --git a/virt/kvm/arm/hyp/timer-sr.c b/virt/kvm/arm/hyp/timer-sr.c index f39861639f08..f24404b3c8df 100644 --- a/virt/kvm/arm/hyp/timer-sr.c +++ b/virt/kvm/arm/hyp/timer-sr.c | |||
@@ -27,42 +27,34 @@ void __hyp_text __kvm_timer_set_cntvoff(u32 cntvoff_low, u32 cntvoff_high) | |||
27 | write_sysreg(cntvoff, cntvoff_el2); | 27 | write_sysreg(cntvoff, cntvoff_el2); |
28 | } | 28 | } |
29 | 29 | ||
30 | void __hyp_text enable_el1_phys_timer_access(void) | ||
31 | { | ||
32 | u64 val; | ||
33 | |||
34 | /* Allow physical timer/counter access for the host */ | ||
35 | val = read_sysreg(cnthctl_el2); | ||
36 | val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN; | ||
37 | write_sysreg(val, cnthctl_el2); | ||
38 | } | ||
39 | |||
40 | void __hyp_text disable_el1_phys_timer_access(void) | ||
41 | { | ||
42 | u64 val; | ||
43 | |||
44 | /* | ||
45 | * Disallow physical timer access for the guest | ||
46 | * Physical counter access is allowed | ||
47 | */ | ||
48 | val = read_sysreg(cnthctl_el2); | ||
49 | val &= ~CNTHCTL_EL1PCEN; | ||
50 | val |= CNTHCTL_EL1PCTEN; | ||
51 | write_sysreg(val, cnthctl_el2); | ||
52 | } | ||
53 | |||
54 | void __hyp_text __timer_disable_traps(struct kvm_vcpu *vcpu) | 30 | void __hyp_text __timer_disable_traps(struct kvm_vcpu *vcpu) |
55 | { | 31 | { |
56 | /* | 32 | /* |
57 | * We don't need to do this for VHE since the host kernel runs in EL2 | 33 | * We don't need to do this for VHE since the host kernel runs in EL2 |
58 | * with HCR_EL2.TGE ==1, which makes those bits have no impact. | 34 | * with HCR_EL2.TGE ==1, which makes those bits have no impact. |
59 | */ | 35 | */ |
60 | if (!has_vhe()) | 36 | if (!has_vhe()) { |
61 | enable_el1_phys_timer_access(); | 37 | u64 val; |
38 | |||
39 | /* Allow physical timer/counter access for the host */ | ||
40 | val = read_sysreg(cnthctl_el2); | ||
41 | val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN; | ||
42 | write_sysreg(val, cnthctl_el2); | ||
43 | } | ||
62 | } | 44 | } |
63 | 45 | ||
64 | void __hyp_text __timer_enable_traps(struct kvm_vcpu *vcpu) | 46 | void __hyp_text __timer_enable_traps(struct kvm_vcpu *vcpu) |
65 | { | 47 | { |
66 | if (!has_vhe()) | 48 | if (!has_vhe()) { |
67 | disable_el1_phys_timer_access(); | 49 | u64 val; |
50 | |||
51 | /* | ||
52 | * Disallow physical timer access for the guest | ||
53 | * Physical counter access is allowed | ||
54 | */ | ||
55 | val = read_sysreg(cnthctl_el2); | ||
56 | val &= ~CNTHCTL_EL1PCEN; | ||
57 | val |= CNTHCTL_EL1PCTEN; | ||
58 | write_sysreg(val, cnthctl_el2); | ||
59 | } | ||
68 | } | 60 | } |
diff --git a/virt/kvm/arm/hyp/vgic-v2-sr.c b/virt/kvm/arm/hyp/vgic-v2-sr.c index a3f18d362366..d7fd46fe9efb 100644 --- a/virt/kvm/arm/hyp/vgic-v2-sr.c +++ b/virt/kvm/arm/hyp/vgic-v2-sr.c | |||
@@ -34,11 +34,7 @@ static void __hyp_text save_elrsr(struct kvm_vcpu *vcpu, void __iomem *base) | |||
34 | else | 34 | else |
35 | elrsr1 = 0; | 35 | elrsr1 = 0; |
36 | 36 | ||
37 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
38 | cpu_if->vgic_elrsr = ((u64)elrsr0 << 32) | elrsr1; | ||
39 | #else | ||
40 | cpu_if->vgic_elrsr = ((u64)elrsr1 << 32) | elrsr0; | 37 | cpu_if->vgic_elrsr = ((u64)elrsr1 << 32) | elrsr0; |
41 | #endif | ||
42 | } | 38 | } |
43 | 39 | ||
44 | static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base) | 40 | static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base) |
diff --git a/virt/kvm/arm/vgic/vgic-irqfd.c b/virt/kvm/arm/vgic/vgic-irqfd.c index b7baf581611a..99e026d2dade 100644 --- a/virt/kvm/arm/vgic/vgic-irqfd.c +++ b/virt/kvm/arm/vgic/vgic-irqfd.c | |||
@@ -112,8 +112,7 @@ int kvm_vgic_setup_default_irq_routing(struct kvm *kvm) | |||
112 | u32 nr = dist->nr_spis; | 112 | u32 nr = dist->nr_spis; |
113 | int i, ret; | 113 | int i, ret; |
114 | 114 | ||
115 | entries = kcalloc(nr, sizeof(struct kvm_kernel_irq_routing_entry), | 115 | entries = kcalloc(nr, sizeof(*entries), GFP_KERNEL); |
116 | GFP_KERNEL); | ||
117 | if (!entries) | 116 | if (!entries) |
118 | return -ENOMEM; | 117 | return -ENOMEM; |
119 | 118 | ||
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c index 1f761a9991e7..8e633bd9cc1e 100644 --- a/virt/kvm/arm/vgic/vgic-its.c +++ b/virt/kvm/arm/vgic/vgic-its.c | |||
@@ -421,6 +421,7 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu) | |||
421 | u32 *intids; | 421 | u32 *intids; |
422 | int nr_irqs, i; | 422 | int nr_irqs, i; |
423 | unsigned long flags; | 423 | unsigned long flags; |
424 | u8 pendmask; | ||
424 | 425 | ||
425 | nr_irqs = vgic_copy_lpi_list(vcpu, &intids); | 426 | nr_irqs = vgic_copy_lpi_list(vcpu, &intids); |
426 | if (nr_irqs < 0) | 427 | if (nr_irqs < 0) |
@@ -428,7 +429,6 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu) | |||
428 | 429 | ||
429 | for (i = 0; i < nr_irqs; i++) { | 430 | for (i = 0; i < nr_irqs; i++) { |
430 | int byte_offset, bit_nr; | 431 | int byte_offset, bit_nr; |
431 | u8 pendmask; | ||
432 | 432 | ||
433 | byte_offset = intids[i] / BITS_PER_BYTE; | 433 | byte_offset = intids[i] / BITS_PER_BYTE; |
434 | bit_nr = intids[i] % BITS_PER_BYTE; | 434 | bit_nr = intids[i] % BITS_PER_BYTE; |
@@ -821,6 +821,8 @@ static int vgic_its_alloc_collection(struct vgic_its *its, | |||
821 | return E_ITS_MAPC_COLLECTION_OOR; | 821 | return E_ITS_MAPC_COLLECTION_OOR; |
822 | 822 | ||
823 | collection = kzalloc(sizeof(*collection), GFP_KERNEL); | 823 | collection = kzalloc(sizeof(*collection), GFP_KERNEL); |
824 | if (!collection) | ||
825 | return -ENOMEM; | ||
824 | 826 | ||
825 | collection->collection_id = coll_id; | 827 | collection->collection_id = coll_id; |
826 | collection->target_addr = COLLECTION_NOT_MAPPED; | 828 | collection->target_addr = COLLECTION_NOT_MAPPED; |
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c index 2f05f732d3fd..f47e8481fa45 100644 --- a/virt/kvm/arm/vgic/vgic-v3.c +++ b/virt/kvm/arm/vgic/vgic-v3.c | |||
@@ -327,13 +327,13 @@ int vgic_v3_save_pending_tables(struct kvm *kvm) | |||
327 | int last_byte_offset = -1; | 327 | int last_byte_offset = -1; |
328 | struct vgic_irq *irq; | 328 | struct vgic_irq *irq; |
329 | int ret; | 329 | int ret; |
330 | u8 val; | ||
330 | 331 | ||
331 | list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) { | 332 | list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) { |
332 | int byte_offset, bit_nr; | 333 | int byte_offset, bit_nr; |
333 | struct kvm_vcpu *vcpu; | 334 | struct kvm_vcpu *vcpu; |
334 | gpa_t pendbase, ptr; | 335 | gpa_t pendbase, ptr; |
335 | bool stored; | 336 | bool stored; |
336 | u8 val; | ||
337 | 337 | ||
338 | vcpu = irq->target_vcpu; | 338 | vcpu = irq->target_vcpu; |
339 | if (!vcpu) | 339 | if (!vcpu) |
diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c index 53c324aa44ef..4a37292855bc 100644 --- a/virt/kvm/arm/vgic/vgic-v4.c +++ b/virt/kvm/arm/vgic/vgic-v4.c | |||
@@ -337,8 +337,10 @@ int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int virq, | |||
337 | goto out; | 337 | goto out; |
338 | 338 | ||
339 | WARN_ON(!(irq->hw && irq->host_irq == virq)); | 339 | WARN_ON(!(irq->hw && irq->host_irq == virq)); |
340 | irq->hw = false; | 340 | if (irq->hw) { |
341 | ret = its_unmap_vlpi(virq); | 341 | irq->hw = false; |
342 | ret = its_unmap_vlpi(virq); | ||
343 | } | ||
342 | 344 | ||
343 | out: | 345 | out: |
344 | mutex_unlock(&its->its_lock); | 346 | mutex_unlock(&its->its_lock); |
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c index b168a328a9e0..ecb8e25f5fe5 100644 --- a/virt/kvm/arm/vgic/vgic.c +++ b/virt/kvm/arm/vgic/vgic.c | |||
@@ -492,6 +492,7 @@ int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid) | |||
492 | int kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner) | 492 | int kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner) |
493 | { | 493 | { |
494 | struct vgic_irq *irq; | 494 | struct vgic_irq *irq; |
495 | unsigned long flags; | ||
495 | int ret = 0; | 496 | int ret = 0; |
496 | 497 | ||
497 | if (!vgic_initialized(vcpu->kvm)) | 498 | if (!vgic_initialized(vcpu->kvm)) |
@@ -502,12 +503,12 @@ int kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner) | |||
502 | return -EINVAL; | 503 | return -EINVAL; |
503 | 504 | ||
504 | irq = vgic_get_irq(vcpu->kvm, vcpu, intid); | 505 | irq = vgic_get_irq(vcpu->kvm, vcpu, intid); |
505 | spin_lock(&irq->irq_lock); | 506 | spin_lock_irqsave(&irq->irq_lock, flags); |
506 | if (irq->owner && irq->owner != owner) | 507 | if (irq->owner && irq->owner != owner) |
507 | ret = -EEXIST; | 508 | ret = -EEXIST; |
508 | else | 509 | else |
509 | irq->owner = owner; | 510 | irq->owner = owner; |
510 | spin_unlock(&irq->irq_lock); | 511 | spin_unlock_irqrestore(&irq->irq_lock, flags); |
511 | 512 | ||
512 | return ret; | 513 | return ret; |
513 | } | 514 | } |
@@ -823,13 +824,14 @@ void vgic_kick_vcpus(struct kvm *kvm) | |||
823 | 824 | ||
824 | bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid) | 825 | bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid) |
825 | { | 826 | { |
826 | struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); | 827 | struct vgic_irq *irq; |
827 | bool map_is_active; | 828 | bool map_is_active; |
828 | unsigned long flags; | 829 | unsigned long flags; |
829 | 830 | ||
830 | if (!vgic_initialized(vcpu->kvm)) | 831 | if (!vgic_initialized(vcpu->kvm)) |
831 | return false; | 832 | return false; |
832 | 833 | ||
834 | irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); | ||
833 | spin_lock_irqsave(&irq->irq_lock, flags); | 835 | spin_lock_irqsave(&irq->irq_lock, flags); |
834 | map_is_active = irq->hw && irq->active; | 836 | map_is_active = irq->hw && irq->active; |
835 | spin_unlock_irqrestore(&irq->irq_lock, flags); | 837 | spin_unlock_irqrestore(&irq->irq_lock, flags); |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index c422c10cd1dd..210bf820385a 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -135,6 +135,11 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm); | |||
135 | static unsigned long long kvm_createvm_count; | 135 | static unsigned long long kvm_createvm_count; |
136 | static unsigned long long kvm_active_vms; | 136 | static unsigned long long kvm_active_vms; |
137 | 137 | ||
138 | __weak void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm, | ||
139 | unsigned long start, unsigned long end) | ||
140 | { | ||
141 | } | ||
142 | |||
138 | bool kvm_is_reserved_pfn(kvm_pfn_t pfn) | 143 | bool kvm_is_reserved_pfn(kvm_pfn_t pfn) |
139 | { | 144 | { |
140 | if (pfn_valid(pfn)) | 145 | if (pfn_valid(pfn)) |
@@ -360,6 +365,9 @@ static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn, | |||
360 | kvm_flush_remote_tlbs(kvm); | 365 | kvm_flush_remote_tlbs(kvm); |
361 | 366 | ||
362 | spin_unlock(&kvm->mmu_lock); | 367 | spin_unlock(&kvm->mmu_lock); |
368 | |||
369 | kvm_arch_mmu_notifier_invalidate_range(kvm, start, end); | ||
370 | |||
363 | srcu_read_unlock(&kvm->srcu, idx); | 371 | srcu_read_unlock(&kvm->srcu, idx); |
364 | } | 372 | } |
365 | 373 | ||