From: Julien Thierry <julien.thierry@arm.com> To: linux-arm-kernel@lists.infradead.org Cc: peterz@infradead.org, jolsa@redhat.com, will.deacon@arm.com, acme@kernel.org, alexander.shishkin@linux.intel.com, mingo@redhat.com, Marc Zyngier <marc.zyngier@arm.com>, namhyung@kernel.org, sthotton@marvell.com, liwei391@huawei.com, kvmarm@lists.cs.columbia.edu Subject: [PATCH v4 7/9] arm/arm64: kvm: pmu: Make overflow handler NMI safe Date: Wed, 17 Jul 2019 09:17:10 +0100 [thread overview] Message-ID: <1563351432-55652-8-git-send-email-julien.thierry@arm.com> (raw) In-Reply-To: <1563351432-55652-1-git-send-email-julien.thierry@arm.com> When using an NMI for the PMU interrupt, taking any lock might cause a deadlock. The current PMU overflow handler in KVM takes locks when trying to wake up a vcpu. When overflow handler is called by an NMI, defer the vcpu waking in an irq_work queue. Signed-off-by: Julien Thierry <julien.thierry@arm.com> Cc: Christoffer Dall <christoffer.dall@arm.com> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: James Morse <james.morse@arm.com> Cc: Suzuki K Pouloze <suzuki.poulose@arm.com> Cc: kvmarm@lists.cs.columbia.edu --- include/kvm/arm_pmu.h | 1 + virt/kvm/arm/pmu.c | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h index 16c769a..8202ed7 100644 --- a/include/kvm/arm_pmu.h +++ b/include/kvm/arm_pmu.h @@ -27,6 +27,7 @@ struct kvm_pmu { bool ready; bool created; bool irq_level; + struct irq_work overflow_work; }; #define kvm_arm_pmu_v3_ready(v) ((v)->arch.pmu.ready) diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c index 3dd8238..deed8fb 100644 --- a/virt/kvm/arm/pmu.c +++ b/virt/kvm/arm/pmu.c @@ -421,6 +421,22 @@ void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu) } /** + * When perf interrupt is an NMI, we cannot safely notify the vcpu corresponding + * to the event. + * This is why we need a callback to do it once outside of the NMI context. + */ +static void kvm_pmu_perf_overflow_notify_vcpu(struct irq_work *work) +{ + struct kvm_vcpu *vcpu; + struct kvm_pmu *pmu; + + pmu = container_of(work, struct kvm_pmu, overflow_work); + vcpu = kvm_pmc_to_vcpu(&pmu->pmc[0]); + + kvm_vcpu_kick(vcpu); +} + +/** * When the perf event overflows, set the overflow status and inform the vcpu. */ static void kvm_pmu_perf_overflow(struct perf_event *perf_event, @@ -435,7 +451,11 @@ static void kvm_pmu_perf_overflow(struct perf_event *perf_event, if (kvm_pmu_overflow_status(vcpu)) { kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu); - kvm_vcpu_kick(vcpu); + + if (!in_nmi()) + kvm_vcpu_kick(vcpu); + else + irq_work_queue(&vcpu->arch.pmu.overflow_work); } } @@ -706,6 +726,9 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu) return ret; } + init_irq_work(&vcpu->arch.pmu.overflow_work, + kvm_pmu_perf_overflow_notify_vcpu); + vcpu->arch.pmu.created = true; return 0; } -- 1.9.1 _______________________________________________ kvmarm mailing list kvmarm@lists.cs.columbia.edu https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
WARNING: multiple messages have this Message-ID (diff)
From: Julien Thierry <julien.thierry@arm.com> To: linux-arm-kernel@lists.infradead.org Cc: mark.rutland@arm.com, Julien Thierry <julien.thierry@arm.com>, peterz@infradead.org, jolsa@redhat.com, Suzuki K Pouloze <suzuki.poulose@arm.com>, will.deacon@arm.com, Christoffer Dall <christoffer.dall@arm.com>, acme@kernel.org, alexander.shishkin@linux.intel.com, mingo@redhat.com, James Morse <james.morse@arm.com>, Marc Zyngier <marc.zyngier@arm.com>, namhyung@kernel.org, sthotton@marvell.com, liwei391@huawei.com, kvmarm@lists.cs.columbia.edu Subject: [PATCH v4 7/9] arm/arm64: kvm: pmu: Make overflow handler NMI safe Date: Wed, 17 Jul 2019 09:17:10 +0100 [thread overview] Message-ID: <1563351432-55652-8-git-send-email-julien.thierry@arm.com> (raw) In-Reply-To: <1563351432-55652-1-git-send-email-julien.thierry@arm.com> When using an NMI for the PMU interrupt, taking any lock might cause a deadlock. The current PMU overflow handler in KVM takes locks when trying to wake up a vcpu. When overflow handler is called by an NMI, defer the vcpu waking in an irq_work queue. Signed-off-by: Julien Thierry <julien.thierry@arm.com> Cc: Christoffer Dall <christoffer.dall@arm.com> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: James Morse <james.morse@arm.com> Cc: Suzuki K Pouloze <suzuki.poulose@arm.com> Cc: kvmarm@lists.cs.columbia.edu --- include/kvm/arm_pmu.h | 1 + virt/kvm/arm/pmu.c | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h index 16c769a..8202ed7 100644 --- a/include/kvm/arm_pmu.h +++ b/include/kvm/arm_pmu.h @@ -27,6 +27,7 @@ struct kvm_pmu { bool ready; bool created; bool irq_level; + struct irq_work overflow_work; }; #define kvm_arm_pmu_v3_ready(v) ((v)->arch.pmu.ready) diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c index 3dd8238..deed8fb 100644 --- a/virt/kvm/arm/pmu.c +++ b/virt/kvm/arm/pmu.c @@ -421,6 +421,22 @@ void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu) } /** + * When perf interrupt is an NMI, we cannot safely notify the vcpu corresponding + * to the event. + * This is why we need a callback to do it once outside of the NMI context. + */ +static void kvm_pmu_perf_overflow_notify_vcpu(struct irq_work *work) +{ + struct kvm_vcpu *vcpu; + struct kvm_pmu *pmu; + + pmu = container_of(work, struct kvm_pmu, overflow_work); + vcpu = kvm_pmc_to_vcpu(&pmu->pmc[0]); + + kvm_vcpu_kick(vcpu); +} + +/** * When the perf event overflows, set the overflow status and inform the vcpu. */ static void kvm_pmu_perf_overflow(struct perf_event *perf_event, @@ -435,7 +451,11 @@ static void kvm_pmu_perf_overflow(struct perf_event *perf_event, if (kvm_pmu_overflow_status(vcpu)) { kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu); - kvm_vcpu_kick(vcpu); + + if (!in_nmi()) + kvm_vcpu_kick(vcpu); + else + irq_work_queue(&vcpu->arch.pmu.overflow_work); } } @@ -706,6 +726,9 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu) return ret; } + init_irq_work(&vcpu->arch.pmu.overflow_work, + kvm_pmu_perf_overflow_notify_vcpu); + vcpu->arch.pmu.created = true; return 0; } -- 1.9.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-07-17 8:17 UTC|newest] Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-07-17 8:17 [PATCH v4 0/9] arm_pmu: Use NMI for perf interrupt Julien Thierry 2019-07-17 8:17 ` [PATCH v4 1/9] arm64: perf: avoid PMXEV* indirection Julien Thierry 2019-07-17 8:17 ` [PATCH v4 2/9] arm64: perf: Remove PMU locking Julien Thierry 2019-08-01 12:58 ` Will Deacon 2019-08-02 14:26 ` Julien Thierry 2019-07-17 8:17 ` [PATCH v4 3/9] arm: perf: save/resore pmsel Julien Thierry 2019-07-17 8:17 ` Julien Thierry 2019-08-01 13:01 ` Will Deacon 2019-08-01 13:01 ` Will Deacon 2019-08-02 14:34 ` Julien Thierry 2019-08-02 14:34 ` Julien Thierry 2019-07-17 8:17 ` [PATCH v4 4/9] arm: perf: Remove Remove PMU locking Julien Thierry 2019-08-01 13:06 ` Will Deacon 2019-08-02 14:36 ` Julien Thierry 2019-07-17 8:17 ` [PATCH v4 5/9] perf/arm_pmu: Move PMU lock to ARMv6 events Julien Thierry 2019-07-17 8:17 ` [PATCH v4 6/9] arm64: perf: Do not call irq_work_run in NMI context Julien Thierry 2019-08-01 13:06 ` Will Deacon 2019-08-02 14:43 ` Julien Thierry 2019-07-17 8:17 ` Julien Thierry [this message] 2019-07-17 8:17 ` [PATCH v4 7/9] arm/arm64: kvm: pmu: Make overflow handler NMI safe Julien Thierry 2019-07-30 20:57 ` Marc Zyngier 2019-07-17 8:17 ` [PATCH v4 8/9] arm_pmu: Introduce pmu_irq_ops Julien Thierry 2019-07-17 8:17 ` [PATCH v4 9/9] arm_pmu: Use NMIs for PMU Julien Thierry 2019-07-30 9:11 ` Russell King - ARM Linux admin 2019-07-30 9:18 ` Julien Thierry 2019-07-30 9:28 ` Russell King - ARM Linux admin 2019-07-30 14:06 ` Julien Thierry 2019-07-17 9:02 ` [PATCH v4 0/9] arm_pmu: Use NMI for perf interrupt Julien Thierry 2019-07-30 9:05 ` Julien Thierry
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=1563351432-55652-8-git-send-email-julien.thierry@arm.com \ --to=julien.thierry@arm.com \ --cc=acme@kernel.org \ --cc=alexander.shishkin@linux.intel.com \ --cc=jolsa@redhat.com \ --cc=kvmarm@lists.cs.columbia.edu \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=liwei391@huawei.com \ --cc=marc.zyngier@arm.com \ --cc=mingo@redhat.com \ --cc=namhyung@kernel.org \ --cc=peterz@infradead.org \ --cc=sthotton@marvell.com \ --cc=will.deacon@arm.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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.