static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) { struct kvm *kvm = vcpu->kvm; int ret; if (likely(vcpu->arch.has_run_once)) return 0; vcpu->arch.has_run_once = true; /* * Map the VGIC hardware resources before running a vcpu the first * time on this VM. */ if (unlikely(irqchip_in_kernel(kvm) && !vgic_ready(kvm))) { ret = kvm_vgic_map_resources(kvm); if (ret) return ret; } /* * Enable the arch timers only if we have an in-kernel VGIC * and it has been properly initialized, since we cannot handle * interrupts from the virtual timer with a userspace gic. */ if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) kvm_timer_enable(kvm); return 0; }
/* * vgic_init: allocates and initializes dist and vcpu data structures * depending on two dimensioning parameters: * - the number of spis * - the number of vcpus * The function is generally called when nr_spis has been explicitly set * by the guest through the KVM DEVICE API. If not nr_spis is set to 256. * vgic_initialized() returns true when this function has succeeded. * Must be called with kvm->lock held! */ int vgic_init(struct kvm *kvm) { struct vgic_dist *dist = &kvm->arch.vgic; struct kvm_vcpu *vcpu; int ret = 0, i; if (vgic_initialized(kvm)) return 0; /* freeze the number of spis */ if (!dist->nr_spis) dist->nr_spis = VGIC_NR_IRQS_LEGACY - VGIC_NR_PRIVATE_IRQS; ret = kvm_vgic_dist_init(kvm, dist->nr_spis); if (ret) goto out; if (vgic_has_its(kvm)) dist->msis_require_devid = true; kvm_for_each_vcpu(i, vcpu, kvm) kvm_vgic_vcpu_init(vcpu); ret = kvm_vgic_setup_default_irq_routing(kvm); if (ret) goto out; dist->initialized = true; out: return ret; }
static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level) { int ret; struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; BUG_ON(!vgic_initialized(vcpu->kvm)); timer->irq.level = new_level; trace_kvm_timer_update_irq(vcpu->vcpu_id, timer->map->virt_irq, timer->irq.level); ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id, timer->map, timer->irq.level); WARN_ON(ret); }
/* * Check if there was a change in the timer state (should we raise or lower * the line level to the GIC). */ static void kvm_timer_update_state(struct kvm_vcpu *vcpu) { struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; /* * If userspace modified the timer registers via SET_ONE_REG before * the vgic was initialized, we mustn't set the timer->irq.level value * because the guest would never see the interrupt. Instead wait * until we call this function from kvm_timer_flush_hwstate. */ if (!vgic_initialized(vcpu->kvm)) return; if (kvm_timer_should_fire(vcpu) != timer->irq.level) kvm_timer_update_irq(vcpu, !timer->irq.level); }
/** * vgic_lazy_init: Lazy init is only allowed if the GIC exposed to the guest * is a GICv2. A GICv3 must be explicitly initialized by the guest using the * KVM_DEV_ARM_VGIC_GRP_CTRL KVM_DEVICE group. * @kvm: kvm struct pointer */ int vgic_lazy_init(struct kvm *kvm) { int ret = 0; if (unlikely(!vgic_initialized(kvm))) { /* * We only provide the automatic initialization of the VGIC * for the legacy case of a GICv2. Any other type must * be explicitly initialized once setup with the respective * KVM device call. */ if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2) return -EBUSY; mutex_lock(&kvm->lock); ret = vgic_init(kvm); mutex_unlock(&kvm->lock); } return ret; }
struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) { int err; struct kvm_vcpu *vcpu; if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) { err = -EBUSY; goto out; } if (id >= kvm->arch.max_vcpus) { err = -EINVAL; goto out; } vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); if (!vcpu) { err = -ENOMEM; goto out; } err = kvm_vcpu_init(vcpu, kvm, id); if (err) goto free_vcpu; err = create_hyp_mappings(vcpu, vcpu + 1); if (err) goto vcpu_uninit; return vcpu; vcpu_uninit: kvm_vcpu_uninit(vcpu); free_vcpu: kmem_cache_free(kvm_vcpu_cache, vcpu); out: return ERR_PTR(err); }
bool kvm_arch_intc_initialized(struct kvm *kvm) { return vgic_initialized(kvm); }