qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Nicholas Piggin <npiggin@gmail.com>
To: qemu-ppc@nongnu.org
Cc: "Nicholas Piggin" <npiggin@gmail.com>,
	qemu-devel@nongnu.org, "Frédéric Barrat" <fbarrat@linux.ibm.com>,
	"Glenn Miles" <milesg@linux.ibm.com>,
	"Michael Kowal" <kowal@linux.ibm.com>,
	"Caleb Schlossin" <calebs@linux.vnet.ibm.com>
Subject: [PATCH 22/50] ppc/xive2: Support redistribution of group interrupts
Date: Mon, 12 May 2025 13:10:31 +1000	[thread overview]
Message-ID: <20250512031100.439842-23-npiggin@gmail.com> (raw)
In-Reply-To: <20250512031100.439842-1-npiggin@gmail.com>

From: Glenn Miles <milesg@linux.ibm.com>

When an XIVE context is pulled while it has an active, unacknowledged
group interrupt, XIVE will check to see if a context on another thread
can handle the interrupt and, if so, notify that context.  If there
are no contexts that can handle the interrupt, then the interrupt is
added to a backlog and XIVE will attempt to escalate the interrupt,
if configured to do so, allowing the higher privileged handler to
activate a context that can handle the original interrupt.

Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
---
 hw/intc/xive2.c             | 84 +++++++++++++++++++++++++++++++++++--
 include/hw/ppc/xive2_regs.h |  3 ++
 2 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
index 0993e792cc..34fc561c9c 100644
--- a/hw/intc/xive2.c
+++ b/hw/intc/xive2.c
@@ -19,6 +19,10 @@
 #include "hw/ppc/xive2_regs.h"
 #include "trace.h"
 
+static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk,
+                                    uint32_t end_idx, uint32_t end_data,
+                                    bool redistribute);
+
 uint32_t xive2_router_get_config(Xive2Router *xrtr)
 {
     Xive2RouterClass *xrc = XIVE2_ROUTER_GET_CLASS(xrtr);
@@ -597,6 +601,68 @@ static uint32_t xive2_tctx_hw_cam_line(XivePresenter *xptr, XiveTCTX *tctx)
     return xive2_nvp_cam_line(blk, 1 << tid_shift | (pir & tid_mask));
 }
 
