iommu.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
From: Jean-Philippe Brucker <jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
Cc: kevin.tian-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org,
	rafael-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org,
	will.deacon-5wv7dgnIgG8@public.gmane.org,
	christian.koenig-5C7GfCeVMHo@public.gmane.org,
	alex.williamson-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
	robin.murphy-5wv7dgnIgG8@public.gmane.org
Subject: [RFC PATCH 6/6] iommu/arm-smmu-v3: Add support for auxiliary domains
Date: Fri, 19 Oct 2018 19:11:58 +0100	[thread overview]
Message-ID: <20181019181158.2395-7-jean-philippe.brucker@arm.com> (raw)
In-Reply-To: <20181019181158.2395-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>

Allow device driver to create PASID contexts by setting a device in
'auxiliary' mode and allocating new domains. Each domain corrsponds to a
PASID.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
---
 drivers/iommu/arm-smmu-v3.c | 157 ++++++++++++++++++++++++++++++++++--
 1 file changed, 151 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 665365b5f02e..ae10c78d20a8 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -539,6 +539,7 @@ struct arm_smmu_s1_cfg {
 	struct iommu_pasid_table_cfg	tables;
 	struct iommu_pasid_table_ops	*ops;
 	struct iommu_pasid_entry	*cd0; /* Default context */
+	int				pasid;
 };
 
 struct arm_smmu_s2_cfg {
@@ -656,6 +657,7 @@ struct arm_smmu_master_data {
 	struct device			*dev;
 	size_t				ssid_bits;
 	bool				can_fault;
+	bool				auxd;
 };
 
 /* SMMU private data for an IOMMU domain */
@@ -715,6 +717,13 @@ static struct arm_smmu_mm *to_smmu_mm(struct io_mm *io_mm)
 	return container_of(io_mm, struct arm_smmu_mm, io_mm);
 }
 
+static struct arm_smmu_master_data *dev_to_master(struct device *dev)
+{
+	struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+
+	return fwspec ? fwspec->iommu_priv : NULL;
+}
+
 static void parse_driver_options(struct arm_smmu_device *smmu)
 {
 	int i = 0;
@@ -2007,10 +2016,12 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
 	if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
 		struct iommu_pasid_table_ops *ops = smmu_domain->s1_cfg.ops;
 
-		if (ops) {
+		if (smmu_domain->s1_cfg.pasid)
+			iommu_sva_free_pasid(smmu_domain->s1_cfg.pasid);
+		if (smmu_domain->s1_cfg.cd0)
 			iommu_free_pasid_entry(smmu_domain->s1_cfg.cd0);
+		if (ops)
 			iommu_free_pasid_ops(ops);
-		}
 	} else {
 		struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
 		if (cfg->vmid)
@@ -2068,6 +2079,28 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
 	return ret;
 }
 
+static int arm_smmu_domain_finalise_aux(struct arm_smmu_domain *smmu_domain,
+					struct arm_smmu_master_data *master,
+					struct io_pgtable_cfg *pgtbl_cfg)
+{
+	struct iommu_pasid_entry *entry;
+	struct iommu_pasid_table_ops *ops;
+
+	if (!master->ste.s1_cfg)
+		return -EINVAL;
+
+	ops = master->ste.s1_cfg->ops;
+	if (!ops)
+		return -EINVAL;
+
+	entry = ops->alloc_priv_entry(ops, ARM_64_LPAE_S1, pgtbl_cfg);
+	if (IS_ERR(entry))
+		return PTR_ERR(entry);
+
+	smmu_domain->s1_cfg.cd0 = entry; /* FIXME: cd, not cd0 */
+	return 0;
+}
+
 static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
 				       struct arm_smmu_master_data *master,
 				       struct io_pgtable_cfg *pgtbl_cfg)
@@ -2130,6 +2163,13 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain,
 		return -EINVAL;
 	}
 
