Module Name:    src
Committed By:   riastradh
Date:           Fri May  8 00:49:43 UTC 2020

Modified Files:
        src/sys/arch/amd64/amd64: machdep.c
        src/sys/arch/x86/include: pmap.h
        src/sys/arch/x86/x86: pmap.c

Log Message:
Factor randomization out of slotspace_rand.

slotspace_rand becomes deterministic; the randomization moves into
the callers instead.  Why?

There are two callers of slotspace_rand:

- x86/pmap.c pmap_bootstrap
- amd64/amd64.c init_slotspace

When the randomization was introduced, it used an x86-only
`cpu_earlyrng' abstraction that would hash rdseed/rdrand and rdtsc
output together.  Except init_slotspace ran before cpu_probe, so
cpu_feature was not yet filled out, so during init_slotspace, the
only randomization was rdtsc.

In the course of the recent entropy overhaul, I replaced cpu_earlyrng
by entropy_extract, and moved cpu_init_rng much earlier -- but still
after cpu_probe -- in order to reduce the number of abstractions
lying around and the number of copies of rdrand/rdseed logic.  In so
doing I added some annoying complication (see curcpu_available) to
kern_entropy.c to make it work early enough for init_slotspace, and
dropped the rdtsc.

For pmap_bootstrap that didn't substantively change anything.  But
for init_slotspace, it removed the only randomization.  To mitigate
this, this commit pulls the randomization out of slotspace_rand into
pmap_bootstrap and init_slotspace, so that

(a) init_slotspace can use rdtsc and a little private entropy pool in
    order to restore the prior (weak) randomization it had, and

(b) pmap_bootstrap, which runs a little bit later, can continue to
    use entropy_extract normally and get rdrand/rdseed too.

A subsequent commit will move cpu_init_rng just a wee bit later,
after cpu_init_msrs, so the kern_entropy.c complications can go away.
Perhaps someone else more wizardly with x86 can find a way to make
init_slotspace run a little later too, after cpu_probe and after
cpu_init_msrs and after cpu_rng_init, but I am not that wizardly.


To generate a diff of this commit:
cvs rdiff -u -r1.352 -r1.353 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.119 -r1.120 src/sys/arch/x86/include/pmap.h
cvs rdiff -u -r1.388 -r1.389 src/sys/arch/x86/x86/pmap.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/amd64/machdep.c
diff -u src/sys/arch/amd64/amd64/machdep.c:1.352 src/sys/arch/amd64/amd64/machdep.c:1.353
--- src/sys/arch/amd64/amd64/machdep.c:1.352	Sat May  2 16:44:34 2020
+++ src/sys/arch/amd64/amd64/machdep.c	Fri May  8 00:49:42 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.352 2020/05/02 16:44:34 bouyer Exp $	*/
+/*	$NetBSD: machdep.c,v 1.353 2020/05/08 00:49:42 riastradh Exp $	*/
 
 /*
  * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011
@@ -110,7 +110,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.352 2020/05/02 16:44:34 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.353 2020/05/08 00:49:42 riastradh Exp $");
 
 #include "opt_modular.h"
 #include "opt_user_ldt.h"
@@ -158,6 +158,8 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 
 #include <sys/kgdb.h>
 #endif
 
+#include <lib/libkern/entpool.h> /* XXX */
+
 #include <dev/cons.h>
 #include <dev/mm.h>
 
@@ -1581,8 +1583,21 @@ init_pte(void)
 void
 init_slotspace(void)
 {
+	/*
+	 * XXX Too early to use cprng(9), or even entropy_extract.
+	 * Also too early to use rdrand/rdseed, since we haven't probed
+	 * cpu features yet.  This is a hack -- fix me!
+	 */
+	struct entpool pool;
+	size_t randhole;
+	vaddr_t randva;
+	uint64_t sample;
 	vaddr_t va;
 
+	memset(&pool, 0, sizeof pool);
+	sample = rdtsc();
+	entpool_enter(&pool, &sample, sizeof sample);
+
 	memset(&slotspace, 0, sizeof(slotspace));
 
 	/* User. [256, because we want to land in >= 256] */
@@ -1636,16 +1651,26 @@ init_slotspace(void)
 	slotspace.area[SLAREA_KERN].active = true;
 
 	/* Main. */
+	sample = rdtsc();
+	entpool_enter(&pool, &sample, sizeof sample);
+	entpool_extract(&pool, &randhole, sizeof randhole);
+	entpool_extract(&pool, &randva, sizeof randva);
 	va = slotspace_rand(SLAREA_MAIN, NKL4_MAX_ENTRIES * NBPD_L4,
-	    NBPD_L4); /* TODO: NBPD_L1 */
+	    NBPD_L4, randhole, randva); /* TODO: NBPD_L1 */
 	vm_min_kernel_address = va;
 	vm_max_kernel_address = va + NKL4_MAX_ENTRIES * NBPD_L4;
 
 #ifndef XENPV
 	/* PTE. */
-	va = slotspace_rand(SLAREA_PTE, NBPD_L4, NBPD_L4);
+	sample = rdtsc();
+	entpool_enter(&pool, &sample, sizeof sample);
+	entpool_extract(&pool, &randhole, sizeof randhole);
+	entpool_extract(&pool, &randva, sizeof randva);
+	va = slotspace_rand(SLAREA_PTE, NBPD_L4, NBPD_L4, randhole, randva);
 	pte_base = (pd_entry_t *)va;
 #endif
+
+	explicit_memset(&pool, 0, sizeof pool);
 }
 
 void

Index: src/sys/arch/x86/include/pmap.h
diff -u src/sys/arch/x86/include/pmap.h:1.119 src/sys/arch/x86/include/pmap.h:1.120
--- src/sys/arch/x86/include/pmap.h:1.119	Sat Apr 25 15:26:18 2020
+++ src/sys/arch/x86/include/pmap.h	Fri May  8 00:49:42 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.h,v 1.119 2020/04/25 15:26:18 bouyer Exp $	*/
+/*	$NetBSD: pmap.h,v 1.120 2020/05/08 00:49:42 riastradh Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -402,7 +402,7 @@ void		pmap_ept_transform(struct pmap *);
 #ifndef __HAVE_DIRECT_MAP
 void		pmap_vpage_cpu_init(struct cpu_info *);
 #endif
-vaddr_t		slotspace_rand(int, size_t, size_t);
+vaddr_t		slotspace_rand(int, size_t, size_t, size_t, vaddr_t);
 
 vaddr_t reserve_dumppages(vaddr_t); /* XXX: not a pmap fn */
 

Index: src/sys/arch/x86/x86/pmap.c
diff -u src/sys/arch/x86/x86/pmap.c:1.388 src/sys/arch/x86/x86/pmap.c:1.389
--- src/sys/arch/x86/x86/pmap.c:1.388	Tue May  5 17:02:01 2020
+++ src/sys/arch/x86/x86/pmap.c	Fri May  8 00:49:43 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.388 2020/05/05 17:02:01 bouyer Exp $	*/
+/*	$NetBSD: pmap.c,v 1.389 2020/05/08 00:49:43 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2008, 2010, 2016, 2017, 2019, 2020 The NetBSD Foundation, Inc.
@@ -130,7 +130,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.388 2020/05/05 17:02:01 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.389 2020/05/08 00:49:43 riastradh Exp $");
 
 #include "opt_user_ldt.h"
 #include "opt_lockdebug.h"
@@ -1415,7 +1415,8 @@ slotspace_copy(int type, pd_entry_t *dst
  * Finally we update the associated entry in the slotspace structure.
  */
 vaddr_t
-slotspace_rand(int type, size_t sz, size_t align)
+slotspace_rand(int type, size_t sz, size_t align, size_t randhole,
+    vaddr_t randva)
 {
 	struct {
 		int start;
@@ -1480,7 +1481,7 @@ slotspace_rand(int type, size_t sz, size
 	}
 
 	/* Select a hole. */
-	entropy_extract(&hole, sizeof(hole), 0);
+	hole = randhole;
 #ifdef NO_X86_ASLR
 	hole = 0;
 #endif
@@ -1490,7 +1491,7 @@ slotspace_rand(int type, size_t sz, size
 	startva = VA_SIGN_NEG(startsl * NBPD_L4);
 
 	/* Select an area within the hole. */
-	entropy_extract(&va, sizeof(va), 0);
+	va = randva;
 #ifdef NO_X86_ASLR
 	va = 0;
 #endif
@@ -1619,6 +1620,8 @@ pmap_init_directmap(struct pmap *kpm)
 	pt_entry_t *pte;
 	phys_ram_seg_t *mc;
 	int i;
+	size_t randhole;
+	vaddr_t randva;
 
 	const pd_entry_t pteflags = PTE_P | PTE_W | pmap_pg_nx;
 	const pd_entry_t holepteflags = PTE_P | pmap_pg_nx;
@@ -1642,7 +1645,10 @@ pmap_init_directmap(struct pmap *kpm)
 		panic("pmap_init_directmap: lastpa incorrect");
 	}
 
-	startva = slotspace_rand(SLAREA_DMAP, lastpa, NBPD_L2);
+	entropy_extract(&randhole, sizeof randhole, 0);
+	entropy_extract(&randva, sizeof randva, 0);
+	startva = slotspace_rand(SLAREA_DMAP, lastpa, NBPD_L2,
+	    randhole, randva);
 	endva = startva + lastpa;
 
 	/* We will use this temporary va. */

Reply via email to