+static void xive2_redistribute(Xive2Router *xrtr, XiveTCTX *tctx,
+                               uint8_t nvp_blk, uint32_t nvp_idx, uint8_t ring)
+{
+    uint8_t nsr = tctx->regs[ring + TM_NSR];
+    uint8_t crowd = NVx_CROWD_LVL(nsr);
+    uint8_t group = NVx_GROUP_LVL(nsr);
+    uint8_t nvgc_blk;
+    uint8_t nvgc_idx;
+    uint8_t end_blk;
+    uint32_t end_idx;
+    uint8_t pipr = tctx->regs[ring + TM_PIPR];
+    Xive2Nvgc nvgc;
+    uint8_t prio_limit;
+    uint32_t cfg;
+
+    /* convert crowd/group to blk/idx */
+    if (group > 0) {
+        nvgc_idx = (nvp_idx & (0xffffffff << group)) |
+                   ((1 << (group - 1)) - 1);
+    } else {
+        nvgc_idx = nvp_idx;
+    }
+
+    if (crowd > 0) {
+        crowd = (crowd == 3) ? 4 : crowd;
+        nvgc_blk = (nvp_blk & (0xffffffff << crowd)) |
+                   ((1 << (crowd - 1)) - 1);
+    } else {
+        nvgc_blk = nvp_blk;
+    }
+
+    /* Use blk/idx to retrieve the NVGC */
+    if (xive2_router_get_nvgc(xrtr, crowd, nvgc_blk, nvgc_idx, &nvgc)) {
+        qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no %s %x/%x\n",
+                      crowd ? "NVC" : "NVG", nvgc_blk, nvgc_idx);
+        return;
+    }
+
+    /* retrieve the END blk/idx from the NVGC */
+    end_blk = xive_get_field32(NVGC2_W1_END_BLK, nvgc.w1);
+    end_idx = xive_get_field32(NVGC2_W1_END_IDX, nvgc.w1);
+
+    /* determine number of priorities being used */
+    cfg = xive2_router_get_config(xrtr);
+    if (cfg & XIVE2_EN_VP_GRP_PRIORITY) {
+        prio_limit = 1 << GETFIELD(NVGC2_W1_PSIZE, nvgc.w1);
+    } else {
+        prio_limit = 1 << GETFIELD(XIVE2_VP_INT_PRIO, cfg);
+    }
+
+    /* add priority offset to end index */
+    end_idx += pipr % prio_limit;
+
+    /* trigger the group END */
+    xive2_router_end_notify(xrtr, end_blk, end_idx, 0, true);
+
+    /* clear interrupt indication for the context */
+    tctx->regs[ring + TM_NSR] = 0;
+    tctx->regs[ring + TM_PIPR] = tctx->regs[ring + TM_CPPR];
+    xive_tctx_reset_signal(tctx, ring);
+}
+
 static uint64_t xive2_tm_pull_ctx(XivePresenter *xptr, XiveTCTX *tctx,
                                   hwaddr offset, unsigned size, uint8_t ring)
 {
@@ -608,6 +674,7 @@ static uint64_t xive2_tm_pull_ctx(XivePresenter *xptr, XiveTCTX *tctx,
     uint8_t cur_ring;
     bool valid;
     bool do_save;
+    uint8_t nsr;
 
     xive2_cam_decode(cam, &nvp_blk, &nvp_idx, &valid, &do_save);
 
@@ -624,6 +691,12 @@ static uint64_t xive2_tm_pull_ctx(XivePresenter *xptr, XiveTCTX *tctx,
         memcpy(&tctx->regs[cur_ring + TM_WORD2], &ringw2_new, 4);
     }
 
+    /* Active group/crowd interrupts need to be redistributed */
+    nsr = tctx->regs[ring + TM_NSR];
+    if (xive_nsr_indicates_group_exception(ring, nsr)) {
+        xive2_redistribute(xrtr, tctx, nvp_blk, nvp_idx, ring);
+    }
+
     if (xive2_router_get_config(xrtr) & XIVE2_VP_SAVE_RESTORE && do_save) {
         xive2_tctx_save_ctx(xrtr, tctx, nvp_blk, nvp_idx, ring);
     }
@@ -1352,7 +1425,8 @@ static bool xive2_router_end_es_notify(Xive2Router *xrtr, uint8_t end_blk,
  * message has the same parameters than in the function below.
  */
 static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk,
-                                    uint32_t end_idx, uint32_t end_data)
+                                    uint32_t end_idx, uint32_t end_data,
+                                    bool redistribute)
 {
     Xive2End end;
     uint8_t priority;
@@ -1380,7 +1454,7 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk,
         return;
     }
 
-    if (xive2_end_is_enqueue(&end)) {
+    if (!redistribute && xive2_end_is_enqueue(&end)) {
         xive2_end_enqueue(&end, end_data);
         /* Enqueuing event data modifies the EQ toggle and index */
         xive2_router_write_end(xrtr, end_blk, end_idx, &end, 1);
@@ -1560,7 +1634,8 @@ do_escalation:
         xive2_router_end_notify(xrtr,
                                xive_get_field32(END2_W4_END_BLOCK,     end.w4),
                                xive_get_field32(END2_W4_ESC_END_INDEX, end.w4),
-                               xive_get_field32(END2_W5_ESC_END_DATA,  end.w5));
+                               xive_get_field32(END2_W5_ESC_END_DATA,  end.w5),
+                               false);
     } /* end END adaptive escalation */
 
     else {
@@ -1641,7 +1716,8 @@ void xive2_notify(Xive2Router *xrtr , uint32_t lisn, bool pq_checked)
     xive2_router_end_notify(xrtr,
                             xive_get_field64(EAS2_END_BLOCK, eas.w),
                             xive_get_field64(EAS2_END_INDEX, eas.w),
-                            xive_get_field64(EAS2_END_DATA,  eas.w));
+                            xive_get_field64(EAS2_END_DATA,  eas.w),
+                            false);
     return;
 }
 
diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h
index 2c535ec0d0..e222038143 100644
--- a/include/hw/ppc/xive2_regs.h
+++ b/include/hw/ppc/xive2_regs.h
@@ -224,6 +224,9 @@ typedef struct Xive2Nvgc {
 #define NVGC2_W0_VALID             PPC_BIT32(0)
 #define NVGC2_W0_PGONEXT           PPC_BITMASK32(26, 31)
         uint32_t        w1;
+#define NVGC2_W1_PSIZE             PPC_BITMASK32(0, 1)
+#define NVGC2_W1_END_BLK           PPC_BITMASK32(4, 7)
+#define NVGC2_W1_END_IDX           PPC_BITMASK32(8, 31)
         uint32_t        w2;
         uint32_t        w3;
         uint32_t        w4;
-- 
2.47.1



  parent reply	other threads:[~2025-05-12  3:19 UTC|newest]

Thread overview: 192+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-12  3:10 [PATCH 00/50] ppc/xive: updates for PowerVM Nicholas Piggin
2025-05-12  3:10 ` [PATCH 01/50] ppc/xive: Fix xive trace event output Nicholas Piggin
2025-05-14 14:26   ` Caleb Schlossin
2025-05-14 18:41   ` Mike Kowal
2025-05-15 15:30   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 02/50] ppc/xive: Report access size in XIVE TM operation error logs Nicholas Piggin
2025-05-14 14:27   ` Caleb Schlossin
2025-05-14 18:42   ` Mike Kowal
2025-05-15 15:31   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 03/50] ppc/xive2: Fix calculation of END queue sizes Nicholas Piggin
2025-05-14 14:27   ` Caleb Schlossin
2025-05-14 18:45   ` Mike Kowal
2025-05-16  0:06   ` Nicholas Piggin
2025-05-12  3:10 ` [PATCH 04/50] ppc/xive2: Remote VSDs need to match on forwarding address Nicholas Piggin
2025-05-14 14:27   ` Caleb Schlossin
2025-05-14 18:46   ` Mike Kowal
2025-05-15 15:34   ` Miles Glenn
2025-05-16  0:08   ` Nicholas Piggin
2025-05-12  3:10 ` [PATCH 05/50] ppc/xive2: fix context push calculation of IPB priority Nicholas Piggin
2025-05-14 14:30   ` Caleb Schlossin
2025-05-14 18:48   ` Mike Kowal
2025-05-15 15:36   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 06/50] ppc/xive: Fix PHYS NSR ring matching Nicholas Piggin
2025-05-14 14:30   ` Caleb Schlossin
2025-05-14 18:49   ` Mike Kowal
2025-05-15 15:39   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 07/50] ppc/xive2: Reset Generation Flipped bit on END Cache Watch Nicholas Piggin
2025-05-14 14:30   ` Caleb Schlossin
2025-05-14 18:50   ` Mike Kowal
2025-05-15 15:41   ` Miles Glenn
2025-05-16  0:09   ` Nicholas Piggin
2025-05-12  3:10 ` [PATCH 08/50] ppc/xive2: Use fair irq target search algorithm Nicholas Piggin
2025-05-14 14:31   ` Caleb Schlossin
2025-05-14 18:51   ` Mike Kowal
2025-05-15 15:42   ` Miles Glenn
2025-05-16  0:12   ` Nicholas Piggin
2025-05-16 16:22     ` Mike Kowal
2025-05-12  3:10 ` [PATCH 09/50] ppc/xive2: Fix irq preempted by lower priority group irq Nicholas Piggin
2025-05-14 14:31   ` Caleb Schlossin
2025-05-14 18:52   ` Mike Kowal
2025-05-16  0:12   ` Nicholas Piggin
2025-05-12  3:10 ` [PATCH 10/50] ppc/xive2: Fix treatment of PIPR in CPPR update Nicholas Piggin
2025-05-14 14:32   ` Caleb Schlossin
2025-05-14 18:53   ` Mike Kowal
2025-05-16  0:15   ` Nicholas Piggin
2025-05-12  3:10 ` [PATCH 11/50] ppc/xive2: Do not present group interrupt on OS-push if precluded by CPPR Nicholas Piggin
2025-05-14 14:32   ` Caleb Schlossin
2025-05-14 18:54   ` Mike Kowal
2025-05-15 15:43   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 12/50] ppc/xive2: Set CPPR delivery should account for group priority Nicholas Piggin
2025-05-14 14:33   ` Caleb Schlossin
2025-05-14 18:57   ` Mike Kowal
2025-05-15 15:45   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 13/50] ppc/xive: tctx_notify should clear the precluded interrupt Nicholas Piggin
2025-05-14 14:33   ` Caleb Schlossin
2025-05-14 18:58   ` Mike Kowal
2025-05-15 15:46   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 14/50] ppc/xive: Explicitly zero NSR after accepting Nicholas Piggin
2025-05-14 14:34   ` Caleb Schlossin
2025-05-14 19:07   ` Mike Kowal
2025-05-15 23:31     ` Nicholas Piggin
2025-05-15 15:47   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 15/50] ppc/xive: Move NSR decoding into helper functions Nicholas Piggin
2025-05-14 14:35   ` Caleb Schlossin
2025-05-14 19:04   ` Mike Kowal
2025-05-15 15:48   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 16/50] ppc/xive: Fix pulling pool and phys contexts Nicholas Piggin
2025-05-14 14:36   ` Caleb Schlossin
2025-05-14 19:01   ` Mike Kowal
2025-05-15 15:49   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 17/50] pnv/xive2: Support ESB Escalation Nicholas Piggin
2025-05-14 14:36   ` Caleb Schlossin
2025-05-14 19:00   ` Mike Kowal
2025-05-16  0:05   ` Nicholas Piggin
2025-05-16 15:44     ` Miles Glenn
2025-05-12  3:10 ` [PATCH 18/50] pnv/xive2: Print value in invalid register write logging Nicholas Piggin
2025-05-14 14:36   ` Caleb Schlossin
2025-05-14 19:09   ` Mike Kowal
2025-05-15 15:50   ` Miles Glenn
2025-05-16  0:15   ` Nicholas Piggin
2025-05-12  3:10 ` [PATCH 19/50] pnv/xive2: VC_ENDC_WATCH_SPEC regs should read back WATCH_FULL Nicholas Piggin
2025-05-14 14:37   ` Caleb Schlossin
2025-05-14 19:10   ` Mike Kowal
2025-05-15 15:51   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 20/50] pnv/xive2: Permit valid writes to VC/PC Flush Control registers Nicholas Piggin
2025-05-14 14:37   ` Caleb Schlossin
2025-05-14 19:11   ` Mike Kowal
2025-05-15 15:52   ` Miles Glenn
2025-05-16  0:18   ` Nicholas Piggin
2025-05-12  3:10 ` [PATCH 21/50] ppc/xive2: add interrupt priority configuration flags Nicholas Piggin
2025-05-14 19:41   ` Mike Kowal
2025-05-16  0:18   ` Nicholas Piggin
2025-05-12  3:10 ` Nicholas Piggin [this message]
2025-05-14 19:42   ` [PATCH 22/50] ppc/xive2: Support redistribution of group interrupts Mike Kowal
2025-05-16  0:19   ` Nicholas Piggin
2025-05-12  3:10 ` [PATCH 23/50] ppc/xive: Add more interrupt notification tracing Nicholas Piggin
2025-05-14 19:46   ` Mike Kowal
2025-05-16  0:19   ` Nicholas Piggin
2025-05-12  3:10 ` [PATCH 24/50] ppc/xive2: Improve pool regs variable name Nicholas Piggin
2025-05-14 19:47   ` Mike Kowal
2025-05-16  0:19   ` Nicholas Piggin
2025-05-12  3:10 ` [PATCH 25/50] ppc/xive2: Implement "Ack OS IRQ to even report line" TIMA op Nicholas Piggin
2025-05-14 19:48   ` Mike Kowal
2025-05-16  0:20   ` Nicholas Piggin
2025-05-12  3:10 ` [PATCH 26/50] ppc/xive2: Redistribute group interrupt precluded by CPPR update Nicholas Piggin
2025-05-14 19:48   ` Mike Kowal
2025-05-16  0:20   ` Nicholas Piggin
2025-05-12  3:10 ` [PATCH 27/50] ppc/xive2: redistribute irqs for pool and phys ctx pull Nicholas Piggin
2025-05-14 19:51   ` Mike Kowal
2025-05-12  3:10 ` [PATCH 28/50] ppc/xive: Change presenter .match_nvt to match not present Nicholas Piggin
2025-05-14 19:54   ` Mike Kowal
2025-05-15 23:40     ` Nicholas Piggin
2025-05-15 15:53   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 29/50] ppc/xive2: Redistribute group interrupt preempted by higher priority interrupt Nicholas Piggin
2025-05-14 19:55   ` Mike Kowal
2025-05-15 15:54   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 30/50] ppc/xive: Add xive_tctx_pipr_present() to present new interrupt Nicholas Piggin
2025-05-14 20:10   ` Mike Kowal
2025-05-15 15:21     ` Mike Kowal
2025-05-15 23:51       ` Nicholas Piggin
2025-05-15 23:43     ` Nicholas Piggin
2025-05-15 15:55   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 31/50] ppc/xive: Fix high prio group interrupt being preempted by low prio VP Nicholas Piggin
2025-05-15 15:21   ` Mike Kowal
2025-05-15 15:55   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 32/50] ppc/xive: Split xive recompute from IPB function Nicholas Piggin
2025-05-14 20:42   ` Mike Kowal
2025-05-15 23:46     ` Nicholas Piggin
2025-05-15 15:56   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 33/50] ppc/xive: tctx signaling registers rework Nicholas Piggin
2025-05-14 20:49   ` Mike Kowal
2025-05-15 15:58   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 34/50] ppc/xive: tctx_accept only lower irq line if an interrupt was presented Nicholas Piggin
2025-05-15 15:16   ` Mike Kowal
2025-05-15 23:50     ` Nicholas Piggin
2025-05-15 16:04   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 35/50] ppc/xive: Add xive_tctx_pipr_set() helper function Nicholas Piggin
2025-05-15 15:18   ` Mike Kowal
2025-05-15 16:05   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 36/50] ppc/xive2: split tctx presentation processing from set CPPR Nicholas Piggin
2025-05-15 15:24   ` Mike Kowal
2025-05-15 16:06   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 37/50] ppc/xive2: Consolidate presentation processing in context push Nicholas Piggin
2025-05-15 15:25   ` Mike Kowal
2025-05-15 16:06   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 38/50] ppc/xive2: Avoid needless interrupt re-check on CPPR set Nicholas Piggin
2025-05-15 15:26   ` Mike Kowal
2025-05-15 16:07   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 39/50] ppc/xive: Assert group interrupts were redistributed Nicholas Piggin
2025-05-15 15:28   ` Mike Kowal
2025-05-15 16:08   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 40/50] ppc/xive2: implement NVP context save restore for POOL ring Nicholas Piggin
2025-05-15 15:36   ` Mike Kowal
2025-05-15 16:09   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 41/50] ppc/xive2: Prevent pulling of pool context losing phys interrupt Nicholas Piggin
2025-05-15 15:43   ` Mike Kowal
2025-05-15 16:10   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 42/50] ppc/xive: Redistribute phys after pulling of pool context Nicholas Piggin
2025-05-15 15:46   ` Mike Kowal
2025-05-15 16:11   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 43/50] ppc/xive: Check TIMA operations validity Nicholas Piggin
2025-05-15 15:47   ` Mike Kowal
2025-05-15 16:12   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 44/50] ppc/xive2: Implement pool context push TIMA op Nicholas Piggin
2025-05-15 15:48   ` Mike Kowal
2025-05-15 16:13   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 45/50] ppc/xive2: redistribute group interrupts on context push Nicholas Piggin
2025-05-15 15:44   ` Mike Kowal
2025-05-15 16:13   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 46/50] ppc/xive2: Implement set_os_pending TIMA op Nicholas Piggin
2025-05-15 15:49   ` Mike Kowal
2025-05-15 16:14   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 47/50] ppc/xive2: Implement POOL LGS push " Nicholas Piggin
2025-05-15 15:50   ` Mike Kowal
2025-05-15 16:15   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 48/50] ppc/xive2: Implement PHYS ring VP " Nicholas Piggin
2025-05-15 15:50   ` Mike Kowal
2025-05-15 16:16   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 49/50] ppc/xive: Split need_resend into restore_nvp Nicholas Piggin
2025-05-15 15:57   ` Mike Kowal
2025-05-15 16:16   ` Miles Glenn
2025-05-12  3:10 ` [PATCH 50/50] ppc/xive2: Enable lower level contexts on VP push Nicholas Piggin
2025-05-15 15:54   ` Mike Kowal
2025-05-15 16:17   ` Miles Glenn
2025-05-15 15:36 ` [PATCH 00/50] ppc/xive: updates for PowerVM Cédric Le Goater
2025-05-16  1:29   ` Nicholas Piggin
2025-07-20 21:26     ` Cédric Le Goater
2025-08-04 17:37       ` Miles Glenn
2025-08-05  5:09         ` Cédric Le Goater
2025-08-05 15:52           ` Miles Glenn
2025-08-05 20:09             ` Cédric Le Goater
2025-07-03  9:37 ` Gautam Menghani

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=20250512031100.439842-23-npiggin@gmail.com \
    --to=npiggin@gmail.com \
    --cc=calebs@linux.vnet.ibm.com \
    --cc=fbarrat@linux.ibm.com \
    --cc=kowal@linux.ibm.com \
    --cc=milesg@linux.ibm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.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).