From: "Alex Bennée" <alex.bennee@linaro.org>
To: Christoffer Dall <christoffer.dall@linaro.org>
Cc: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
kvmarm@lists.cs.columbia.edu, marc.zyngier@arm.com,
Gleb Natapov <gleb@kernel.org>,
Paolo Bonzini <pbonzini@redhat.com>,
open list <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v2 2/5] arm/arm64: KVM: Implement support for unqueueing active IRQs
Date: Mon, 09 Mar 2015 16:40:57 +0000 [thread overview]
Message-ID: <87oao2azty.fsf@linaro.org> (raw)
In-Reply-To: <20150309144148.GD20559@cbox>
Christoffer Dall <christoffer.dall@linaro.org> writes:
> On Mon, Mar 02, 2015 at 01:29:01PM +0000, Alex Bennée wrote:
>> From: Christoffer Dall <christoffer.dall@linaro.org>
>>
>> Migrating active interrupts causes the active state to be lost
>> completely. This implements some additional bitmaps to track the active
>> state on the distributor and export this to user space.
>>
>> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
>>
>> ---
>> AJB:
>> - fixed merge conflicts
>> - moved additional shared bitmaps to be dynamically allocated
>> - make irq_active_on_cpu dynamically allocated as well
>> - in vgic_queue_irq don't queue pending if already active
>> - in __kvm_vgic_flush_hwstate use pr_shared when checking SPIs
>> - vgic: clear active on CPU bit
>> - checkpatch, remove extraneous braces
>> - checkpatch, remove debug, fix overflows
>> - move register access fns to re-factored vgic-v2-emul.c
>> v2
>> - doc: unqueue and update_state
>>
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index 7c55dd5..7042251 100644
<snip>
> if you respin: the active state
> if you respin: Mark the
OK
<snip>
>>
>> @@ -1030,39 +1113,49 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
>> {
>> struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>> struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>> + unsigned long *pa_percpu, *pa_shared;
>> int i, vcpu_id;
>> int overflow = 0;
>> + int nr_shared = vgic_nr_shared_irqs(dist);
>>
>> vcpu_id = vcpu->vcpu_id;
>>
>> + pa_percpu = vcpu->arch.vgic_cpu.pend_act_percpu;
>> + pa_shared = vcpu->arch.vgic_cpu.pend_act_shared;
>> +
>> + bitmap_or(pa_percpu, vgic_cpu->pending_percpu, vgic_cpu->active_percpu,
>> + VGIC_NR_PRIVATE_IRQS);
>> + bitmap_or(pa_shared, vgic_cpu->pending_shared, vgic_cpu->active_shared,
>> + nr_shared);
>> /*
>> * We may not have any pending interrupt, or the interrupts
>> * may have been serviced from another vcpu. In all cases,
>> * move along.
>> */
>> - if (!kvm_vgic_vcpu_pending_irq(vcpu)) {
>> - pr_debug("CPU%d has no pending interrupt\n", vcpu_id);
>> + if (!kvm_vgic_vcpu_pending_irq(vcpu) && !kvm_vgic_vcpu_active_irq(vcpu))
>> goto epilog;
>> - }
>>
>> /* SGIs */
>> - for_each_set_bit(i, vgic_cpu->pending_percpu, VGIC_NR_SGIS) {
>> + for_each_set_bit(i, pa_percpu, VGIC_NR_SGIS) {
>> if (!queue_sgi(vcpu, i))
>> overflow = 1;
>> }
>>
>> /* PPIs */
>> - for_each_set_bit_from(i, vgic_cpu->pending_percpu, VGIC_NR_PRIVATE_IRQS) {
>> + for_each_set_bit_from(i, pa_percpu, VGIC_NR_PRIVATE_IRQS) {
>> if (!vgic_queue_hwirq(vcpu, i))
>> overflow = 1;
>> }
>>
>> /* SPIs */
>> - for_each_set_bit(i, vgic_cpu->pending_shared, vgic_nr_shared_irqs(dist)) {
>> + for_each_set_bit(i, pa_shared, nr_shared) {
>> if (!vgic_queue_hwirq(vcpu, i + VGIC_NR_PRIVATE_IRQS))
>> overflow = 1;
>> }
>
> meh, these changes will now produce a quite strange result if one
> bisects at this specific patch, since we will be setting pending
> interrupts to active.... I thought it was more clear as one patch
> containing the changes to vgic_queue_... imho.
I split the re-factor off by Marc's request but your right it becomes a
little weird. Now the horror of dealing with the merge conflicts is done
I could split the next patch and add it before this one:
* add a common vgic_queue_irq_to_lr fn (just deal with pending)
* Implement support for unqueuing active IRQs (expand vgic_queue_irq_to_lr)
>
> Thoughts?
>
>>
>> +
>> +
>> +
>> epilog:
>> if (overflow) {
>> vgic_enable_underflow(vcpu);
>> @@ -1209,6 +1302,17 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
>> return test_bit(vcpu->vcpu_id, dist->irq_pending_on_cpu);
>> }
>>
>> +int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu)
>> +{
>> + struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>> +
>> + if (!irqchip_in_kernel(vcpu->kvm))
>> + return 0;
>> +
>> + return test_bit(vcpu->vcpu_id, dist->irq_active_on_cpu);
>> +}
>> +
>> +
>> void vgic_kick_vcpus(struct kvm *kvm)
>> {
>> struct kvm_vcpu *vcpu;
>> @@ -1381,8 +1485,12 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
>> struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>>
>> kfree(vgic_cpu->pending_shared);
>> + kfree(vgic_cpu->active_shared);
>> + kfree(vgic_cpu->pend_act_shared);
>> kfree(vgic_cpu->vgic_irq_lr_map);
>> vgic_cpu->pending_shared = NULL;
>> + vgic_cpu->active_shared = NULL;
>> + vgic_cpu->pend_act_shared = NULL;
>> vgic_cpu->vgic_irq_lr_map = NULL;
>> }
>>
>> @@ -1392,9 +1500,14 @@ static int vgic_vcpu_init_maps(struct kvm_vcpu *vcpu, int nr_irqs)
>>
>> int sz = (nr_irqs - VGIC_NR_PRIVATE_IRQS) / 8;
>> vgic_cpu->pending_shared = kzalloc(sz, GFP_KERNEL);
>> + vgic_cpu->active_shared = kzalloc(sz, GFP_KERNEL);
>> + vgic_cpu->pend_act_shared = kzalloc(sz, GFP_KERNEL);
>> vgic_cpu->vgic_irq_lr_map = kmalloc(nr_irqs, GFP_KERNEL);
>>
>> - if (!vgic_cpu->pending_shared || !vgic_cpu->vgic_irq_lr_map) {
>> + if (!vgic_cpu->pending_shared
>> + || !vgic_cpu->active_shared
>> + || !vgic_cpu->pend_act_shared
>> + || !vgic_cpu->vgic_irq_lr_map) {
>> kvm_vgic_vcpu_destroy(vcpu);
>> return -ENOMEM;
>> }
>> @@ -1447,10 +1560,12 @@ void kvm_vgic_destroy(struct kvm *kvm)
>> kfree(dist->irq_spi_mpidr);
>> kfree(dist->irq_spi_target);
>> kfree(dist->irq_pending_on_cpu);
>> + kfree(dist->irq_active_on_cpu);
>> dist->irq_sgi_sources = NULL;
>> dist->irq_spi_cpu = NULL;
>> dist->irq_spi_target = NULL;
>> dist->irq_pending_on_cpu = NULL;
>> + dist->irq_active_on_cpu = NULL;
>> dist->nr_cpus = 0;
>> }
>>
>> @@ -1486,6 +1601,7 @@ int vgic_init(struct kvm *kvm)
>> ret |= vgic_init_bitmap(&dist->irq_pending, nr_cpus, nr_irqs);
>> ret |= vgic_init_bitmap(&dist->irq_soft_pend, nr_cpus, nr_irqs);
>> ret |= vgic_init_bitmap(&dist->irq_queued, nr_cpus, nr_irqs);
>> + ret |= vgic_init_bitmap(&dist->irq_active, nr_cpus, nr_irqs);
>> ret |= vgic_init_bitmap(&dist->irq_cfg, nr_cpus, nr_irqs);
>> ret |= vgic_init_bytemap(&dist->irq_priority, nr_cpus, nr_irqs);
>>
>> @@ -1498,10 +1614,13 @@ int vgic_init(struct kvm *kvm)
>> GFP_KERNEL);
>> dist->irq_pending_on_cpu = kzalloc(BITS_TO_LONGS(nr_cpus) * sizeof(long),
>> GFP_KERNEL);
>> + dist->irq_active_on_cpu = kzalloc(BITS_TO_LONGS(nr_cpus) * sizeof(long),
>> + GFP_KERNEL);
>> if (!dist->irq_sgi_sources ||
>> !dist->irq_spi_cpu ||
>> !dist->irq_spi_target ||
>> - !dist->irq_pending_on_cpu) {
>> + !dist->irq_pending_on_cpu ||
>> + !dist->irq_active_on_cpu) {
>> ret = -ENOMEM;
>> goto out;
>> }
>> diff --git a/virt/kvm/arm/vgic.h b/virt/kvm/arm/vgic.h
>> index 1e83bdf..1e5a381 100644
>> --- a/virt/kvm/arm/vgic.h
>> +++ b/virt/kvm/arm/vgic.h
>> @@ -107,6 +107,14 @@ bool vgic_handle_set_pending_reg(struct kvm *kvm, struct kvm_exit_mmio *mmio,
>> bool vgic_handle_clear_pending_reg(struct kvm *kvm, struct kvm_exit_mmio *mmio,
>> phys_addr_t offset, int vcpu_id);
>>
>> +bool vgic_handle_set_active_reg(struct kvm *kvm,
>> + struct kvm_exit_mmio *mmio,
>> + phys_addr_t offset, int vcpu_id);
>> +
>> +bool vgic_handle_clear_active_reg(struct kvm *kvm,
>> + struct kvm_exit_mmio *mmio,
>> + phys_addr_t offset, int vcpu_id);
>> +
>> bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio *mmio,
>> phys_addr_t offset);
>>
>> --
>> 2.3.0
>>
--
Alex Bennée
next prev parent reply other threads:[~2015-03-09 16:41 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1425302944-6276-1-git-send-email-alex.bennee@linaro.org>
2015-03-02 13:29 ` [PATCH v2 1/5] arm: KVM: export vcpi->pause state via MP_STATE ioctls Alex Bennée
2015-03-09 13:50 ` Christoffer Dall
2015-03-09 16:34 ` Alex Bennée
2015-03-09 19:29 ` Christoffer Dall
2015-03-09 19:55 ` Peter Maydell
2015-03-02 13:29 ` [PATCH v2 2/5] arm/arm64: KVM: Implement support for unqueueing active IRQs Alex Bennée
2015-03-09 14:41 ` Christoffer Dall
2015-03-09 16:40 ` Alex Bennée [this message]
2015-03-02 13:29 ` [PATCH v2 3/5] arm: KVM: add a common vgic_queue_irq_to_lr fn Alex Bennée
2015-03-09 14:47 ` Christoffer Dall
2015-03-02 13:29 ` [PATCH v2 4/5] arm/arm64: KVM: Fix migration race in the arch timer Alex Bennée
2015-03-02 13:29 ` [PATCH v2 5/5] arm/arm64: KVM: Keep elrsr/aisr in sync with software model Alex Bennée
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=87oao2azty.fsf@linaro.org \
--to=alex.bennee@linaro.org \
--cc=christoffer.dall@linaro.org \
--cc=gleb@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=marc.zyngier@arm.com \
--cc=pbonzini@redhat.com \
/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).