+	if (master->auxd) {
+		if (WARN_ON(smmu_domain->stage != ARM_SMMU_DOMAIN_S1))
+			return -EINVAL;
+		/* We're initializing an auxiliary domain */
+		finalise_stage_fn = arm_smmu_domain_finalise_aux;
+	}
+
 	pgtbl_cfg = (struct io_pgtable_cfg) {
 		.pgsize_bitmap	= smmu->pgsize_bitmap,
 		.ias		= ias,
@@ -2202,11 +2242,36 @@ static void arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec)
 	}
 }
 
+static void arm_smmu_detach_dev_aux(struct arm_smmu_domain *smmu_domain,
+				    struct arm_smmu_master_data *master)
+{
+	int pasid;
+	struct iommu_pasid_table_ops *ops = master->ste.s1_cfg->ops;
+
+	if (WARN_ON(!ops))
+		return;
+
+	pasid = smmu_domain->s1_cfg.pasid;
+	if (WARN_ON(!pasid))
+		return;
+	ops->clear_entry(ops, pasid, smmu_domain->s1_cfg.cd0);
+	arm_smmu_atc_inv_master_all(master, pasid);
+	/*
+	 * We don't count the number of attached devices, so free the
+	 * PASID in domain_free.
+	 */
+}
+
 static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev)
 {
 	unsigned long flags;
 	struct arm_smmu_master_data *master = dev->iommu_fwspec->iommu_priv;
-	struct arm_smmu_domain *smmu_domain = master->domain;
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+
+	if (master->auxd) {
+		arm_smmu_detach_dev_aux(smmu_domain, master);
+		return;
+	}
 
 	if (smmu_domain) {
 		iommu_sva_unbind_device_all(dev);
@@ -2224,6 +2289,39 @@ static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev)
 	arm_smmu_install_ste_for_dev(dev->iommu_fwspec);
 }
 
+static int arm_smmu_attach_dev_aux(struct arm_smmu_domain *smmu_domain,
+				   struct arm_smmu_master_data *master)
+{
+	int pasid, ret;
+	struct iommu_pasid_table_ops *ops = master->ste.s1_cfg->ops;
+
+	if (!ops)
+		return -EINVAL;
+
+	if (smmu_domain->s1_cfg.pasid) {
+		/*
+		 * Reuse PASID if already allocated for another device. As the
+		 * PASID space is global and this is the same SMMU, we know that
+		 * the below set_entry will work.
+		 *
+		 * TODO: check device boundaries (sva_param)
+		 */
+		pasid = smmu_domain->s1_cfg.pasid;
+	} else {
+		pasid = iommu_sva_alloc_pasid(master->dev);
+		if (pasid < 0)
+			return pasid;
+
+		smmu_domain->s1_cfg.pasid = pasid;
+	}
+
+	ret = ops->set_entry(ops, pasid, smmu_domain->s1_cfg.cd0);
+	if (ret)
+		return ret;
+
+	return 1; /* Auxd needs special value. */
+}
+
 static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 {
 	int ret = 0;
@@ -2240,8 +2338,12 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 	smmu = master->smmu;
 	ste = &master->ste;
 
+	/* Spurious attach_dev when doing detach on an aux domain... */
+	if (master->domain == smmu_domain)
+		return !!master->auxd;
+
 	/* Already attached to a different domain? */
-	if (master->domain)
+	if (master->domain && !master->auxd)
 		arm_smmu_detach_dev(&master->domain->domain, dev);
 
 	mutex_lock(&smmu_domain->init_mutex);
@@ -2262,6 +2364,12 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 		goto out_unlock;
 	}
 
+	if (master->auxd) {
+		/* Now install the context descriptor */
+		ret = arm_smmu_attach_dev_aux(smmu_domain, master);
+		goto out_unlock;
+	}
+
 	ste->assigned = true;
 	master->domain = smmu_domain;
 
