linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: christoffer.dall@linaro.org (Christoffer Dall)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 05/19] arm/arm64: KVM: introduce per-VM ops
Date: Mon, 3 Nov 2014 14:59:23 +0100	[thread overview]
Message-ID: <20141103135923.GF16132@cbox> (raw)
In-Reply-To: <1414776414-13426-6-git-send-email-andre.przywara@arm.com>

On Fri, Oct 31, 2014 at 05:26:40PM +0000, Andre Przywara wrote:
> Currently we only have one virtual GIC model supported, so all guests
> use the same emulation code. With the addition of another model we
> end up with different guests using potentially different vGIC models,
> so we have to split up some functions to be per VM.
> Introduce a vgic_vm_ops struct to hold function pointers for those
> functions that are different and provide the necessary code to
> initialize them.
> 
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
>  include/kvm/arm_vgic.h |   10 ++++++
>  virt/kvm/arm/vgic.c    |   81 +++++++++++++++++++++++++++++++++++-------------
>  2 files changed, 69 insertions(+), 22 deletions(-)
> 
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index dde5a00..bfb660a 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -134,6 +134,14 @@ struct vgic_params {
>  	void __iomem	*vctrl_base;
>  };
>  
> +struct vgic_vm_ops {
> +	bool	(*handle_mmio)(struct kvm_vcpu *, struct kvm_run *,
> +			       struct kvm_exit_mmio *);
> +	bool	(*queue_sgi)(struct kvm_vcpu *vcpu, int irq);
> +	void	(*add_sgi_source)(struct kvm_vcpu *vcpu, int irq, int source);
> +	int	(*vgic_init)(struct kvm *kvm, const struct vgic_params *params);
> +};
> +
>  struct vgic_dist {
>  #ifdef CONFIG_KVM_ARM_VGIC
>  	spinlock_t		lock;
> @@ -215,6 +223,8 @@ struct vgic_dist {
>  
>  	/* Bitmap indicating which CPU has something pending */
>  	unsigned long		*irq_pending_on_cpu;
> +
> +	struct vgic_vm_ops	vm_ops;
>  #endif
>  };
>  
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index 0cbdde9..2c16684 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -105,6 +105,8 @@ static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
>  static const struct vgic_ops *vgic_ops;
>  static const struct vgic_params *vgic;
>  
> +#define vgic_vm_op(kvm, fn) ((kvm)->arch.vgic.vm_ops.fn)
> +

another one?  why did you simply ignore my comment from the last review?

If it wasn't obvious last time around, YUCK, and no ;)

>  /*
>   * struct vgic_bitmap contains a bitmap made of unsigned longs, but
>   * extracts u32s out of them.
> @@ -761,6 +763,13 @@ static bool handle_mmio_sgi_reg(struct kvm_vcpu *vcpu,
>  	return false;
>  }
>  
> +static void vgic_v2_add_sgi_source(struct kvm_vcpu *vcpu, int irq, int source)
> +{
> +	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> +
> +	*vgic_get_sgi_sources(dist, vcpu->vcpu_id, irq) |= 1 << source;
> +}
> +
>  /**
>   * vgic_unqueue_irqs - move pending IRQs from LRs to the distributor
>   * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs
> @@ -775,9 +784,7 @@ static bool handle_mmio_sgi_reg(struct kvm_vcpu *vcpu,
>   */
>  static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
>  {
> -	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>  	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
> -	int vcpu_id = vcpu->vcpu_id;
>  	int i;
>  
>  	for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) {
> @@ -804,7 +811,8 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
>  		 */
>  		vgic_dist_irq_set_pending(vcpu, lr.irq);
>  		if (lr.irq < VGIC_NR_SGIS)
> -			*vgic_get_sgi_sources(dist, vcpu_id, lr.irq) |= 1 << lr.source;
> +			vgic_vm_op(vcpu->kvm, add_sgi_source)(vcpu, lr.irq,
> +							      lr.source);
>  		lr.state &= ~LR_STATE_PENDING;
>  		vgic_set_lr(vcpu, i, lr);
>  
> @@ -1162,7 +1170,7 @@ bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,
>  	if (!irqchip_in_kernel(vcpu->kvm))
>  		return false;
>  
> -	return vgic_v2_handle_mmio(vcpu, run, mmio);
> +	return vgic_vm_op(vcpu->kvm, handle_mmio)(vcpu, run, mmio);
>  }
>  
>  static u8 *vgic_get_sgi_sources(struct vgic_dist *dist, int vcpu_id, int sgi)
> @@ -1414,7 +1422,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
>  	return true;
>  }
>  
> -static bool vgic_queue_sgi(struct kvm_vcpu *vcpu, int irq)
> +static bool vgic_v2_queue_sgi(struct kvm_vcpu *vcpu, int irq)
>  {
>  	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>  	unsigned long sources;
> @@ -1489,7 +1497,7 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
>  
>  	/* SGIs */
>  	for_each_set_bit(i, vgic_cpu->pending_percpu, VGIC_NR_SGIS) {
> -		if (!vgic_queue_sgi(vcpu, i))
> +		if (!vgic_vm_op(vcpu->kvm, queue_sgi)(vcpu, i))
>  			overflow = 1;
>  	}
>  
> @@ -1944,9 +1952,6 @@ static int vgic_init_maps(struct kvm *kvm)
>  		}
>  	}
>  
> -	for (i = VGIC_NR_PRIVATE_IRQS; i < dist->nr_irqs; i += 4)
> -		vgic_set_target_reg(kvm, 0, i);
> -

