diff options
| author | Radim Krčmář <rkrcmar@redhat.com> | 2017-12-05 12:02:03 -0500 |
|---|---|---|
| committer | Radim Krčmář <rkrcmar@redhat.com> | 2017-12-05 12:02:03 -0500 |
| commit | 609b7002705ae72a6ca45b633b7ff1a09a7a0d86 (patch) | |
| tree | 515db242be433c34cd45c522dcf295580f864837 | |
| parent | ae64f9bd1d3621b5e60d7363bc20afb46aede215 (diff) | |
| parent | fc396e066318c0a02208c1d3f0b62950a7714999 (diff) | |
Merge tag 'kvm-arm-fixes-for-v4.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm
KVM/ARM Fixes for v4.15.
Fixes:
- A number of issues in the vgic discovered using SMATCH
- A bit one-off calculation in out stage base address mask (32-bit and
64-bit)
- Fixes to single-step debugging instructions that trap for other
reasons such as MMMIO aborts
- Printing unavailable hyp mode as error
- Potential spinlock deadlock in the vgic
- Avoid calling vgic vcpu free more than once
- Broken bit calculation for big endian systems
| -rw-r--r-- | arch/arm/include/asm/kvm_arm.h | 3 | ||||
| -rw-r--r-- | arch/arm/include/asm/kvm_host.h | 5 | ||||
| -rw-r--r-- | arch/arm64/include/asm/kvm_arm.h | 3 | ||||
| -rw-r--r-- | arch/arm64/include/asm/kvm_host.h | 1 | ||||
| -rw-r--r-- | arch/arm64/kvm/debug.c | 21 | ||||
| -rw-r--r-- | arch/arm64/kvm/handle_exit.c | 57 | ||||
| -rw-r--r-- | arch/arm64/kvm/hyp/switch.c | 37 | ||||
| -rw-r--r-- | include/kvm/arm_arch_timer.h | 3 | ||||
| -rw-r--r-- | virt/kvm/arm/arch_timer.c | 11 | ||||
| -rw-r--r-- | virt/kvm/arm/arm.c | 7 | ||||
| -rw-r--r-- | virt/kvm/arm/hyp/timer-sr.c | 48 | ||||
| -rw-r--r-- | virt/kvm/arm/hyp/vgic-v2-sr.c | 4 | ||||
| -rw-r--r-- | virt/kvm/arm/vgic/vgic-irqfd.c | 3 | ||||
| -rw-r--r-- | virt/kvm/arm/vgic/vgic-its.c | 4 | ||||
| -rw-r--r-- | virt/kvm/arm/vgic/vgic-v3.c | 2 | ||||
| -rw-r--r-- | virt/kvm/arm/vgic/vgic-v4.c | 6 | ||||
| -rw-r--r-- | virt/kvm/arm/vgic/vgic.c | 8 |
17 files changed, 144 insertions, 79 deletions
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/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/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); |
