linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: andre.przywara@arm.com (Andre Przywara)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 12/16] KVM: arm64: handle pending bit for LPIs in ITS emulation
Date: Mon, 12 Oct 2015 15:17:52 +0100	[thread overview]
Message-ID: <561BC110.9090403@arm.com> (raw)
In-Reply-To: <016d01d104c1$47a41570$d6ec4050$@samsung.com>

Hi Pavel,

On 12/10/15 08:40, Pavel Fedin wrote:
>  Hello!
> 
>> -----Original Message-----
>> From: kvm-owner at vger.kernel.org [mailto:kvm-owner at vger.kernel.org] On Behalf Of Andre Przywara
>> Sent: Wednesday, October 07, 2015 5:55 PM
>> To: marc.zyngier at arm.com; christoffer.dall at linaro.org
>> Cc: eric.auger at linaro.org; p.fedin at samsung.com; kvmarm at lists.cs.columbia.edu; linux-arm-
>> kernel at lists.infradead.org; kvm at vger.kernel.org
>> Subject: [PATCH v3 12/16] KVM: arm64: handle pending bit for LPIs in ITS emulation
>>
>> As the actual LPI number in a guest can be quite high, but is mostly
>> assigned using a very sparse allocation scheme, bitmaps and arrays
>> for storing the virtual interrupt status are a waste of memory.
>> We use our equivalent of the "Interrupt Translation Table Entry"
>> (ITTE) to hold this extra status information for a virtual LPI.
>> As the normal VGIC code cannot use its fancy bitmaps to manage
>> pending interrupts, we provide a hook in the VGIC code to let the
>> ITS emulation handle the list register queueing itself.
>> LPIs are located in a separate number range (>=8192), so
>> distinguishing them is easy. With LPIs being only edge-triggered, we
>> get away with a less complex IRQ handling.
>> We extend the number of bits for storing the IRQ number in our
>> LR struct to 16 to cover the LPI numbers we support as well.
>>
>> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
>> ---
>> Changelog v2..v3:
>> - extend LR data structure to hold 16-bit wide IRQ IDs
>> - only clear pending bit if IRQ could be queued
>> - adapt __kvm_vgic_sync_hwstate() to upstream changes
>>
>>  include/kvm/arm_vgic.h      |  4 +-
>>  virt/kvm/arm/its-emul.c     | 75 ++++++++++++++++++++++++++++++++++++
>>  virt/kvm/arm/its-emul.h     |  3 ++
>>  virt/kvm/arm/vgic-v3-emul.c |  2 +
>>  virt/kvm/arm/vgic.c         | 93 +++++++++++++++++++++++++++++++--------------
>>  5 files changed, 148 insertions(+), 29 deletions(-)
>>
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index c3eb414..035911f 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -95,7 +95,7 @@ enum vgic_type {
>>  #define LR_HW			(1 << 3)
>>
>>  struct vgic_lr {
>> -	unsigned irq:10;
>> +	unsigned irq:16;
>>  	union {
>>  		unsigned hwirq:10;
>>  		unsigned source:3;
>> @@ -147,6 +147,8 @@ struct vgic_vm_ops {
>>  	int	(*init_model)(struct kvm *);
>>  	void	(*destroy_model)(struct kvm *);
>>  	int	(*map_resources)(struct kvm *, const struct vgic_params *);
>> +	bool	(*queue_lpis)(struct kvm_vcpu *);
>> +	void	(*unqueue_lpi)(struct kvm_vcpu *, int irq);
>>  };
>>
>>  struct vgic_io_device {
>> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
>> index bab8033..8349970 100644
>> --- a/virt/kvm/arm/its-emul.c
>> +++ b/virt/kvm/arm/its-emul.c
>> @@ -59,8 +59,27 @@ struct its_itte {
>>  	struct its_collection *collection;
>>  	u32 lpi;
>>  	u32 event_id;
>> +	bool enabled;
>> +	unsigned long *pending;
>>  };
>>
>> +/* To be used as an iterator this macro misses the enclosing parentheses */
>> +#define for_each_lpi(dev, itte, kvm) \
>> +	list_for_each_entry(dev, &(kvm)->arch.vgic.its.device_list, dev_list) \
>> +		list_for_each_entry(itte, &(dev)->itt, itte_list)
>> +
>> +static struct its_itte *find_itte_by_lpi(struct kvm *kvm, int lpi)
>> +{
>> +	struct its_device *device;
>> +	struct its_itte *itte;
>> +
>> +	for_each_lpi(device, itte, kvm) {
>> +		if (itte->lpi == lpi)
>> +			return itte;
>> +	}
>> +	return NULL;
>> +}
>> +
>>  #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>>
>>  /* The distributor lock is held by the VGIC MMIO handler. */
>> @@ -154,9 +173,65 @@ static bool handle_mmio_gits_idregs(struct kvm_vcpu *vcpu,
>>  	return false;
>>  }
>>
>> +/*
>> + * Find all enabled and pending LPIs and queue them into the list
>> + * registers.
>> + * The dist lock is held by the caller.
>> + */
>> +bool vits_queue_lpis(struct kvm_vcpu *vcpu)
>> +{
>> +	struct vgic_its *its = &vcpu->kvm->arch.vgic.its;
>> +	struct its_device *device;
>> +	struct its_itte *itte;
>> +	bool ret = true;
>> +
>> +	if (!vgic_has_its(vcpu->kvm))
>> +		return true;
>> +	if (!its->enabled || !vcpu->kvm->arch.vgic.lpis_enabled)
>> +		return true;
>> +
>> +	spin_lock(&its->lock);
>> +	for_each_lpi(device, itte, vcpu->kvm) {
>> +		if (!itte->enabled || !test_bit(vcpu->vcpu_id, itte->pending))
>> +			continue;
>> +
>> +		if (!itte->collection)
>> +			continue;
>> +
>> +		if (itte->collection->target_addr != vcpu->vcpu_id)
>> +			continue;
>> +
>> +
>> +		if (vgic_queue_irq(vcpu, 0, itte->lpi))
>> +			__clear_bit(vcpu->vcpu_id, itte->pending);
>> +		else
>> +			ret = false;
> 
>  Shouldn't we also have 'break' here? If vgic_queue_irq() returns false, this means we have no more
> LRs to use, therefore it makes no sense to keep iterating.

I consider this too much optimization at this point.
vgic_queue_irq() just tells about the success for this interrupt, I'd
rather not make assumptions about other IRQs (we could piggy-back those,
for instance).
Even if not, I'd prefer to not break abstraction here.

Cheers,
Andre.

  parent reply	other threads:[~2015-10-12 14:17 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-07 14:55 [PATCH v3 00/16] KVM: arm64: GICv3 ITS emulation Andre Przywara
2015-10-07 14:55 ` [PATCH v3 01/16] KVM: arm/arm64: VGIC: don't track used LRs in the distributor Andre Przywara
2015-10-07 14:55 ` [PATCH v3 02/16] KVM: arm/arm64: remove now unused code after stay-in-LR rework Andre Przywara
2015-10-07 14:55 ` [PATCH v3 03/16] KVM: extend struct kvm_msi to hold a 32-bit device ID Andre Przywara
2015-10-07 14:55 ` [PATCH v3 04/16] KVM: arm/arm64: add emulation model specific destroy function Andre Przywara
2015-10-07 14:55 ` [PATCH v3 05/16] KVM: arm/arm64: extend arch CAP checks to allow per-VM capabilities Andre Przywara
2015-10-07 14:55 ` [PATCH v3 06/16] KVM: arm/arm64: make GIC frame address initialization model specific Andre Przywara
2015-10-07 14:55 ` [PATCH v3 07/16] KVM: arm64: Introduce new MMIO region for the ITS base address Andre Przywara
2015-10-07 14:55 ` [PATCH v3 08/16] KVM: arm64: handle ITS related GICv3 redistributor registers Andre Przywara
2015-10-22 15:46   ` Pavel Fedin
2015-10-22 15:55     ` Pavel Fedin
2015-10-07 14:55 ` [PATCH v3 09/16] KVM: arm64: introduce ITS emulation file with stub functions Andre Przywara
2015-10-07 14:55 ` [PATCH v3 10/16] KVM: arm64: implement basic ITS register handlers Andre Przywara
2015-10-07 14:55 ` [PATCH v3 11/16] KVM: arm64: add data structures to model ITS interrupt translation Andre Przywara
2015-10-07 14:55 ` [PATCH v3 12/16] KVM: arm64: handle pending bit for LPIs in ITS emulation Andre Przywara
2015-10-07 15:10   ` Pavel Fedin
2015-10-07 15:35     ` Marc Zyngier
2015-10-07 15:46       ` Pavel Fedin
2015-10-07 15:49         ` Marc Zyngier
2015-10-12  7:40   ` Pavel Fedin
2015-10-12 11:39     ` Pavel Fedin
2015-10-12 14:17     ` Andre Przywara [this message]
2015-10-07 14:55 ` [PATCH v3 13/16] KVM: arm64: sync LPI configuration and pending tables Andre Przywara
2015-10-21 11:29   ` Pavel Fedin
2015-10-07 14:55 ` [PATCH v3 14/16] KVM: arm64: implement ITS command queue command handlers Andre Przywara
2015-10-14 12:26   ` Pavel Fedin
2015-10-07 14:55 ` [PATCH v3 15/16] KVM: arm64: implement MSI injection in ITS emulation Andre Przywara
2015-11-25 13:28   ` Pavel Fedin
2015-10-07 14:55 ` [PATCH v3 16/16] KVM: arm64: enable ITS emulation as a virtual MSI controller Andre Przywara
2015-10-07 16:05 ` [PATCH v3 00/16] KVM: arm64: GICv3 ITS emulation Pavel Fedin
2015-10-07 16:22   ` Marc Zyngier
2015-10-07 18:09     ` Pavel Fedin
2015-10-07 19:48       ` Marc Zyngier
2015-10-08  8:41         ` Pavel Fedin
2015-10-10 15:37 ` Christoffer Dall
2015-10-12 14:12   ` Andre Przywara
2015-10-12 15:18     ` Pavel Fedin
2015-10-14  8:48       ` Eric Auger
2015-10-14  8:50         ` Pavel Fedin
2015-10-13 15:46 ` Pavel Fedin
2016-03-09 11:35 ` Tomasz Nowicki
2016-03-13 18:16   ` Christoffer Dall
2016-03-14 11:13     ` Andre Przywara
2016-03-14 17:29       ` Peter Maydell
2016-03-14 17:54         ` Marc Zyngier
2016-03-14 18:20           ` Andre Przywara
2016-03-14 18:36             ` Marc Zyngier
2016-03-18  9:40             ` Christoffer Dall
2016-03-18 17:14               ` Peter Maydell
2016-03-18  9:38         ` 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=561BC110.9090403@arm.com \
    --to=andre.przywara@arm.com \
    --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).