linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Ram Pai <linuxram@us.ibm.com>
To: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org,
	linux-arch@vger.kernel.org, linux-mm@kvack.org, x86@kernel.org,
	linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org
Cc: benh@kernel.crashing.org, paulus@samba.org, mpe@ellerman.id.au,
	khandual@linux.vnet.ibm.com, aneesh.kumar@linux.vnet.ibm.com,
	bsingharora@gmail.com, dave.hansen@intel.com, hbabu@us.ibm.com,
	linuxram@us.ibm.com, arnd@arndb.de, akpm@linux-foundation.org,
	corbet@lwn.net, mingo@redhat.com, mhocko@kernel.org
Subject: [RFC v6 52/62] selftest/vm: generic cleanup
Date: Sat, 15 Jul 2017 20:56:54 -0700	[thread overview]
Message-ID: <1500177424-13695-53-git-send-email-linuxram@us.ibm.com> (raw)
In-Reply-To: <1500177424-13695-1-git-send-email-linuxram@us.ibm.com>

cleanup the code to satisfy coding styles.

Signed-off-by: Ram Pai <linuxram@us.ibm.com>
---
 tools/testing/selftests/vm/protection_keys.c |   81 ++++++++++++++------------
 1 files changed, 43 insertions(+), 38 deletions(-)

diff --git a/tools/testing/selftests/vm/protection_keys.c b/tools/testing/selftests/vm/protection_keys.c
index f21e177..fd94449 100644
--- a/tools/testing/selftests/vm/protection_keys.c
+++ b/tools/testing/selftests/vm/protection_keys.c
@@ -3,7 +3,7 @@
  *
  * There are examples in here of:
  *  * how to set protection keys on memory
- *  * how to set/clear bits in pkey registers (the rights register)
+ *  * how to set/clear bits in Protection Key registers (the rights register)
  *  * how to handle SEGV_PKUERR signals and extract pkey-relevant
  *    information from the siginfo
  *
@@ -12,13 +12,18 @@
  *	prefault pages in at malloc, or not
  *	protect MPX bounds tables with protection keys?
  *	make sure VMA splitting/merging is working correctly
- *	OOMs can destroy mm->mmap (see exit_mmap()), so make sure it is immune to pkeys
- *	look for pkey "leaks" where it is still set on a VMA but "freed" back to the kernel
- *	do a plain mprotect() to a mprotect_pkey() area and make sure the pkey sticks
+ *	OOMs can destroy mm->mmap (see exit_mmap()),
+ *			so make sure it is immune to pkeys
+ *	look for pkey "leaks" where it is still set on a VMA
+ *			 but "freed" back to the kernel
+ *	do a plain mprotect() to a mprotect_pkey() area and make
+ *			 sure the pkey sticks
  *
  * Compile like this:
- *	gcc      -o protection_keys    -O2 -g -std=gnu99 -pthread -Wall protection_keys.c -lrt -ldl -lm
- *	gcc -m32 -o protection_keys_32 -O2 -g -std=gnu99 -pthread -Wall protection_keys.c -lrt -ldl -lm
+ *	gcc      -o protection_keys    -O2 -g -std=gnu99
+ *			 -pthread -Wall protection_keys.c -lrt -ldl -lm
+ *	gcc -m32 -o protection_keys_32 -O2 -g -std=gnu99
+ *			 -pthread -Wall protection_keys.c -lrt -ldl -lm
  */
 #define _GNU_SOURCE
 #include <errno.h>
@@ -251,26 +256,11 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext)
 	dprintf1("signal pkey_reg from  pkey_reg: %016lx\n", __rdpkey_reg());
 	dprintf1("si_pkey from siginfo: %jx\n", si_pkey);
 	*(u64 *)pkey_reg_ptr = 0x00000000;
-	dprintf1("WARNING: set PRKU=0 to allow faulting instruction to continue\n");
+	dprintf1("WARNING: set PKEY_REG=0 to allow faulting instruction "
+			"to continue\n");
 	pkey_faults++;
 	dprintf1("<<<<==================================================\n");
 	return;
