[PATCH v3 1/9] ARM: KVM: Allow creating the VGIC after VCPUs

Marc Zyngier marc.zyngier at arm.com
Mon Dec 9 10:11:48 EST 2013


On 2013-11-17 04:30, Christoffer Dall wrote:
> Rework the VGIC initialization slightly to allow initialization of 
> the
> vgic cpu-specific state even if the irqchip (the VGIC) hasn't been
> created by user space yet.  This is safe, because the vgic data
> structures are already allocated when the CPU is allocated if VGIC
> support is compiled into the kernel.  Further, the init process does 
> not
> depend on any other information and the sacrifice is a slight
> performance degradation for creating VMs in the no-VGIC case.
>
> The reason is that the new device control API doesn't mandate 
> creating
> the VGIC before creating the VCPU and it is unreasonable to require 
> user
> space to create the VGIC before creating the VCPUs.
>
> At the same time move the irqchip_in_kernel check out of
> kvm_vcpu_first_run_init and into the init function to make the 
> per-vcpu
> and global init functions symmetric and add comments on the exported
> functions making it a bit easier to understand the init flow by only
> looking at vgic.c.
>
> Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>

Looks good to me:

Acked-by: Marc Zyngier <marc.zyngier at arm.com>

         M.

> ---
>  arch/arm/kvm/arm.c  |    7 ++++---
>  virt/kvm/arm/vgic.c |   22 +++++++++++++++++++---
>  2 files changed, 23 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 2bc2ec4..e80b6a1 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -464,6 +464,8 @@ static void update_vttbr(struct kvm *kvm)
>
>  static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
>  {
> +	int ret;
> +
>  	if (likely(vcpu->arch.has_run_once))
>  		return 0;
>
> @@ -473,9 +475,8 @@ static int kvm_vcpu_first_run_init(struct 
> kvm_vcpu *vcpu)
>  	 * Initialize the VGIC before running a vcpu the first time on
>  	 * this VM.
>  	 */
> -	if (irqchip_in_kernel(vcpu->kvm) &&
> -	    unlikely(!vgic_initialized(vcpu->kvm))) {
> -		int ret = kvm_vgic_init(vcpu->kvm);
> +	if (unlikely(!vgic_initialized(vcpu->kvm))) {
> +		ret = kvm_vgic_init(vcpu->kvm);
>  		if (ret)
>  			return ret;
>  	}
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index 81e9481..5e9df47 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -1243,15 +1243,19 @@ static irqreturn_t
> vgic_maintenance_handler(int irq, void *data)
>  	return IRQ_HANDLED;
>  }
>
> +/**
> + * kvm_vgic_vcpu_init - Initialize per-vcpu VGIC state
> + * @vcpu: pointer to the vcpu struct
> + *
> + * Initialize the vgic_cpu struct and vgic_dist struct fields 
> pertaining to
> + * this vcpu and enable the VGIC for this VCPU
> + */
>  int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
>  {
>  	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>  	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>  	int i;
>
> -	if (!irqchip_in_kernel(vcpu->kvm))
> -		return 0;
> -
>  	if (vcpu->vcpu_id >= VGIC_MAX_CPUS)
>  		return -EBUSY;
>
> @@ -1383,10 +1387,22 @@ out:
>  	return ret;
>  }
>
> +/**
> + * kvm_vgic_init - Initialize global VGIC state before running any 
> VCPUs
> + * @kvm: pointer to the kvm struct
> + *
> + * Map the virtual CPU interface into the VM before running any 
> VCPUs.  We
> + * can't do this at creation time, because user space must first set 
> the
> + * virtual CPU interface address in the guest physical address 
> space.  Also
> + * initialize the ITARGETSRn regs to 0 on the emulated distributor.
> + */
>  int kvm_vgic_init(struct kvm *kvm)
>  {
>  	int ret = 0, i;
>
> +	if (!irqchip_in_kernel(kvm))
> +		return 0;
> +
>  	mutex_lock(&kvm->lock);
>
>  	if (vgic_initialized(kvm))

-- 
Fast, cheap, reliable. Pick two.



More information about the linux-arm-kernel mailing list