@@ -2411,7 +2519,7 @@ static int arm_smmu_sva_init(struct device *dev, struct iommu_sva_param *param)
 	if (!master->ssid_bits)
 		return -EINVAL;
 
-	if (param->features & ~IOMMU_SVA_FEAT_IOPF)
+	if (param->features & ~(IOMMU_SVA_FEAT_IOPF | IOMMU_SVA_FEAT_AUXD))
 		return -EINVAL;
 
 	if (param->features & IOMMU_SVA_FEAT_IOPF) {
@@ -2426,6 +2534,9 @@ static int arm_smmu_sva_init(struct device *dev, struct iommu_sva_param *param)
 			goto err_disable_pri;
 	}
 
+	if (param->features & IOMMU_SVA_FEAT_AUXD)
+		master->auxd = true;
+
 	if (!param->max_pasid)
 		param->max_pasid = 0xfffffU;
 
@@ -2443,7 +2554,13 @@ static int arm_smmu_sva_init(struct device *dev, struct iommu_sva_param *param)
 
 static void arm_smmu_sva_shutdown(struct device *dev)
 {
-	arm_smmu_disable_pri(dev->iommu_fwspec->iommu_priv);
+	struct arm_smmu_master_data *master = dev_to_master(dev);
+
+	if (!master)
+		return;
+
+	master->auxd = false;
+	arm_smmu_disable_pri(master);
 	iopf_queue_remove_device(dev);
 }
 
@@ -2874,6 +2991,11 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
 	case DOMAIN_ATTR_NESTING:
 		*(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED);
 		return 0;
+	case DOMAIN_ATTR_AUXD_ID:
+		if (smmu_domain->stage != ARM_SMMU_DOMAIN_S1)
+			return -EINVAL;
+		*(int *)data = smmu_domain->s1_cfg.pasid;
+		return 0;
 	default:
 		return -ENODEV;
 	}
@@ -2912,6 +3034,28 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
 	return ret;
 }
 
