mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Marc Zyngier <marc.zyngier@arm.com>
To: linux-kernel@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Jason Cooper <jason@lakedaemon.net>,
	Shanker Donthineni <shankerd@codeaurora.org>,
	Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>,
	Christoffer Dall <cdall@linaro.org>,
	Eric Auger <eric.auger@redhat.com>
Subject: [PATCH 10/10] irqchip/gic-v4: Make the doorbells managed affinity interrupts
Date: Tue, 10 Oct 2017 13:51:37 +0100	[thread overview]
Message-ID: <20171010125137.9464-11-marc.zyngier@arm.com> (raw)
In-Reply-To: <20171010125137.9464-1-marc.zyngier@arm.com>

We so far allocate the doorbell interrupts without taking any
special measure regarding the affinity of these interrupts. We
simply move them around as required when the vcpu gets scheduled
on a different CPU.

But that's counting without userspace (and the evil irqbalance) that
can try and move the VPE interrupt around, causing the ITS code
to emit VMOVP commands and remap the doorbell to another redistributor.
Worse, this can happen while the vcpu is running, causing all kind
of trouble as the VPE is not resident on this redistributor.

So let's take a definitive action and prevent userspace from messing
with us. This is just a matter of passing an affinity to the IRQ
allocator, and all the VPE interrupts will get the IRQD_AFFINITY_MANAGED
flag, which let the kernel is sole control of the affinity.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v4.c       | 35 +++++++++++++++++++++++++++++++++--
 include/linux/irqchip/arm-gic-v4.h |  1 +
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
index cd0bcc3b7e33..bd5382799788 100644
--- a/drivers/irqchip/irq-gic-v4.c
+++ b/drivers/irqchip/irq-gic-v4.c
@@ -86,7 +86,10 @@
  * - mask/unmask do what is expected on the doorbell interrupt.
  *
  * - irq_set_affinity is used to move a VPE from one redistributor to
- *   another.
+ *   another. Note that we make the doorbells a set of "managed
+ *   affinity" interrupts in order to prevent userspace from messing
+ *   with the affinity (you really don't want irqbalance to bounce
+ *   them around while the VPE is running).
  *
  * - irq_set_vcpu_affinity once again gets hijacked for the purpose of
  *   creating a new sub-API, namely scheduling/descheduling a VPE
@@ -97,10 +100,36 @@
 static struct irq_domain *gic_domain;
 static const struct irq_domain_ops *vpe_domain_ops;
 
+static void its_free_affinity_masks(struct its_vm *vm)
+{
+	int i;
+	
+	if (!vm->affinity_masks)
+		return;
+	
+	for (i = 0; i < vm->nr_vpes; i++)
+		if (vm->affinity_masks[i])
+			free_cpumask_var(vm->affinity_masks[i]);
+
+	kfree(vm->affinity_masks);
+}
+
 int its_alloc_vcpu_irqs(struct its_vm *vm)
 {
 	int vpe_base_irq, i;
 
+	vm->affinity_masks = kzalloc(vm->nr_vpes * sizeof(*vm->affinity_masks),
+				     GFP_KERNEL);
+	if (!vm->affinity_masks)
+		goto err;
+
+	for (i = 0; i < vm->nr_vpes; i++) {
+		if (!alloc_cpumask_var(&vm->affinity_masks[i], GFP_KERNEL))
+			goto err;
+
+		cpumask_copy(vm->affinity_masks[i], cpu_possible_mask);
+	}
+
 	vm->fwnode = irq_domain_alloc_named_id_fwnode("GICv4-vpe",
 						      task_pid_nr(current));
 	if (!vm->fwnode)
@@ -119,7 +148,7 @@ int its_alloc_vcpu_irqs(struct its_vm *vm)
 
 	vpe_base_irq = __irq_domain_alloc_irqs(vm->domain, -1, vm->nr_vpes,
 					       NUMA_NO_NODE, vm,
-					       false, NULL);
+					       false, *vm->affinity_masks);
 	if (vpe_base_irq <= 0)
 		goto err;
 
@@ -133,6 +162,7 @@ int its_alloc_vcpu_irqs(struct its_vm *vm)
 		irq_domain_remove(vm->domain);
 	if (vm->fwnode)
 		irq_domain_free_fwnode(vm->fwnode);
+	its_free_affinity_masks(vm);
 
 	return -ENOMEM;
 }
@@ -142,6 +172,7 @@ void its_free_vcpu_irqs(struct its_vm *vm)
 	irq_domain_free_irqs(vm->vpes[0]->irq, vm->nr_vpes);
 	irq_domain_remove(vm->domain);
 	irq_domain_free_fwnode(vm->fwnode);
+	its_free_affinity_masks(vm);
 }
 
 static int its_send_vpe_cmd(struct its_vpe *vpe, struct its_cmd_info *info)
diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
index 43cde15f221b..1052d654a863 100644
--- a/include/linux/irqchip/arm-gic-v4.h
+++ b/include/linux/irqchip/arm-gic-v4.h
@@ -32,6 +32,7 @@ struct its_vm {
 	struct irq_domain	*domain;
 	struct page		*vprop_page;
 	struct its_vpe		**vpes;
+	cpumask_var_t		*affinity_masks;
 	int			nr_vpes;
 	irq_hw_number_t		db_lpi_base;
 	unsigned long		*db_bitmap;
-- 
2.11.0

  parent reply	other threads:[~2017-10-10 12:52 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-10 12:51 [PATCH 00/10] irqchip: Proposed GICv4 updates for 4.15 Marc Zyngier
2017-10-10 12:51 ` [PATCH 01/10] irqchip/gic-v3-its: Add post-mortem info on command timeout Marc Zyngier
2017-10-10 12:51 ` [PATCH 02/10] irqchip/gic-v3-its: Pass its_node pointer to each command builder Marc Zyngier
2017-10-10 12:51 ` [PATCH 03/10] irqchip/gic-v3-its: Workaround HiSilicon Hip07 redistributor addressing Marc Zyngier
2017-10-10 12:51 ` [PATCH 04/10] irqchip/gic-v3-its: Track per-ITS list number Marc Zyngier
2017-10-10 12:51 ` [PATCH 05/10] irqchip/gic-v3-its: Make GICv4_ITS_LIST_MAX globally available Marc Zyngier
2017-10-10 12:51 ` [PATCH 06/10] irqchip/gic-v3-its: Make its_send_vinvall operate on a single ITS Marc Zyngier
2017-10-10 12:51 ` [PATCH 07/10] irqchip/gic-v3-its: Make its_send_vmapp " Marc Zyngier
2017-10-10 12:51 ` [PATCH 08/10] irqchip/gic-v3-its: Limit scope of VPE mapping to be per ITS Marc Zyngier
2017-10-10 12:51 ` [PATCH 09/10] irqchip/gic-v3-its: Only send VINVALL to a single ITS Marc Zyngier
2017-10-10 12:51 ` Marc Zyngier [this message]
2017-10-12  9:22   ` [PATCH 10/10] irqchip/gic-v4: Make the doorbells managed affinity interrupts Thomas Gleixner
2017-10-12 14:38     ` Marc Zyngier

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=20171010125137.9464-11-marc.zyngier@arm.com \
    --to=marc.zyngier@arm.com \
    --cc=cdall@linaro.org \
    --cc=eric.auger@redhat.com \
    --cc=jason@lakedaemon.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=shameerali.kolothum.thodi@huawei.com \
    --cc=shankerd@codeaurora.org \
    --cc=tglx@linutronix.de \
    /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

all inboxes | Powered by JetHome®