-	if (trapno == 14) {
-		fprintf(stderr,
-			"ERROR: In signal handler, page fault, trapno = %d, ip = %016lx\n",
-			trapno, ip);
-		fprintf(stderr, "si_addr %p\n", si->si_addr);
-		fprintf(stderr, "REG_ERR: %lx\n",
-				(unsigned long)uctxt->uc_mcontext.gregs[REG_ERR]);
-		exit(1);
-	} else {
-		fprintf(stderr, "unexpected trap %d! at 0x%lx\n", trapno, ip);
-		fprintf(stderr, "si_addr %p\n", si->si_addr);
-		fprintf(stderr, "REG_ERR: %lx\n",
-				(unsigned long)uctxt->uc_mcontext.gregs[REG_ERR]);
-		exit(2);
-	}
-	dprint_in_signal = 0;
 }
 
 int wait_all_children(void)
@@ -415,7 +405,7 @@ void pkey_disable_set(int pkey, int flags)
 {
 	unsigned long syscall_flags = 0;
 	int ret;
-	int pkey_rights;
+	u32 pkey_rights;
 	pkey_reg_t orig_pkey_reg = rdpkey_reg();
 
 	dprintf1("START->%s(%d, 0x%x)\n", __func__,
@@ -453,7 +443,7 @@ void pkey_disable_clear(int pkey, int flags)
 {
 	unsigned long syscall_flags = 0;
 	int ret;
-	int pkey_rights = pkey_get(pkey, syscall_flags);
+	u32 pkey_rights = pkey_get(pkey, syscall_flags);
 	pkey_reg_t orig_pkey_reg = rdpkey_reg();
 
 	pkey_assert(flags & (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE));
@@ -516,9 +506,10 @@ int sys_mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot,
 	return sret;
 }
 
-int sys_pkey_alloc(unsigned long flags, unsigned long init_val)
+int sys_pkey_alloc(unsigned long flags, u64 init_val)
 {
 	int ret = syscall(SYS_pkey_alloc, flags, init_val);
+
 	dprintf1("%s(flags=%lx, init_val=%lx) syscall ret: %d errno: %d\n",
 			__func__, flags, init_val, ret, errno);
 	return ret;
@@ -542,7 +533,7 @@ void pkey_set_shadow(u32 key, u64 init_val)
 int alloc_pkey(void)
 {
 	int ret;
-	unsigned long init_val = 0x0;
+	u64 init_val = 0x0;
 
 	dprintf1("%s()::%d, pkey_reg: 0x%016lx shadow: %016lx\n", __func__,
 			__LINE__, __rdpkey_reg(), shadow_pkey_reg);
@@ -692,7 +683,9 @@ void record_pkey_malloc(void *ptr, long size)
 		/* every record is full */
 		size_t old_nr_records = nr_pkey_malloc_records;
 		size_t new_nr_records = (nr_pkey_malloc_records * 2 + 1);
-		size_t new_size = new_nr_records * sizeof(struct pkey_malloc_record);
+		size_t new_size = new_nr_records *
+				sizeof(struct pkey_malloc_record);
+
 		dprintf2("new_nr_records: %zd\n", new_nr_records);
 		dprintf2("new_size: %zd\n", new_size);
 		pkey_malloc_records = realloc(pkey_malloc_records, new_size);
@@ -716,9 +709,11 @@ void free_pkey_malloc(void *ptr)
 {
 	long i;
 	int ret;
+
 	dprintf3("%s(%p)\n", __func__, ptr);
 	for (i = 0; i < nr_pkey_malloc_records; i++) {
 		struct pkey_malloc_record *rec = &pkey_malloc_records[i];
+
 		dprintf4("looking for ptr %p at record[%ld/%p]: {%p, %ld}\n",
 				ptr, i, rec, rec->ptr, rec->size);
 		if ((ptr <  rec->ptr) ||
@@ -799,11 +794,13 @@ void setup_hugetlbfs(void)
 	char buf[] = "123";
 
 	if (geteuid() != 0) {
-		fprintf(stderr, "WARNING: not run as root, can not do hugetlb test\n");
+		fprintf(stderr,
+			"WARNING: not run as root, can not do hugetlb test\n");
 		return;
 	}
 
-	cat_into_file(__stringify(GET_NR_HUGE_PAGES), "/proc/sys/vm/nr_hugepages");
+	cat_into_file(__stringify(GET_NR_HUGE_PAGES),
+				"/proc/sys/vm/nr_hugepages");
 
 	/*
 	 * Now go make sure that we got the pages and that they
@@ -824,7 +821,8 @@ void setup_hugetlbfs(void)
 	}
 
 	if (atoi(buf) != GET_NR_HUGE_PAGES) {
-		fprintf(stderr, "could not confirm 2M pages, got: '%s' expected %d\n",
+		fprintf(stderr, "could not confirm 2M pages, got:"
+			       " '%s' expected %d\n",
 			buf, GET_NR_HUGE_PAGES);
 		return;
 	}
@@ -957,6 +955,7 @@ void __save_test_fd(int fd)
 int get_test_read_fd(void)
 {
 	int test_fd = open("/etc/passwd", O_RDONLY);
+
 	__save_test_fd(test_fd);
 	return test_fd;
 }
@@ -998,7 +997,8 @@ void test_read_of_access_disabled_region(int *ptr, u16 pkey)
 {
 	int ptr_contents;
 
-	dprintf1("disabling access to PKEY[%02d], doing read @ %p\n", pkey, ptr);
+	dprintf1("disabling access to PKEY[%02d], doing read @ %p\n",
+			 pkey, ptr);
 	rdpkey_reg();
 	pkey_access_deny(pkey);
 	ptr_contents = read_ptr(ptr);
@@ -1120,13 +1120,14 @@ void test_pkey_syscalls_bad_args(int *ptr, u16 pkey)
 /* Assumes that all pkeys other than 'pkey' are unallocated */
 void test_pkey_alloc_exhaust(int *ptr, u16 pkey)
 {
-	int err;
+	int err = 0;
 	int allocated_pkeys[NR_PKEYS] = {0};
 	int nr_allocated_pkeys = 0;
 	int i;
 
 	for (i = 0; i < NR_PKEYS*2; i++) {
 		int new_pkey;
+
 		dprintf1("%s() alloc loop: %d\n", __func__, i);
 		new_pkey = alloc_pkey();
 		dprintf4("%s()::%d, err: %d pkey_reg: 0x%016lx "
@@ -1134,9 +1135,11 @@ void test_pkey_alloc_exhaust(int *ptr, u16 pkey)
 			__func__, __LINE__, err, __rdpkey_reg(),
 			shadow_pkey_reg);
 		rdpkey_reg(); /* for shadow checking */
-		dprintf2("%s() errno: %d ENOSPC: %d\n", __func__, errno, ENOSPC);
+		dprintf2("%s() errno: %d ENOSPC: %d\n",
+				__func__, errno, ENOSPC);
 		if ((new_pkey == -1) && (errno == ENOSPC)) {
-			dprintf2("%s() failed to allocate pkey after %d tries\n",
+			dprintf2("%s() failed to allocate pkey "
+					"after %d tries\n",
 				__func__, nr_allocated_pkeys);
 			break;
 		}
@@ -1338,7 +1341,8 @@ void run_tests_once(void)
 		tracing_off();
 		close_test_fds();
 
-		printf("test %2d PASSED (iteration %d)\n", test_nr, iteration_nr);
+		printf("test %2d PASSED (iteration %d)\n",
+				test_nr, iteration_nr);
 		dprintf1("======================\n\n");
 	}
 	iteration_nr++;
@@ -1350,7 +1354,7 @@ int main(void)
 
 	setup_handlers();
 
-	printf("has pku: %d\n", cpu_has_pku());
+	printf("has pkey: %d\n", cpu_has_pku());
 
 	if (!cpu_has_pku()) {
 		int size = PAGE_SIZE;
@@ -1358,7 +1362,8 @@ int main(void)
 
 		printf("running PKEY tests for unsupported CPU/OS\n");
 
-		ptr  = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+		ptr  = mmap(NULL, size, PROT_NONE,
+				MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
 		assert(ptr != (void *)-1);
 		test_mprotect_pkey_on_unsupported_cpu(ptr, 1);
 		exit(0);
-- 
1.7.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  parent reply	other threads:[~2017-07-16  4:00 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-16  3:56 [RFC v6 00/62] powerpc: Memory Protection Keys Ram Pai
2017-07-16  3:56 ` [RFC v6 01/62] powerpc: Free up four 64K PTE bits in 4K backed HPTE pages Ram Pai
2017-07-20  5:51   ` Aneesh Kumar K.V
2017-07-20 22:03     ` Ram Pai
2017-07-16  3:56 ` [RFC v6 02/62] powerpc: Free up four 64K PTE bits in 64K " Ram Pai
2017-07-20  5:53   ` Aneesh Kumar K.V
2017-07-16  3:56 ` [RFC v6 03/62] powerpc: introduce pte_set_hash_slot() helper Ram Pai
2017-07-20  5:56   ` Aneesh Kumar K.V
2017-07-16  3:56 ` [RFC v6 04/62] powerpc: introduce pte_get_hash_gslot() helper Ram Pai
2017-07-20  5:57   ` Aneesh Kumar K.V
2017-07-16  3:56 ` [RFC v6 05/62] powerpc: capture the PTE format changes in the dump pte report Ram Pai
2017-07-20  5:56   ` Aneesh Kumar K.V
2017-07-16  3:56 ` [RFC v6 06/62] powerpc: use helper functions in __hash_page_64K() for 64K PTE Ram Pai
2017-07-20  5:58   ` Aneesh Kumar K.V
2017-07-16  3:56 ` [RFC v6 07/62] powerpc: use helper functions in __hash_page_huge() " Ram Pai
2017-07-20  5:58   ` Aneesh Kumar K.V
2017-07-16  3:56 ` [RFC v6 08/62] powerpc: use helper functions in __hash_page_4K() " Ram Pai
2017-07-16  3:56 ` [RFC v6 09/62] powerpc: use helper functions in __hash_page_4K() for 4K PTE Ram Pai
2017-07-16  3:56 ` [RFC v6 10/62] powerpc: use helper functions in flush_hash_page() Ram Pai
2017-07-16  3:56 ` [RFC v6 11/62] powerpc: initial pkey plumbing Ram Pai
2017-07-20  6:04   ` Aneesh Kumar K.V
2017-07-20 22:11     ` Ram Pai
2017-07-16  3:56 ` [RFC v6 12/62] mm: introduce an additional vma bit for powerpc pkey Ram Pai
2017-07-16  3:56 ` [RFC v6 13/62] powerpc: track allocation status of all pkeys Ram Pai
2017-07-27 14:01   ` Thiago Jung Bauermann
2017-07-29 22:43     ` Ram Pai
2017-07-31 18:15   ` Thiago Jung Bauermann
2017-07-16  3:56 ` [RFC v6 14/62] powerpc: helper function to read,write AMR,IAMR,UAMOR registers Ram Pai
2017-07-16  3:56 ` [RFC v6 15/62] powerpc: helper functions to initialize AMR, IAMR and UMOR registers Ram Pai
2017-07-27 20:40   ` Thiago Jung Bauermann
2017-07-30  0:38     ` Ram Pai
2017-07-16  3:56 ` [RFC v6 16/62] powerpc: cleaup AMR,iAMR when a key is allocated or freed Ram Pai
2017-07-16  3:56 ` [RFC v6 17/62] powerpc: implementation for arch_set_user_pkey_access() Ram Pai
2017-07-27 14:15   ` Thiago Jung Bauermann
2017-07-29 22:59     ` Ram Pai
2017-07-16  3:56 ` [RFC v6 18/62] powerpc: sys_pkey_alloc() and sys_pkey_free() system calls Ram Pai
2017-07-16  3:56 ` [RFC v6 19/62] powerpc: ability to create execute-disabled pkeys Ram Pai
2017-07-27 14:54   ` Thiago Jung Bauermann
2017-07-27 15:34     ` Thiago Jung Bauermann
2017-07-29 23:24     ` Ram Pai
2017-07-31 12:59       ` Michael Ellerman
2017-07-16  3:56 ` [RFC v6 20/62] powerpc: store and restore the pkey state across context switches Ram Pai
2017-07-27 17:32   ` Thiago Jung Bauermann
2017-07-29 23:31     ` Ram Pai
2017-07-31 13:00       ` Michael Ellerman
2017-07-16  3:56 ` [RFC v6 21/62] powerpc: introduce execute-only pkey Ram Pai
2017-07-28 22:17   ` Thiago Jung Bauermann
2017-07-30  0:51     ` Ram Pai
2017-07-31 16:19       ` Thiago Jung Bauermann
2017-08-01  6:46     ` Michael Ellerman
2017-08-01 16:14       ` Thiago Jung Bauermann
2017-08-02  9:40         ` Michael Ellerman
     [not found]           ` <20170817233555.GC5427@ram.oc3035372033.ibm.com>
2017-08-17 23:42             ` Ram Pai
2017-07-16  3:56 ` [RFC v6 22/62] powerpc: ability to associate pkey to a vma Ram Pai
2017-07-16  3:56 ` [RFC v6 23/62] powerpc: implementation for arch_override_mprotect_pkey() Ram Pai
2017-07-16  3:56 ` [RFC v6 24/62] powerpc: map vma key-protection bits to pte key bits Ram Pai
2017-07-16  3:56 ` [RFC v6 25/62] powerpc: sys_pkey_mprotect() system call Ram Pai
2017-07-16  3:56 ` [RFC v6 26/62] powerpc: Program HPTE key protection bits Ram Pai
2017-07-20  6:28   ` Aneesh Kumar K.V
2017-07-16  3:56 ` [RFC v6 27/62] powerpc: helper to validate key-access permissions of a pte Ram Pai
2017-07-20  6:42   ` Aneesh Kumar K.V
2017-07-20 22:15     ` Ram Pai
2017-07-21  6:51       ` Aneesh Kumar K.V
2017-07-21 16:42         ` Ram Pai
2017-07-28 21:00   ` Thiago Jung Bauermann
2017-07-30  0:39     ` Ram Pai
2017-07-16  3:56 ` [RFC v6 28/62] powerpc: check key protection for user page access Ram Pai
2017-07-16  3:56 ` [RFC v6 29/62] powerpc: Macro the mask used for checking DSI exception Ram Pai
2017-07-16  3:56 ` [RFC v6 30/62] powerpc: implementation for arch_vma_access_permitted() Ram Pai
2017-07-16  3:56 ` [RFC v6 31/62] powerpc: Handle exceptions caused by pkey violation Ram Pai
2017-07-16  3:56 ` [RFC v6 32/62] powerpc: capture AMR register content on " Ram Pai
2017-07-16  3:56 ` [RFC v6 33/62] powerpc: introduce get_pte_pkey() helper Ram Pai
2017-07-16  3:56 ` [RFC v6 34/62] powerpc: capture the violated protection key on fault Ram Pai
2017-07-16  3:56 ` [RFC v6 35/62] powerpc: Deliver SEGV signal on pkey violation Ram Pai
2017-08-19 19:09   ` Eric W. Biederman
2017-08-22 18:06     ` Ram Pai
2017-07-16  3:56 ` [RFC v6 36/62] mm: introduce arch_pkeys_enabled() Ram Pai
2017-07-16  3:56 ` [RFC v6 37/62] x86: implementation for arch_pkeys_enabled() Ram Pai
2017-07-16  3:56 ` [RFC v6 38/62] powerpc: " Ram Pai
2017-07-16  3:56 ` [RFC v6 39/62] mm: display pkey in smaps if arch_pkeys_enabled() is true Ram Pai
2017-07-16  3:56 ` [RFC v6 40/62] x86: delete arch_show_smap() Ram Pai
2017-07-16  3:56 ` [RFC v6 41/62] selftest/x86: Move protecton key selftest to arch neutral directory Ram Pai
2017-07-16  3:56 ` [RFC v6 42/62] selftest/vm: rename all references to pkru to a generic name Ram Pai
2017-07-16  3:56 ` [RFC v6 43/62] selftest/vm: move generic definitions to header file Ram Pai
2017-07-16  3:56 ` [RFC v6 44/62] selftest/vm: typecast the pkey register Ram Pai
2017-07-16  3:56 ` [RFC v6 45/62] selftest/vm: generics function to handle shadow key register Ram Pai
2017-07-16  3:56 ` [RFC v6 46/62] selftest/vm: fix the wrong assert in pkey_disable_set() Ram Pai
2017-07-16  3:56 ` [RFC v6 47/62] selftest/vm: fixed bugs in pkey_disable_clear() Ram Pai
2017-07-16  3:56 ` [RFC v6 48/62] selftest/vm: clear the bits in shadow reg when a pkey is freed Ram Pai
2017-07-16  3:56 ` [RFC v6 49/62] selftest/vm: fix alloc_random_pkey() to make it really random Ram Pai
2017-07-16  3:56 ` [RFC v6 50/62] selftest/vm: introduce two arch independent abstraction Ram Pai
2017-07-16  3:56 ` [RFC v6 51/62] selftest/vm: pkey register should match shadow pkey Ram Pai
2017-07-16  3:56 ` Ram Pai [this message]
2017-07-16  3:56 ` [RFC v6 53/62] selftest/vm: powerpc implementation for generic abstraction Ram Pai
2017-07-16  3:56 ` [RFC v6 54/62] selftest/vm: fix an assertion in test_pkey_alloc_exhaust() Ram Pai
2017-07-16  3:56 ` [RFC v6 55/62] selftest/vm: associate key on a mapped page and detect access violation Ram Pai
2017-07-16  3:56 ` [RFC v6 56/62] selftest/vm: detect no key violation on a freed key Ram Pai
2017-07-16  3:56 ` [RFC v6 57/62] selftest/vm: associate key on a mapped page and detect write violation Ram Pai
2017-07-16  3:57 ` [RFC v6 58/62] selftest/vm: detect no write key-violation on a freed key Ram Pai
2017-07-16  3:57 ` [RFC v6 59/62] selftest/vm: detect write violation on a mapped access-denied-key page Ram Pai
2017-07-16  3:57 ` [RFC v6 60/62] selftest/vm: sub-page allocator Ram Pai
2017-07-16  3:57 ` [RFC v6 61/62] Documentation/x86: Move protecton key documentation to arch neutral directory Ram Pai
2017-07-16  3:57 ` [RFC v6 62/62] Documentation/vm: PowerPC specific updates to memory protection keys Ram Pai

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=1500177424-13695-53-git-send-email-linuxram@us.ibm.com \
    --to=linuxram@us.ibm.com \
    --cc=akpm@linux-foundation.org \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=arnd@arndb.de \
    --cc=benh@kernel.crashing.org \
    --cc=bsingharora@gmail.com \
    --cc=corbet@lwn.net \
    --cc=dave.hansen@intel.com \
    --cc=hbabu@us.ibm.com \
    --cc=khandual@linux.vnet.ibm.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mhocko@kernel.org \
    --cc=mingo@redhat.com \
    --cc=mpe@ellerman.id.au \
    --cc=paulus@samba.org \
    --cc=x86@kernel.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).