+static int arm_smmu_get_dev_attr(struct device *dev, enum iommu_dev_attr attr,
+				 void *data)
+{
+	bool *auxd;
+	struct arm_smmu_master_data *master = dev_to_master(dev);
+
+	if (!master || !data)
+		return -ENODEV;
+
+	switch (attr) {
+	case IOMMU_DEV_ATTR_AUXD_CAPABILITY:
+		auxd = data;
+		/* PASID supported */
+		*auxd = !!master->ssid_bits;
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
 static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
 {
 	return iommu_fwspec_add_ids(dev, args->args, 1);
@@ -2966,6 +3110,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.device_group		= arm_smmu_device_group,
 	.domain_get_attr	= arm_smmu_domain_get_attr,
 	.domain_set_attr	= arm_smmu_domain_set_attr,
+	.get_dev_attr		= arm_smmu_get_dev_attr,
 	.of_xlate		= arm_smmu_of_xlate,
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.put_resv_regions	= arm_smmu_put_resv_regions,
-- 
2.19.1

  parent reply	other threads:[~2018-10-19 18:11 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-19 18:11 [RFC PATCH 0/6] Auxiliary IOMMU domains and Arm SMMUv3 Jean-Philippe Brucker
     [not found] ` <20181019181158.2395-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2018-10-19 18:11   ` [RFC PATCH 1/6] iommu: Adapt attach/detach_dev() for auxiliary domains Jean-Philippe Brucker
     [not found]     ` <20181019181158.2395-2-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2018-10-22  2:32       ` Lu Baolu
2018-10-19 18:11   ` [RFC PATCH 2/6] drivers core: Add I/O ASID allocator Jean-Philippe Brucker
     [not found]     ` <20181019181158.2395-3-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2018-10-22  4:49       ` Lu Baolu
     [not found]         ` <9c6cd6c1-3569-4251-8344-fc9df0e743bc-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2018-10-22 10:22           ` Raj, Ashok
     [not found]             ` <20181022102254.GA25399-7RUrO8UaCDyr4tA6zuQqW9h3ngVCH38I@public.gmane.org>
2018-10-23  6:56               ` Lu Baolu
     [not found]                 ` <02006e4f-2acf-6ff8-b695-c54c99509b46-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2018-10-23 22:13                   ` Tian, Kevin
2018-11-07  4:53       ` Lu Baolu
     [not found]         ` <fb2bd5fe-5742-fcd8-b8f0-1885040e8d4f-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2018-11-08 18:51           ` Jean-Philippe Brucker
2018-11-12 14:40       ` Joerg Roedel
     [not found]         ` <20181112144039.GA25808-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
2018-11-21 11:16           ` Jean-Philippe Brucker
     [not found]             ` <8f17757a-c657-aab9-a6a0-fb0cc9c610a8-5wv7dgnIgG8@public.gmane.org>
2018-11-21 19:10               ` Koenig, Christian
     [not found]                 ` <62f05552-df46-6e12-10ed-820429dfda59-5C7GfCeVMHo@public.gmane.org>
2018-11-22  6:59                   ` Tian, Kevin
2018-11-22  8:38                   ` Joerg Roedel
2018-11-22  8:44               ` Joerg Roedel
     [not found]                 ` <20181122084429.GB1586-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
2018-11-22 11:17                   ` Jean-Philippe Brucker
2018-10-19 18:11   ` [RFC PATCH 3/6] iommu/sva: Use external PASID allocator Jean-Philippe Brucker
2018-10-19 18:11   ` [RFC PATCH 4/6] iommu/sva: Support AUXD feature Jean-Philippe Brucker
2018-10-19 18:11   ` [RFC PATCH 5/6] iommu/arm-smmu-v3: Implement detach_dev op Jean-Philippe Brucker
2018-10-19 18:11   ` Jean-Philippe Brucker [this message]
2018-10-20  3:36   ` [RFC PATCH 0/6] Auxiliary IOMMU domains and Arm SMMUv3 Xu Zaibo
2018-10-22  6:53   ` Tian, Kevin
     [not found]     ` <AADFC41AFE54684AB9EE6CBC0274A5D19BE0E176-0J0gbvR4kThpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2018-10-22 11:50       ` Robin Murphy
     [not found]         ` <11f88122-afd3-a34c-3cd4-db681bf5498b-5wv7dgnIgG8@public.gmane.org>
2018-10-22 15:35           ` Jordan Crouse
2018-10-22 18:01           ` Jean-Philippe Brucker
2018-11-06 16:25           ` joro-zLv9SwRftAIdnm+yROfE0A
     [not found]             ` <20181106162539.4gmkvg57mja3bn7k-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
2018-11-07  3:40               ` Lu Baolu
     [not found]                 ` <e22e3631-2ecb-664d-5666-8e0f865dec83-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2018-11-07 16:43                   ` joro-zLv9SwRftAIdnm+yROfE0A
     [not found]                     ` <20181107164323.GA19831-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
2018-11-07 17:23                       ` Alex Williamson
2018-11-21  4:40                       ` Lu Baolu
     [not found]                         ` <758bb120-5bc0-1e2d-ccd0-9be0bcc5d8bc-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2018-11-23 11:21                           ` joro-zLv9SwRftAIdnm+yROfE0A
     [not found]                             ` <20181123112125.GF1586-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
2018-11-25  6:51                               ` Lu Baolu
2018-11-26  3:01                               ` Tian, Kevin
     [not found]                             ` <AADFC41AFE54684AB9EE6CBC0274A5D19BE68777@SHSMSX101.ccr.corp.intel.com>
     [not found]                               ` <AADFC41AFE54684AB9EE6CBC0274A5D19BE68777-0J0gbvR4kThpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2018-11-26  7:29                                 ` Tian, Kevin
     [not found]                                   ` <AADFC41AFE54684AB9EE6CBC0274A5D19BE689B8-0J0gbvR4kThpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2018-12-07 10:29                                     ` 'joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org'
     [not found]                                       ` <20181207102926.GM16835-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
2018-12-10  2:06                                         ` Tian, Kevin
     [not found]                                           ` <AADFC41AFE54684AB9EE6CBC0274A5D19BE95394-0J0gbvR4kThpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2018-12-10  8:57                                             ` 'joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org'
     [not found]                                               ` <20181210085745.GN16835-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
2018-12-11 18:34                                                 ` Jean-Philippe Brucker
     [not found]                                                   ` <4be63d12-fa1c-b180-761b-5e8ceed58545-5wv7dgnIgG8@public.gmane.org>
2018-12-12  9:22                                                     ` 'joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org'
2018-12-12  9:31                                                 ` Tian, Kevin
     [not found]                                                   ` <AADFC41AFE54684AB9EE6CBC0274A5D19BE9D6CA-0J0gbvR4kThpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2018-12-12  9:54                                                     ` 'joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org'
     [not found]                                                       ` <20181212095403.GU16835-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
2018-12-12 10:03                                                         ` Tian, Kevin
2018-12-10  2:57                                         ` Lu Baolu
     [not found]                                           ` <bf1ee4a3-6d3f-e0db-a02a-1db819843a60-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2018-12-10  8:59                                             ` 'joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org'
2018-12-11 13:35                                         ` Jean-Philippe Brucker
     [not found]                                           ` <fc173d9f-57e2-dd87-95d0-1c615f2e14e3-5wv7dgnIgG8@public.gmane.org>
2018-12-12  9:29                                             ` 'joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org'
2018-11-08 18:29               ` Jean-Philippe Brucker
     [not found]                 ` <42949d93-e22c-dd4d-cd49-46efc0b73cdb-5wv7dgnIgG8@public.gmane.org>
2018-11-12 14:55                   ` joro-zLv9SwRftAIdnm+yROfE0A
     [not found]                     ` <20181112145541.GB25808-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>
2018-11-21 19:05                       ` Jean-Philippe Brucker
     [not found]                         ` <5dcf9238-62b2-8df6-b378-183ee09c5951-5wv7dgnIgG8@public.gmane.org>
2018-11-23 12:50                           ` joro-zLv9SwRftAIdnm+yROfE0A
2018-11-22  8:39                       ` Tian, Kevin
     [not found]                         ` <AADFC41AFE54684AB9EE6CBC0274A5D19BE5A7A7-0J0gbvR4kThpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2018-11-23 12:14                           ` joro-zLv9SwRftAIdnm+yROfE0A
2018-10-22 10:07   ` Raj, Ashok
     [not found]     ` <20181021194426.GA11201-7RUrO8UaCDyr4tA6zuQqW9h3ngVCH38I@public.gmane.org>
2018-10-22 16:03       ` Jean-Philippe Brucker
     [not found]         ` <d45c5222-68e9-1d6e-730b-bb8dbc060586-5wv7dgnIgG8@public.gmane.org>
2018-10-23 17:16           ` Raj, Ashok
     [not found]             ` <1540314963.21962.20.camel-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2018-10-23 22:08               ` Tian, Kevin
2018-10-26  3:00           ` Lu Baolu
2018-10-22 16:48   ` Jordan Crouse
     [not found]     ` <20181022164834.GH26762-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
2018-11-02  3:19       ` Lu Baolu

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=20181019181158.2395-7-jean-philippe.brucker@arm.com \
    --to=jean-philippe.brucker-5wv7dgnigg8@public.gmane.org \
    --cc=alex.williamson-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=christian.koenig-5C7GfCeVMHo@public.gmane.org \
    --cc=gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org \
    --cc=iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
    --cc=kevin.tian-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
    --cc=rafael-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=robin.murphy-5wv7dgnIgG8@public.gmane.org \
    --cc=will.deacon-5wv7dgnIgG8@public.gmane.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).