Remind me, why are we moving this chunk?

>  out:
>  	if (ret)
>  		kvm_vgic_destroy(kvm);
> @@ -1954,6 +1959,31 @@ out:
>  	return ret;
>  }
>  
> +static int vgic_v2_init(struct kvm *kvm, const struct vgic_params *params)
> +{
> +	struct vgic_dist *dist = &kvm->arch.vgic;
> +	int ret, i;
> +
> +	if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base) ||
> +	    IS_VGIC_ADDR_UNDEF(dist->vgic_cpu_base)) {
> +		kvm_err("Need to set vgic distributor addresses first\n");
> +		return -ENXIO;
> +	}
> +
> +	ret = kvm_phys_addr_ioremap(kvm, dist->vgic_cpu_base,
> +				    params->vcpu_base,
> +				    KVM_VGIC_V2_CPU_SIZE, true);
> +	if (ret) {
> +		kvm_err("Unable to remap VGIC CPU to VCPU\n");
> +		return ret;
> +	}
> +
> +	for (i = VGIC_NR_PRIVATE_IRQS; i < dist->nr_irqs; i += 4)
> +		vgic_set_target_reg(kvm, 0, i);
> +
> +	return 0;
> +}
> +
>  /**
>   * kvm_vgic_init - Initialize global VGIC state before running any VCPUs
>   * @kvm: pointer to the kvm struct
> @@ -1976,26 +2006,15 @@ int kvm_vgic_init(struct kvm *kvm)
>  	if (vgic_initialized(kvm))
>  		goto out;
>  
> -	if (IS_VGIC_ADDR_UNDEF(kvm->arch.vgic.vgic_dist_base) ||
> -	    IS_VGIC_ADDR_UNDEF(kvm->arch.vgic.vgic_cpu_base)) {
> -		kvm_err("Need to set vgic cpu and dist addresses first\n");
> -		ret = -ENXIO;
> -		goto out;
> -	}
> -
>  	ret = vgic_init_maps(kvm);
>  	if (ret) {
>  		kvm_err("Unable to allocate maps\n");
>  		goto out;
>  	}
>  
> -	ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base,
> -				    vgic->vcpu_base, KVM_VGIC_V2_CPU_SIZE,
> -				    true);
> -	if (ret) {
> -		kvm_err("Unable to remap VGIC CPU to VCPU\n");
> +	ret = vgic_vm_op(kvm, vgic_init)(kvm, vgic);
> +	if (ret)
>  		goto out;
> -	}
>  
>  	kvm_for_each_vcpu(i, vcpu, kvm)
>  		kvm_vgic_vcpu_init(vcpu);
> @@ -2008,6 +2027,21 @@ out:
>  	return ret;
>  }
>  
> +static bool init_emulation_ops(struct kvm *kvm, int type)
> +{
> +	struct vgic_dist *dist = &kvm->arch.vgic;
> +
> +	switch (type) {
> +	case KVM_DEV_TYPE_ARM_VGIC_V2:
> +		dist->vm_ops.handle_mmio = vgic_v2_handle_mmio;
> +		dist->vm_ops.queue_sgi = vgic_v2_queue_sgi;
> +		dist->vm_ops.add_sgi_source = vgic_v2_add_sgi_source;
> +		dist->vm_ops.vgic_init = vgic_v2_init;
> +		return true;
> +	}
> +	return false;
> +}
> +
>  int kvm_vgic_create(struct kvm *kvm, u32 type)
>  {
>  	int i, vcpu_lock_idx = -1, ret = 0;
> @@ -2045,6 +2079,9 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
>  	kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
>  	kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF;
>  
> +	if (!init_emulation_ops(kvm, type))
> +		ret = -ENODEV;
> +
>  out_unlock:
>  	for (; vcpu_lock_idx >= 0; vcpu_lock_idx--) {
>  		vcpu = kvm_get_vcpu(kvm, vcpu_lock_idx);
> -- 
> 1.7.9.5
> 

-Christoffer

  reply	other threads:[~2014-11-03 13:59 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-31 17:26 [PATCH v3 00/19] KVM GICv3 emulation Andre Przywara
2014-10-31 17:26 ` [PATCH v3 01/19] arm/arm64: KVM: rework MPIDR assignment and add accessors Andre Przywara
2014-11-03 13:13   ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 02/19] arm/arm64: KVM: pass down user space provided GIC type into vGIC code Andre Przywara
2014-11-03 13:14   ` Christoffer Dall
2014-11-03 13:25     ` Andre Przywara
2014-11-03 16:51       ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 03/19] arm/arm64: KVM: refactor vgic_handle_mmio() function Andre Przywara
2014-11-03 13:23   ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 04/19] arm/arm64: KVM: wrap 64 bit MMIO accesses with two 32 bit ones Andre Przywara
2014-11-03 13:25   ` Christoffer Dall
2014-11-04 12:18     ` Andre Przywara
2014-11-04 13:24       ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 05/19] arm/arm64: KVM: introduce per-VM ops Andre Przywara
2014-11-03 13:59   ` Christoffer Dall [this message]
2014-11-04 15:58     ` Andre Przywara
2014-11-04 19:03       ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 06/19] arm/arm64: KVM: move [sg]et_lr into " Andre Przywara
2014-11-03 14:15   ` Christoffer Dall
2014-11-04 16:30     ` Andre Przywara
2014-11-04 19:12       ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 07/19] arm/arm64: KVM: move kvm_register_device_ops() into vGIC probing Andre Przywara
2014-11-03 20:05   ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 08/19] arm/arm64: KVM: dont rely on a valid GICH base address Andre Przywara
2014-11-03 20:05   ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 09/19] arm/arm64: KVM: make the maximum number of vCPUs a per-VM value Andre Przywara
2014-11-03 20:06   ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 10/19] arm/arm64: KVM: make the value of ICC_SRE_EL1 a per-VM variable Andre Przywara
2014-11-03 20:04   ` Christoffer Dall
2014-11-03 20:17     ` Marc Zyngier
2014-11-07 19:18       ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 11/19] arm/arm64: KVM: refactor MMIO accessors Andre Przywara
2014-11-04 11:55   ` Christoffer Dall
2014-11-04 12:25     ` Andre Przywara
2014-10-31 17:26 ` [PATCH v3 12/19] arm/arm64: KVM: refactor/wrap vgic_set/get_attr() Andre Przywara
2014-11-04 19:30   ` Christoffer Dall
2014-11-05 10:27     ` Andre Przywara
2014-11-05 10:37       ` Andre Przywara
2014-11-05 12:57       ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 13/19] arm/arm64: KVM: add vgic.h header file Andre Przywara
2014-11-04 19:30   ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 14/19] arm/arm64: KVM: split GICv2 specific emulation code from vgic.c Andre Przywara
2014-11-04 19:30   ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 15/19] arm/arm64: KVM: add opaque private pointer to MMIO accessors Andre Przywara
2014-11-04 15:44   ` Christoffer Dall
2014-11-04 17:24     ` Andre Przywara
2014-11-04 18:05       ` Marc Zyngier
2014-11-04 19:18         ` Christoffer Dall
2014-11-04 20:17           ` Marc Zyngier
2014-11-05  9:49             ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 16/19] arm/arm64: KVM: add virtual GICv3 distributor emulation Andre Przywara
2014-11-07 14:30   ` Christoffer Dall
2014-11-10 17:30     ` [PATCH v3 16/19] arm/arm64: KVM: add virtual GICv3 distributor emulation / PART 1 Andre Przywara
2014-11-11 13:48       ` Christoffer Dall
2014-11-12 12:39     ` [PATCH v3 16/19] arm/arm64: KVM: add virtual GICv3 distributor emulation / PART 2 Andre Przywara
2014-11-12 19:51       ` Christoffer Dall
2014-11-13 11:18       ` Christoffer Dall
2014-11-13 11:45         ` Marc Zyngier
2014-11-13 12:01           ` Andre Przywara
2014-10-31 17:26 ` [PATCH v3 17/19] arm64: KVM: add SGI system register trapping Andre Przywara
2014-11-07 15:07   ` Christoffer Dall
2014-11-10 11:31     ` Andre Przywara
2014-11-10 12:45       ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 18/19] arm/arm64: KVM: enable kernel side of GICv3 emulation Andre Przywara
2014-11-07 16:07   ` Christoffer Dall
2014-11-10 12:19     ` Andre Przywara
2014-11-10 13:24       ` Christoffer Dall
2014-10-31 17:26 ` [PATCH v3 19/19] arm/arm64: KVM: allow userland to request a virtual GICv3 Andre Przywara
2014-11-07 16:15   ` Christoffer Dall
2014-11-10 12:26     ` Andre Przywara
2014-11-10 13:25       ` Christoffer Dall
2014-11-03 12:59 ` [PATCH v3 00/19] KVM GICv3 emulation Christoffer Dall
2014-11-06 10:57 ` Christoffer Dall
2014-11-06 11:21   ` Christoffer Dall
2014-11-06 15:13     ` Andre Przywara
2014-11-06 18:09       ` Christoffer Dall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20141103135923.GF16132@cbox \
    --to=christoffer.dall@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).