aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kvm/arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kvm/arm.c')
-rw-r--r--arch/arm/kvm/arm.c78
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
420static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) 426static 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
667static 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
652static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, 709static 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}