diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2015-06-19 11:15:24 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-06-19 11:15:24 -0400 |
commit | 05fe125fa3237de2ec5bada80031e694de78909c (patch) | |
tree | 9e8cec45a5ded37b04c92a7a94dd1eefb5259344 /arch/arm/kvm | |
parent | e80a4a9426adeaa34c009bc0bc61365e0580bf01 (diff) | |
parent | c62e631d4a8e41493c6341d8259e996ed5fc11e3 (diff) |
Merge tag 'kvm-arm-for-4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/ARM changes for v4.2:
- Proper guest time accounting
- FP access fix for 32bit
- The usual pile of GIC fixes
- PSCI fixes
- Random cleanups
Diffstat (limited to 'arch/arm/kvm')
-rw-r--r-- | arch/arm/kvm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/kvm/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/kvm/arm.c | 22 | ||||
-rw-r--r-- | arch/arm/kvm/interrupts.S | 10 | ||||
-rw-r--r-- | arch/arm/kvm/interrupts_head.S | 23 | ||||
-rw-r--r-- | arch/arm/kvm/mmu.c | 4 | ||||
-rw-r--r-- | arch/arm/kvm/psci.c | 16 |
7 files changed, 46 insertions, 32 deletions
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index f1f79d104309..bfb915d05665 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig | |||
@@ -28,6 +28,7 @@ config KVM | |||
28 | select KVM_GENERIC_DIRTYLOG_READ_PROTECT | 28 | select KVM_GENERIC_DIRTYLOG_READ_PROTECT |
29 | select SRCU | 29 | select SRCU |
30 | select MMU_NOTIFIER | 30 | select MMU_NOTIFIER |
31 | select KVM_VFIO | ||
31 | select HAVE_KVM_EVENTFD | 32 | select HAVE_KVM_EVENTFD |
32 | select HAVE_KVM_IRQFD | 33 | select HAVE_KVM_IRQFD |
33 | depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER | 34 | depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER |
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile index 139e46c08b6e..c5eef02c52ba 100644 --- a/arch/arm/kvm/Makefile +++ b/arch/arm/kvm/Makefile | |||
@@ -15,7 +15,7 @@ AFLAGS_init.o := -Wa,-march=armv7-a$(plus_virt) | |||
15 | AFLAGS_interrupts.o := -Wa,-march=armv7-a$(plus_virt) | 15 | AFLAGS_interrupts.o := -Wa,-march=armv7-a$(plus_virt) |
16 | 16 | ||
17 | KVM := ../../../virt/kvm | 17 | KVM := ../../../virt/kvm |
18 | kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o | 18 | kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o $(KVM)/vfio.o |
19 | 19 | ||
20 | obj-y += kvm-arm.o init.o interrupts.o | 20 | obj-y += kvm-arm.o init.o interrupts.o |
21 | obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o | 21 | obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o |
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index e41cb11f71b2..bc738d2b8392 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
@@ -171,7 +171,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | |||
171 | int r; | 171 | int r; |
172 | switch (ext) { | 172 | switch (ext) { |
173 | case KVM_CAP_IRQCHIP: | 173 | case KVM_CAP_IRQCHIP: |
174 | case KVM_CAP_IRQFD: | ||
175 | case KVM_CAP_IOEVENTFD: | 174 | case KVM_CAP_IOEVENTFD: |
176 | case KVM_CAP_DEVICE_CTRL: | 175 | case KVM_CAP_DEVICE_CTRL: |
177 | case KVM_CAP_USER_MEMORY: | 176 | case KVM_CAP_USER_MEMORY: |
@@ -532,6 +531,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
532 | kvm_vgic_flush_hwstate(vcpu); | 531 | kvm_vgic_flush_hwstate(vcpu); |
533 | kvm_timer_flush_hwstate(vcpu); | 532 | kvm_timer_flush_hwstate(vcpu); |
534 | 533 | ||
534 | preempt_disable(); | ||
535 | local_irq_disable(); | 535 | local_irq_disable(); |
536 | 536 | ||
537 | /* | 537 | /* |
@@ -544,6 +544,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
544 | 544 | ||
545 | if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) { | 545 | if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) { |
546 | local_irq_enable(); | 546 | local_irq_enable(); |
547 | preempt_enable(); | ||
547 | kvm_timer_sync_hwstate(vcpu); | 548 | kvm_timer_sync_hwstate(vcpu); |
548 | kvm_vgic_sync_hwstate(vcpu); | 549 | kvm_vgic_sync_hwstate(vcpu); |
549 | continue; | 550 | continue; |
@@ -559,8 +560,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
559 | ret = kvm_call_hyp(__kvm_vcpu_run, vcpu); | 560 | ret = kvm_call_hyp(__kvm_vcpu_run, vcpu); |
560 | 561 | ||
561 | vcpu->mode = OUTSIDE_GUEST_MODE; | 562 | vcpu->mode = OUTSIDE_GUEST_MODE; |
562 | __kvm_guest_exit(); | 563 | /* |
563 | trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu)); | 564 | * Back from guest |
565 | *************************************************************/ | ||
566 | |||
564 | /* | 567 | /* |
565 | * We may have taken a host interrupt in HYP mode (ie | 568 | * We may have taken a host interrupt in HYP mode (ie |
566 | * while executing the guest). This interrupt is still | 569 | * while executing the guest). This interrupt is still |
@@ -574,8 +577,17 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
574 | local_irq_enable(); | 577 | local_irq_enable(); |
575 | 578 | ||
576 | /* | 579 | /* |
577 | * Back from guest | 580 | * We do local_irq_enable() before calling kvm_guest_exit() so |
578 | *************************************************************/ | 581 | * that if a timer interrupt hits while running the guest we |
582 | * account that tick as being spent in the guest. We enable | ||
583 | * preemption after calling kvm_guest_exit() so that if we get | ||
584 | * preempted we make sure ticks after that is not counted as | ||
585 | * guest time. | ||
586 | */ | ||
587 | kvm_guest_exit(); | ||
588 | trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu)); | ||
589 | preempt_enable(); | ||
590 | |||
579 | 591 | ||
580 | kvm_timer_sync_hwstate(vcpu); | 592 | kvm_timer_sync_hwstate(vcpu); |
581 | kvm_vgic_sync_hwstate(vcpu); | 593 | kvm_vgic_sync_hwstate(vcpu); |
diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S index 79caf79b304a..f7db3a5d80e3 100644 --- a/arch/arm/kvm/interrupts.S +++ b/arch/arm/kvm/interrupts.S | |||
@@ -170,13 +170,9 @@ __kvm_vcpu_return: | |||
170 | @ Don't trap coprocessor accesses for host kernel | 170 | @ Don't trap coprocessor accesses for host kernel |
171 | set_hstr vmexit | 171 | set_hstr vmexit |
172 | set_hdcr vmexit | 172 | set_hdcr vmexit |
173 | set_hcptr vmexit, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11)) | 173 | set_hcptr vmexit, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11)), after_vfp_restore |
174 | 174 | ||
175 | #ifdef CONFIG_VFPv3 | 175 | #ifdef CONFIG_VFPv3 |
176 | @ Save floating point registers we if let guest use them. | ||
177 | tst r2, #(HCPTR_TCP(10) | HCPTR_TCP(11)) | ||
178 | bne after_vfp_restore | ||
179 | |||
180 | @ Switch VFP/NEON hardware state to the host's | 176 | @ Switch VFP/NEON hardware state to the host's |
181 | add r7, vcpu, #VCPU_VFP_GUEST | 177 | add r7, vcpu, #VCPU_VFP_GUEST |
182 | store_vfp_state r7 | 178 | store_vfp_state r7 |
@@ -188,6 +184,8 @@ after_vfp_restore: | |||
188 | @ Restore FPEXC_EN which we clobbered on entry | 184 | @ Restore FPEXC_EN which we clobbered on entry |
189 | pop {r2} | 185 | pop {r2} |
190 | VFPFMXR FPEXC, r2 | 186 | VFPFMXR FPEXC, r2 |
187 | #else | ||
188 | after_vfp_restore: | ||
191 | #endif | 189 | #endif |
192 | 190 | ||
193 | @ Reset Hyp-role | 191 | @ Reset Hyp-role |
@@ -483,7 +481,7 @@ switch_to_guest_vfp: | |||
483 | push {r3-r7} | 481 | push {r3-r7} |
484 | 482 | ||
485 | @ NEON/VFP used. Turn on VFP access. | 483 | @ NEON/VFP used. Turn on VFP access. |
486 | set_hcptr vmexit, (HCPTR_TCP(10) | HCPTR_TCP(11)) | 484 | set_hcptr vmtrap, (HCPTR_TCP(10) | HCPTR_TCP(11)) |
487 | 485 | ||
488 | @ Switch VFP/NEON hardware state to the guest's | 486 | @ Switch VFP/NEON hardware state to the guest's |
489 | add r7, r0, #VCPU_VFP_HOST | 487 | add r7, r0, #VCPU_VFP_HOST |
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index 35e4a3a0c476..702740d37465 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S | |||
@@ -412,7 +412,6 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
412 | add r11, vcpu, #VCPU_VGIC_CPU | 412 | add r11, vcpu, #VCPU_VGIC_CPU |
413 | 413 | ||
414 | /* Save all interesting registers */ | 414 | /* Save all interesting registers */ |
415 | ldr r3, [r2, #GICH_HCR] | ||
416 | ldr r4, [r2, #GICH_VMCR] | 415 | ldr r4, [r2, #GICH_VMCR] |
417 | ldr r5, [r2, #GICH_MISR] | 416 | ldr r5, [r2, #GICH_MISR] |
418 | ldr r6, [r2, #GICH_EISR0] | 417 | ldr r6, [r2, #GICH_EISR0] |
@@ -420,7 +419,6 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
420 | ldr r8, [r2, #GICH_ELRSR0] | 419 | ldr r8, [r2, #GICH_ELRSR0] |
421 | ldr r9, [r2, #GICH_ELRSR1] | 420 | ldr r9, [r2, #GICH_ELRSR1] |
422 | ldr r10, [r2, #GICH_APR] | 421 | ldr r10, [r2, #GICH_APR] |
423 | ARM_BE8(rev r3, r3 ) | ||
424 | ARM_BE8(rev r4, r4 ) | 422 | ARM_BE8(rev r4, r4 ) |
425 | ARM_BE8(rev r5, r5 ) | 423 | ARM_BE8(rev r5, r5 ) |
426 | ARM_BE8(rev r6, r6 ) | 424 | ARM_BE8(rev r6, r6 ) |
@@ -429,7 +427,6 @@ ARM_BE8(rev r8, r8 ) | |||
429 | ARM_BE8(rev r9, r9 ) | 427 | ARM_BE8(rev r9, r9 ) |
430 | ARM_BE8(rev r10, r10 ) | 428 | ARM_BE8(rev r10, r10 ) |
431 | 429 | ||
432 | str r3, [r11, #VGIC_V2_CPU_HCR] | ||
433 | str r4, [r11, #VGIC_V2_CPU_VMCR] | 430 | str r4, [r11, #VGIC_V2_CPU_VMCR] |
434 | str r5, [r11, #VGIC_V2_CPU_MISR] | 431 | str r5, [r11, #VGIC_V2_CPU_MISR] |
435 | #ifdef CONFIG_CPU_ENDIAN_BE8 | 432 | #ifdef CONFIG_CPU_ENDIAN_BE8 |
@@ -591,8 +588,13 @@ ARM_BE8(rev r6, r6 ) | |||
591 | .endm | 588 | .endm |
592 | 589 | ||
593 | /* Configures the HCPTR (Hyp Coprocessor Trap Register) on entry/return | 590 | /* Configures the HCPTR (Hyp Coprocessor Trap Register) on entry/return |
594 | * (hardware reset value is 0). Keep previous value in r2. */ | 591 | * (hardware reset value is 0). Keep previous value in r2. |
595 | .macro set_hcptr operation, mask | 592 | * An ISB is emited on vmexit/vmtrap, but executed on vmexit only if |
593 | * VFP wasn't already enabled (always executed on vmtrap). | ||
594 | * If a label is specified with vmexit, it is branched to if VFP wasn't | ||
595 | * enabled. | ||
596 | */ | ||
597 | .macro set_hcptr operation, mask, label = none | ||
596 | mrc p15, 4, r2, c1, c1, 2 | 598 | mrc p15, 4, r2, c1, c1, 2 |
597 | ldr r3, =\mask | 599 | ldr r3, =\mask |
598 | .if \operation == vmentry | 600 | .if \operation == vmentry |
@@ -601,6 +603,17 @@ ARM_BE8(rev r6, r6 ) | |||
601 | bic r3, r2, r3 @ Don't trap defined coproc-accesses | 603 | bic r3, r2, r3 @ Don't trap defined coproc-accesses |
602 | .endif | 604 | .endif |
603 | mcr p15, 4, r3, c1, c1, 2 | 605 | mcr p15, 4, r3, c1, c1, 2 |
606 | .if \operation != vmentry | ||
607 | .if \operation == vmexit | ||
608 | tst r2, #(HCPTR_TCP(10) | HCPTR_TCP(11)) | ||
609 | beq 1f | ||
610 | .endif | ||
611 | isb | ||
612 | .if \label != none | ||
613 | b \label | ||
614 | .endif | ||
615 | 1: | ||
616 | .endif | ||
604 | .endm | 617 | .endm |
605 | 618 | ||
606 | /* Configures the HDCR (Hyp Debug Configuration Register) on entry/return | 619 | /* Configures the HDCR (Hyp Debug Configuration Register) on entry/return |
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 7f473e6d3bf5..7b4201294187 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
@@ -691,8 +691,8 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm) | |||
691 | * work. This is not used by the hardware and we have no | 691 | * work. This is not used by the hardware and we have no |
692 | * alignment requirement for this allocation. | 692 | * alignment requirement for this allocation. |
693 | */ | 693 | */ |
694 | pgd = (pgd_t *)kmalloc(PTRS_PER_S2_PGD * sizeof(pgd_t), | 694 | pgd = kmalloc(PTRS_PER_S2_PGD * sizeof(pgd_t), |
695 | GFP_KERNEL | __GFP_ZERO); | 695 | GFP_KERNEL | __GFP_ZERO); |
696 | 696 | ||
697 | if (!pgd) { | 697 | if (!pgd) { |
698 | kvm_free_hwpgd(hwpgd); | 698 | kvm_free_hwpgd(hwpgd); |
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c index 02fa8eff6ae1..531e922486b2 100644 --- a/arch/arm/kvm/psci.c +++ b/arch/arm/kvm/psci.c | |||
@@ -230,10 +230,6 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) | |||
230 | case PSCI_0_2_FN64_AFFINITY_INFO: | 230 | case PSCI_0_2_FN64_AFFINITY_INFO: |
231 | val = kvm_psci_vcpu_affinity_info(vcpu); | 231 | val = kvm_psci_vcpu_affinity_info(vcpu); |
232 | break; | 232 | break; |
233 | case PSCI_0_2_FN_MIGRATE: | ||
234 | case PSCI_0_2_FN64_MIGRATE: | ||
235 | val = PSCI_RET_NOT_SUPPORTED; | ||
236 | break; | ||
237 | case PSCI_0_2_FN_MIGRATE_INFO_TYPE: | 233 | case PSCI_0_2_FN_MIGRATE_INFO_TYPE: |
238 | /* | 234 | /* |
239 | * Trusted OS is MP hence does not require migration | 235 | * Trusted OS is MP hence does not require migration |
@@ -242,10 +238,6 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) | |||
242 | */ | 238 | */ |
243 | val = PSCI_0_2_TOS_MP; | 239 | val = PSCI_0_2_TOS_MP; |
244 | break; | 240 | break; |
245 | case PSCI_0_2_FN_MIGRATE_INFO_UP_CPU: | ||
246 | case PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU: | ||
247 | val = PSCI_RET_NOT_SUPPORTED; | ||
248 | break; | ||
249 | case PSCI_0_2_FN_SYSTEM_OFF: | 241 | case PSCI_0_2_FN_SYSTEM_OFF: |
250 | kvm_psci_system_off(vcpu); | 242 | kvm_psci_system_off(vcpu); |
251 | /* | 243 | /* |
@@ -271,7 +263,8 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) | |||
271 | ret = 0; | 263 | ret = 0; |
272 | break; | 264 | break; |
273 | default: | 265 | default: |
274 | return -EINVAL; | 266 | val = PSCI_RET_NOT_SUPPORTED; |
267 | break; | ||
275 | } | 268 | } |
276 | 269 | ||
277 | *vcpu_reg(vcpu, 0) = val; | 270 | *vcpu_reg(vcpu, 0) = val; |
@@ -291,12 +284,9 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu) | |||
291 | case KVM_PSCI_FN_CPU_ON: | 284 | case KVM_PSCI_FN_CPU_ON: |
292 | val = kvm_psci_vcpu_on(vcpu); | 285 | val = kvm_psci_vcpu_on(vcpu); |
293 | break; | 286 | break; |
294 | case KVM_PSCI_FN_CPU_SUSPEND: | 287 | default: |
295 | case KVM_PSCI_FN_MIGRATE: | ||
296 | val = PSCI_RET_NOT_SUPPORTED; | 288 | val = PSCI_RET_NOT_SUPPORTED; |
297 | break; | 289 | break; |
298 | default: | ||
299 | return -EINVAL; | ||
300 | } | 290 | } |
301 | 291 | ||
302 | *vcpu_reg(vcpu, 0) = val; | 292 | *vcpu_reg(vcpu, 0) = val; |