diff options
Diffstat (limited to 'arch/arm/kvm/arm.c')
-rw-r--r-- | arch/arm/kvm/arm.c | 78 |
1 files changed, 73 insertions, 5 deletions
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 9e193c8a959e..2d6d91001062 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
@@ -213,6 +213,11 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) | |||
213 | int err; | 213 | int err; |
214 | struct kvm_vcpu *vcpu; | 214 | struct kvm_vcpu *vcpu; |
215 | 215 | ||
216 | if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) { | ||
217 | err = -EBUSY; | ||
218 | goto out; | ||
219 | } | ||
220 | |||
216 | vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); | 221 | vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); |
217 | if (!vcpu) { | 222 | if (!vcpu) { |
218 | err = -ENOMEM; | 223 | err = -ENOMEM; |
@@ -263,6 +268,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
263 | { | 268 | { |
264 | /* Force users to call KVM_ARM_VCPU_INIT */ | 269 | /* Force users to call KVM_ARM_VCPU_INIT */ |
265 | vcpu->arch.target = -1; | 270 | vcpu->arch.target = -1; |
271 | bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES); | ||
266 | 272 | ||
267 | /* Set up the timer */ | 273 | /* Set up the timer */ |
268 | kvm_timer_vcpu_init(vcpu); | 274 | kvm_timer_vcpu_init(vcpu); |
@@ -419,6 +425,7 @@ static void update_vttbr(struct kvm *kvm) | |||
419 | 425 | ||
420 | static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) | 426 | static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) |
421 | { | 427 | { |
428 | struct kvm *kvm = vcpu->kvm; | ||
422 | int ret; | 429 | int ret; |
423 | 430 | ||
424 | if (likely(vcpu->arch.has_run_once)) | 431 | if (likely(vcpu->arch.has_run_once)) |
@@ -427,15 +434,23 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) | |||
427 | vcpu->arch.has_run_once = true; | 434 | vcpu->arch.has_run_once = true; |
428 | 435 | ||
429 | /* | 436 | /* |
430 | * Initialize the VGIC before running a vcpu the first time on | 437 | * Map the VGIC hardware resources before running a vcpu the first |
431 | * this VM. | 438 | * time on this VM. |
432 | */ | 439 | */ |
433 | if (unlikely(!vgic_initialized(vcpu->kvm))) { | 440 | if (unlikely(!vgic_ready(kvm))) { |
434 | ret = kvm_vgic_init(vcpu->kvm); | 441 | ret = kvm_vgic_map_resources(kvm); |
435 | if (ret) | 442 | if (ret) |
436 | return ret; | 443 | return ret; |
437 | } | 444 | } |
438 | 445 | ||
446 | /* | ||
447 | * Enable the arch timers only if we have an in-kernel VGIC | ||
448 | * and it has been properly initialized, since we cannot handle | ||
449 | * interrupts from the virtual timer with a userspace gic. | ||
450 | */ | ||
451 | if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) | ||
452 | kvm_timer_enable(kvm); | ||
453 | |||
439 | return 0; | 454 | return 0; |
440 | } | 455 | } |
441 | 456 | ||
@@ -649,6 +664,48 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level, | |||
649 | return -EINVAL; | 664 | return -EINVAL; |
650 | } | 665 | } |
651 | 666 | ||
667 | static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, | ||
668 | const struct kvm_vcpu_init *init) | ||
669 | { | ||
670 | unsigned int i; | ||
671 | int phys_target = kvm_target_cpu(); | ||
672 | |||
673 | if (init->target != phys_target) | ||
674 | return -EINVAL; | ||
675 | |||
676 | /* | ||
677 | * Secondary and subsequent calls to KVM_ARM_VCPU_INIT must | ||
678 | * use the same target. | ||
679 | */ | ||
680 | if (vcpu->arch.target != -1 && vcpu->arch.target != init->target) | ||
681 | return -EINVAL; | ||
682 | |||
683 | /* -ENOENT for unknown features, -EINVAL for invalid combinations. */ | ||
684 | for (i = 0; i < sizeof(init->features) * 8; i++) { | ||
685 | bool set = (init->features[i / 32] & (1 << (i % 32))); | ||
686 | |||
687 | if (set && i >= KVM_VCPU_MAX_FEATURES) | ||
688 | return -ENOENT; | ||
689 | |||
690 | /* | ||
691 | * Secondary and subsequent calls to KVM_ARM_VCPU_INIT must | ||
692 | * use the same feature set. | ||
693 | */ | ||
694 | if (vcpu->arch.target != -1 && i < KVM_VCPU_MAX_FEATURES && | ||
695 | test_bit(i, vcpu->arch.features) != set) | ||
696 | return -EINVAL; | ||
697 | |||
698 | if (set) | ||
699 | set_bit(i, vcpu->arch.features); | ||
700 | } | ||
701 | |||
702 | vcpu->arch.target = phys_target; | ||
703 | |||
704 | /* Now we know what it is, we can reset it. */ | ||
705 | return kvm_reset_vcpu(vcpu); | ||
706 | } | ||
707 | |||
708 | |||
652 | static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, | 709 | static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, |
653 | struct kvm_vcpu_init *init) | 710 | struct kvm_vcpu_init *init) |
654 | { | 711 | { |
@@ -659,10 +716,21 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, | |||
659 | return ret; | 716 | return ret; |
660 | 717 | ||
661 | /* | 718 | /* |
719 | * Ensure a rebooted VM will fault in RAM pages and detect if the | ||
720 | * guest MMU is turned off and flush the caches as needed. | ||
721 | */ | ||
722 | if (vcpu->arch.has_run_once) | ||
723 | stage2_unmap_vm(vcpu->kvm); | ||
724 | |||
725 | vcpu_reset_hcr(vcpu); | ||
726 | |||
727 | /* | ||
662 | * Handle the "start in power-off" case by marking the VCPU as paused. | 728 | * Handle the "start in power-off" case by marking the VCPU as paused. |
663 | */ | 729 | */ |
664 | if (__test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) | 730 | if (test_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) |
665 | vcpu->arch.pause = true; | 731 | vcpu->arch.pause = true; |
732 | else | ||
733 | vcpu->arch.pause = false; | ||
666 | 734 | ||
667 | return 0; | 735 | return 0; |
668 | } | 736 | } |