From: Yan Zhao <yan.y.zhao@intel.com>
To: Sean Christopherson <seanjc@google.com>
Cc: Rick P Edgecombe <rick.p.edgecombe@intel.com>,
"pbonzini@redhat.com" <pbonzini@redhat.com>,
Yuan Yao <yuan.yao@intel.com>, Kai Huang <kai.huang@intel.com>,
"isaku.yamahata@gmail.com" <isaku.yamahata@gmail.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"kvm@vger.kernel.org" <kvm@vger.kernel.org>,
"dmatlack@google.com" <dmatlack@google.com>,
"nik.borisov@suse.com" <nik.borisov@suse.com>
Subject: Re: [PATCH 09/21] KVM: TDX: Retry seamcall when TDX_OPERAND_BUSY with operand SEPT
Date: Fri, 13 Sep 2024 16:36:08 +0800 [thread overview]
Message-ID: <ZuP5eNXFCljzRgWo@yzhao56-desk.sh.intel.com> (raw)
In-Reply-To: <ZuCE_KtmXNi0qePb@google.com>
This is a lock status report of TDX module for current SEAMCALL retry issue
based on code in TDX module public repo https://github.com/intel/tdx-module.git
branch TDX_1.5.05.
TL;DR:
- tdh_mem_track() can contend with tdh_vp_enter().
- tdh_vp_enter() contends with tdh_mem*() when 0-stepping is suspected.
- tdg_mem_page_accept() can contend with other tdh_mem*().
Proposal:
- Return -EAGAIN directly in ops link_external_spt/set_external_spte when
tdh_mem_sept_add()/tdh_mem_page_aug() returns BUSY.
- Kick off vCPUs at the beginning of page removal path, i.e. before the
tdh_mem_range_block().
Set a flag and disallow tdh_vp_enter() until tdh_mem_page_remove() is done.
(one possible optimization:
since contention from tdh_vp_enter()/tdg_mem_page_accept should be rare,
do not kick off vCPUs in normal conditions.
When SEAMCALL BUSY happens, retry for once, kick off vCPUs and do not allow
TD enter until page removal completes.)
Below are detailed analysis:
=== Background ===
In TDX module, there are 4 kinds of locks:
1. sharex_lock:
Normal read/write lock. (no host priority stuff)
2. sharex_hp_lock:
Just like normal read/write lock, except that host can set host priority bit
on failure.
when guest tries to acquire the lock and sees host priority bit set, it will
return "busy host priority" directly, letting host win.
After host acquires the lock successfully, host priority bit is cleared.
3. sept entry lock:
Lock utilizing software bits in SEPT entry.
HP bit (Host priority): bit 52
EL bit (Entry lock): bit 11, used as a bit lock.
- host sets HP bit when host fails to acquire EL bit lock;
- host resets HP bit when host wins.
- guest returns "busy host priority" if HP bit is found set when guest tries
to acquire EL bit lock.
4. mutex lock:
Lock with only 2 states: free, lock.
(not the same as linux mutex, not re-scheduled, could pause() for debugging).
===Resources & users list===
Resources SHARED users EXCLUSIVE users
------------------------------------------------------------------------
(1) TDR tdh_mng_rdwr tdh_mng_create
tdh_vp_create tdh_mng_add_cx
tdh_vp_addcx tdh_mng_init
tdh_vp_init tdh_mng_vpflushdone
tdh_vp_enter tdh_mng_key_config
tdh_vp_flush tdh_mng_key_freeid
tdh_vp_rd_wr tdh_mr_extend
tdh_mem_sept_add tdh_mr_finalize
tdh_mem_sept_remove tdh_vp_init_apicid
tdh_mem_page_aug tdh_mem_page_add
tdh_mem_page_remove
tdh_mem_range_block
tdh_mem_track
tdh_mem_range_unblock
tdh_phymem_page_reclaim
------------------------------------------------------------------------
(2) KOT tdh_phymem_cache_wb tdh_mng_create
tdh_mng_vpflushdone
tdh_mng_key_freeid
------------------------------------------------------------------------
(3) TDCS tdh_mng_rdwr
tdh_vp_create
tdh_vp_addcx
tdh_vp_init
tdh_vp_init_apicid
tdh_vp_enter
tdh_vp_rd_wr
tdh_mem_sept_add
tdh_mem_sept_remove
tdh_mem_page_aug
tdh_mem_page_remove
tdh_mem_range_block
tdh_mem_track
tdh_mem_range_unblock
------------------------------------------------------------------------
(4) TDVPR tdh_vp_rd_wr tdh_vp_create
tdh_vp_addcx
tdh_vp_init
tdh_vp_init_apicid
tdh_vp_enter
tdh_vp_flush
------------------------------------------------------------------------
(5) TDCS epoch tdh_vp_enter tdh_mem_track
------------------------------------------------------------------------
(6) secure_ept_lock tdh_mem_sept_add tdh_vp_enter
tdh_mem_page_aug tdh_mem_sept_remove
tdh_mem_page_remove tdh_mem_range_block
tdh_mem_range_unblock
------------------------------------------------------------------------
(7) SEPT entry tdh_mem_sept_add
tdh_mem_sept_remove
tdh_mem_page_aug
tdh_mem_page_remove
tdh_mem_range_block
tdh_mem_range_unblock
tdg_mem_page_accept
Current KVM interested SEAMCALLs:
------------------------------------------------------------------------
SEAMCALL Lock Name Lock Type Resource
tdh_mng_create sharex_hp_lock EXCLUSIVE TDR
sharex_lock EXCLUSIVE KOT
tdh_mng_add_cx sharex_hp_lock EXCLUSIVE TDR
sharex_hp_lock EXCLUSIVE page to add
tdh_mng_init sharex_hp_lock EXCLUSIVE TDR
sharex_hp_lock NO_LOCK TDCS
tdh_mng_vpflushdone sharex_hp_lock EXCLUSIVE TDR
sharex_lock EXCLUSIVE KOT
tdh_mng_key_config sharex_hp_lock EXCLUSIVE TDR
tdh_mng_key_freeid sharex_hp_lock EXCLUSIVE TDR
sharex_lock EXCLUSIVE KOT
tdh_mng_rdwr sharex_hp_lock SHARED TDR
sharex_hp_lock SHARED TDCS
tdh_mr_extend sharex_hp_lock EXCLUSIVE TDR
sharex_hp_lock NO_LOCK TDCS
tdh_mr_finalize sharex_hp_lock EXCLUSIVE TDR
sharex_hp_lock NO_LOCK TDCS
tdh_vp_create sharex_hp_lock SHARED TDR
sharex_hp_lock SHARED TDCS
sharex_hp_lock EXCLUSIVE TDVPR
tdh_vp_addcx sharex_hp_lock EXCLUSIVE TDVPR
sharex_hp_lock SHARED TDR
sharex_hp_lock SHARED TDCS
sharex_hp_lock EXCLUSIVE page to add
tdh_vp_init sharex_hp_lock EXCLUSIVE TDVPR
sharex_hp_lock SHARED TDR
sharex_hp_lock SHARED TDCS
tdh_vp_init_apicid sharex_hp_lock EXCLUSIVE TDVPR
sharex_hp_lock EXCLUSIVE TDR
sharex_hp_lock SHARED TDCS
tdh_vp_enter(*) sharex_hp_lock EXCLUSIVE TDVPR
sharex_hp_lock SHARED TDR
sharex_hp_lock SHARED TDCS
sharex_lock SHARED TDCS epoch_lock
sharex_lock EXCLUSIVE TDCS secure_ept_lock
tdh_vp_flush sharex_hp_lock EXCLUSIVE TDVPR
sharex_hp_lock SHARED TDR
tdh_vp_rd_wr sharex_hp_lock SHARED TDVPR
sharex_hp_lock SHARED TDR
sharex_hp_lock SHARED TDCS
tdh_mem_sept_add sharex_hp_lock SHARED TDR
sharex_hp_lock SHARED TDCS
sharex_lock SHARED TDCS secure_ept_lock
sept entry lock HOST,EXCLUSIVE SEPT entry to modify
sharex_hp_lock EXCLUSIVE page to add
tdh_mem_sept_remove sharex_hp_lock SHARED TDR
sharex_hp_lock SHARED TDCS
sharex_lock EXCLUSIVE TDCS secure_ept_lock
sept entry lock HOST,EXCLUSIVE SEPT entry to modify
sharex_hp_lock EXCLUSIVE page to remove
tdh_mem_page_add sharex_hp_lock EXCLUSIVE TDR
sharex_hp_lock NO_LOCK TDCS
sharex_lock NO_LOCK TDCS secure_ept_lock
sharex_hp_lock EXCLUSIVE page to add
tdh_mem_page_aug sharex_hp_lock SHARED TDR
sharex_hp_lock SHARED TDCS
sharex_lock SHARED TDCS secure_ept_lock
sept entry lock HOST,EXCLUSIVE SEPT entry to modify
sharex_hp_lock EXCLUSIVE page to aug
tdh_mem_page_remove sharex_hp_lock SHARED TDR
sharex_hp_lock SHARED TDCS
sharex_lock SHARED TDCS secure_ept_lock
sept entry lock HOST,EXCLUSIVE SEPT entry to modify
sharex_hp_lock EXCLUSIVE page to remove
tdh_mem_range_block sharex_hp_lock SHARED TDR
sharex_hp_lock SHARED TDCS
sharex_lock EXCLUSIVE TDCS secure_ept_lock
sept entry lock HOST,EXCLUSIVE SEPT entry to modify
tdh_mem_track sharex_hp_lock SHARED TDR
sharex_hp_lock SHARED TDCS
sharex_lock EXCLUSIVE TDCS epoch_lock
tdh_mem_range_unblock sharex_hp_lock SHARED TDR
sharex_hp_lock SHARED TDCS
sharex_lock EXCLUSIVE TDCS secure_ept_lock
sept entry lock HOST,EXCLUSIVE SEPT entry to modify
tdh_phymem_page_reclaim sharex_hp_lock EXCLUSIVE page to reclaim
sharex_hp_lock SHARED TDR
tdh_phymem_cache_wb mutex_lock per package wbt_entries
sharex_lock SHARED KOT
tdh_phymem_page_wbinvd sharex_hp_lock SHARED page to be wbinvd
Current KVM interested TDCALLs:
------------------------------------------------------------------------
tdg_mem_page_accept sept entry lock GUEST SEPT entry to modify
TDCALLs like tdg_mr_rtmr_extend(), tdg_servtd_rd_wr(), tdg_mem_page_attr_wr()
tdg_mem_page_attr_rd() are not included.
*:(a) tdh_vp_enter() holds shared TDR lock and exclusive TDVPR lock, the two
locks are released when exiting to VMM.
(b) tdh_vp_enter() holds shared TDCS lock and shared TDCS epoch_lock lock,
releases them before entering non-root mode.
(c) tdh_vp_enter() holds shared epoch lock, contending with tdh_mem_track().
(d) tdh_vp_enter() only holds EXCLUSIVE secure_ept_lock when 0-stepping is
suspected, i.e. when last_epf_gpa_list is not empty.
When a EPT violation happens, TDX module checks if the guest RIP equals
to the guest RIP of last TD entry. Only when this is true for 6 continuous
times, the gpa will be recorded in last_epf_gpa_list. The list will be
reset once guest RIP of a EPT violation and last TD enter RIP are unequal.
=== Summary ===
For the 8 kinds of common resources protected in TDX module:
(1) TDR:
There are only shared accesses to TDR during runtime (i.e. after TD is
finalized and before TD tearing down), if we don't need to support calling
tdh_vp_init_apicid() at runtime (e.g. for vCPU hotplug).
tdh_vp_enter() holds shared TDR lock until exiting to VMM.
TDCALLs do not acquire the TDR lock.
(2) KOT (Key Ownership Table)
Current KVM code should have avoided contention to this resource.
(3) TDCS:
Shared accessed or access with no lock when TDR is exclusively locked.
Seamcalls in runtime (after TD finalized and before TD tearing down) do not
contend with each other on TDCS.
tdh_vp_enter() holds shared TDCS lock and releases it before entering
non-root mode.
Current TDCALLs for basic TDX do not acquire this lock.
(4) TDVPR:
Per-vCPU exclusive accessed except for tdh_vp_rd_wr().
tdh_vp_enter() holds exclusive TDVPR lock until exiting to VMM.
TDCALLs do not acquire the TDVPR lock.
(5) TDCS epoch:
tdh_mem_track() requests exclusive access, and tdh_vp_enter() requests
shared access.
tdh_mem_track() can contend with tdh_vp_enter().
(6) SEPT tree:
Protected by secure_ept_lock (sharex_lock).
tdh_mem_sept_add()/tdh_mem_page_aug()/tdh_mem_page_remove() holds shared
lock; tdh_mem_sept_remove()/tdh_mem_range_block()/tdh_mem_range_unblock()
holds exclusive lock.
tdh_vp_enter() requests exclusive access when 0-stepping is suspected,
contending with all other tdh_mem*().
Guest does not acquire this lock.
So,
kvm mmu_lock has prevented contentions between
tdh_mem_sept_add()/tdh_mem_page_aug()/tdh_mem_page_remove() and
tdh_mem_sept_remove()/tdh_mem_range_block().
Though tdh_mem_sept_add()/tdh_mem_page_aug() races with tdh_vp_enter(),
returning -EAGAIN directly is fine for them.
The remaining issue is the contention between tdh_vp_enter() and
tdh_mem_page_remove()/tdh_mem_sept_remove()/tdh_mem_range_block().
(7) SEPT entry:
All exclusive access.
tdg_mem_page_accept() may contend with other tdh_mem*() on a specific SEPT
entry.
(8) PAMT entry for target pages (e.g. page to add/aug/remove/reclaim/wbinvd):
Though they are all exclusively locked, no race should be met as long as
they belong to different pamt entries.
Conclusion:
Current KVM code should have avoided contentions of resources (1)-(4),(8), while
(5),(6),(7) are still possible to meet contention.
- tdh_mem_track() can contend with tdh_vp_enter() for (5)
- tdh_vp_enter() contends with tdh_mem*() for (6) when 0-stepping is suspected.
- tdg_mem_page_accept() can contend with other tdh_mem*() for (7).
next prev parent reply other threads:[~2024-09-13 8:38 UTC|newest]
Thread overview: 139+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-04 3:07 [PATCH 00/21] TDX MMU Part 2 Rick Edgecombe
2024-09-04 3:07 ` [PATCH 01/21] KVM: x86/mmu: Implement memslot deletion for TDX Rick Edgecombe
2024-09-09 13:44 ` Paolo Bonzini
2024-09-09 21:06 ` Edgecombe, Rick P
2024-09-04 3:07 ` [PATCH 02/21] KVM: x86/tdp_mmu: Add a helper function to walk down the TDP MMU Rick Edgecombe
2024-09-09 13:51 ` Paolo Bonzini
2024-09-04 3:07 ` [PATCH 03/21] KVM: x86/mmu: Do not enable page track for TD guest Rick Edgecombe
2024-09-09 13:53 ` Paolo Bonzini
2024-09-09 21:07 ` Edgecombe, Rick P
2024-09-04 3:07 ` [PATCH 04/21] KVM: VMX: Split out guts of EPT violation to common/exposed function Rick Edgecombe
2024-09-09 13:57 ` Paolo Bonzini
2024-09-09 16:07 ` Sean Christopherson
2024-09-10 7:36 ` Paolo Bonzini
2024-09-04 3:07 ` [PATCH 05/21] KVM: VMX: Teach EPT violation helper about private mem Rick Edgecombe
2024-09-09 13:59 ` Paolo Bonzini
2024-09-11 8:52 ` Chao Gao
2024-09-11 16:29 ` Edgecombe, Rick P
2024-09-12 0:39 ` Huang, Kai
2024-09-12 13:58 ` Sean Christopherson
2024-09-12 14:43 ` Edgecombe, Rick P
2024-09-12 14:46 ` Paolo Bonzini
2024-09-12 1:19 ` Huang, Kai
2024-09-04 3:07 ` [PATCH 06/21] KVM: TDX: Add accessors VMX VMCS helpers Rick Edgecombe
2024-09-09 14:19 ` Paolo Bonzini
2024-09-09 21:29 ` Edgecombe, Rick P
2024-09-10 10:48 ` Paolo Bonzini
2024-09-04 3:07 ` [PATCH 07/21] KVM: TDX: Add load_mmu_pgd method for TDX Rick Edgecombe
2024-09-11 2:48 ` Chao Gao
2024-09-11 2:49 ` Edgecombe, Rick P
2024-09-04 3:07 ` [PATCH 08/21] KVM: TDX: Set gfn_direct_bits to shared bit Rick Edgecombe
2024-09-09 15:21 ` Paolo Bonzini
2024-09-04 3:07 ` [PATCH 09/21] KVM: TDX: Retry seamcall when TDX_OPERAND_BUSY with operand SEPT Rick Edgecombe
2024-09-06 1:41 ` Huang, Kai
2024-09-09 20:25 ` Edgecombe, Rick P
2024-09-09 15:25 ` Paolo Bonzini
2024-09-09 20:22 ` Edgecombe, Rick P
2024-09-09 21:11 ` Sean Christopherson
2024-09-09 21:23 ` Sean Christopherson
2024-09-09 22:34 ` Edgecombe, Rick P
2024-09-09 23:58 ` Sean Christopherson
2024-09-10 0:50 ` Edgecombe, Rick P
2024-09-10 1:46 ` Sean Christopherson
2024-09-11 1:17 ` Huang, Kai
2024-09-11 2:48 ` Edgecombe, Rick P
2024-09-11 22:55 ` Huang, Kai
2024-09-10 13:15 ` Paolo Bonzini
2024-09-10 13:57 ` Sean Christopherson
2024-09-10 15:16 ` Paolo Bonzini
2024-09-10 15:57 ` Sean Christopherson
2024-09-10 16:28 ` Edgecombe, Rick P
2024-09-10 17:42 ` Sean Christopherson
2024-09-13 8:36 ` Yan Zhao [this message]
2024-09-13 17:23 ` Sean Christopherson
2024-09-13 19:19 ` Edgecombe, Rick P
2024-09-13 22:18 ` Sean Christopherson
2024-09-14 9:27 ` Yan Zhao
2024-09-15 9:53 ` Yan Zhao
2024-09-17 1:31 ` Huang, Kai
2024-09-25 10:53 ` Yan Zhao
2024-10-08 14:51 ` Sean Christopherson
2024-10-10 5:23 ` Yan Zhao
2024-10-10 17:33 ` Sean Christopherson
2024-10-10 21:53 ` Edgecombe, Rick P
2024-10-11 2:30 ` Yan Zhao
2024-10-14 10:54 ` Huang, Kai
2024-10-14 17:36 ` Edgecombe, Rick P
2024-10-14 23:03 ` Huang, Kai
2024-10-15 1:24 ` Edgecombe, Rick P
2024-10-11 2:06 ` Yan Zhao
2024-10-16 14:13 ` Yan Zhao
2024-09-17 2:11 ` Huang, Kai
2024-09-13 19:19 ` Edgecombe, Rick P
2024-09-14 10:00 ` Yan Zhao
2024-09-04 3:07 ` [PATCH 10/21] KVM: TDX: Require TDP MMU and mmio caching for TDX Rick Edgecombe
2024-09-09 15:26 ` Paolo Bonzini
2024-09-12 0:15 ` Huang, Kai
2024-09-04 3:07 ` [PATCH 11/21] KVM: x86/mmu: Add setter for shadow_mmio_value Rick Edgecombe
2024-09-09 15:33 ` Paolo Bonzini
2024-09-04 3:07 ` [PATCH 12/21] KVM: TDX: Set per-VM shadow_mmio_value to 0 Rick Edgecombe
2024-09-09 15:33 ` Paolo Bonzini
2024-09-04 3:07 ` [PATCH 13/21] KVM: TDX: Handle TLB tracking for TDX Rick Edgecombe
2024-09-10 8:16 ` Paolo Bonzini
2024-09-10 23:49 ` Edgecombe, Rick P
2024-10-14 6:34 ` Yan Zhao
2024-09-11 6:25 ` Xu Yilun
2024-09-11 17:28 ` Edgecombe, Rick P
2024-09-12 4:54 ` Yan Zhao
2024-09-12 14:44 ` Edgecombe, Rick P
2024-09-12 7:47 ` Xu Yilun
2024-09-04 3:07 ` [PATCH 14/21] KVM: TDX: Implement hooks to propagate changes of TDP MMU mirror page table Rick Edgecombe
2024-09-06 2:10 ` Huang, Kai
2024-09-09 21:03 ` Edgecombe, Rick P
2024-09-10 1:52 ` Yan Zhao
2024-09-10 9:33 ` Paolo Bonzini
2024-09-10 23:58 ` Edgecombe, Rick P
2024-09-11 1:05 ` Yan Zhao
2024-10-30 3:03 ` Binbin Wu
2024-11-04 9:09 ` Yan Zhao
2024-09-04 3:07 ` [PATCH 15/21] KVM: TDX: Implement hook to get max mapping level of private pages Rick Edgecombe
2024-09-10 10:17 ` Paolo Bonzini
2024-09-04 3:07 ` [PATCH 16/21] KVM: TDX: Premap initial guest memory Rick Edgecombe
2024-09-10 10:24 ` Paolo Bonzini
2024-09-11 0:19 ` Edgecombe, Rick P
2024-09-13 13:33 ` Adrian Hunter
2024-09-13 19:49 ` Edgecombe, Rick P
2024-09-10 10:49 ` Paolo Bonzini
2024-09-11 0:30 ` Edgecombe, Rick P
2024-09-11 10:39 ` Paolo Bonzini
2024-09-11 16:36 ` Edgecombe, Rick P
2024-09-04 3:07 ` [PATCH 17/21] KVM: TDX: MTRR: implement get_mt_mask() for TDX Rick Edgecombe
2024-09-10 10:04 ` Paolo Bonzini
2024-09-10 14:05 ` Sean Christopherson
2024-09-04 3:07 ` [PATCH 18/21] KVM: x86/mmu: Export kvm_tdp_map_page() Rick Edgecombe
2024-09-10 10:02 ` Paolo Bonzini
2024-09-04 3:07 ` [PATCH 19/21] KVM: TDX: Add an ioctl to create initial guest memory Rick Edgecombe
2024-09-04 4:53 ` Yan Zhao
2024-09-04 14:01 ` Edgecombe, Rick P
2024-09-06 16:30 ` Edgecombe, Rick P
2024-09-09 1:29 ` Yan Zhao
2024-09-10 10:13 ` Paolo Bonzini
2024-09-11 0:11 ` Edgecombe, Rick P
2024-09-04 13:56 ` Edgecombe, Rick P
2024-09-10 10:16 ` Paolo Bonzini
2024-09-11 0:12 ` Edgecombe, Rick P
2024-09-04 3:07 ` [PATCH 20/21] KVM: TDX: Finalize VM initialization Rick Edgecombe
2024-09-04 15:37 ` Adrian Hunter
2024-09-04 16:09 ` Edgecombe, Rick P
2024-09-10 10:33 ` Paolo Bonzini
2024-09-10 11:15 ` Adrian Hunter
2024-09-10 11:28 ` Paolo Bonzini
2024-09-10 11:31 ` Adrian Hunter
2024-09-10 10:25 ` Paolo Bonzini
2024-09-10 11:54 ` Adrian Hunter
2024-09-04 3:07 ` [PATCH 21/21] KVM: TDX: Handle vCPU dissociation Rick Edgecombe
2024-09-09 15:41 ` Paolo Bonzini
2024-09-09 23:30 ` Edgecombe, Rick P
2024-09-10 10:45 ` Paolo Bonzini
2024-09-11 0:17 ` Edgecombe, Rick P
2024-11-04 9:45 ` Yan Zhao
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=ZuP5eNXFCljzRgWo@yzhao56-desk.sh.intel.com \
--to=yan.y.zhao@intel.com \
--cc=dmatlack@google.com \
--cc=isaku.yamahata@gmail.com \
--cc=kai.huang@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nik.borisov@suse.com \
--cc=pbonzini@redhat.com \
--cc=rick.p.edgecombe@intel.com \
--cc=seanjc@google.com \
--cc=yuan.yao@intel.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
all inboxes | Powered by JetHome®