1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/types.h>
27 #include <sys/sysmacros.h>
28 #include <sys/modctl.h>
29 #include <sys/conf.h>
30 #include <sys/devops.h>
31 #include <sys/cmn_err.h>
32 #include <sys/kmem.h>
33 #include <sys/stat.h>
34 #include <sys/open.h>
35 #include <sys/file.h>
36 #include <sys/ddi.h>
37 #include <sys/sunddi.h>
38 #include <sys/cpuvar.h>
39 #include <sys/disp.h>
40 #include <sys/hsvc.h>
41 #include <sys/machsystm.h>
42 #include <sys/param.h>
43 #include <sys/hypervisor_api.h>
44 #include <sys/n2rng.h>
45
46 /*
47 * There are 3 noise cells each with its own oscillator, and each
48 * oscillator can be set to 4 different bias setttings. The bias
49 * setting controls the nominal frequency of the oscillator. The 3
50 * and 4 and hardcoded throughout this file.
51 */
52
53 #define BITS_IN(type) (8 * sizeof (type))
54 #define EXTRACTBIT64(val, bit) (((val) >> (bit)) & 1UL)
55
56 /*
57 * Policy settings
58 */
59 /* Log2 of the number of bits */
60 #define SETTLECYCLES 1000000
61 #define NORMAL_BYPASS 1
62 #define NUMOSC 3
63 #define LOG2_DATA_WORDS 15
64 #define DATA_WORDS (1 << LOG2_DATA_WORDS)
65
66 #define ENTROPY_PASS_VALUE 150000000ULL
67
68 /*
69 * There is a hardware bug that causes the RNG_DATA register to
70 * occasionally be read one cycle before the specifed time.
71 * LOGIC_TEST_EXPECTED_M1 is the value one cycle before
72 * LOGIC_TEST_CYCLES. And there is a second bug that causes the read
73 * to be delayed. We have seen delays of about 150 cycles, but do not
74 * know that maximum that could possibly occur.
75 *
76 * We collect LOGIC_TEST_WORDS words using a diagnostic read with all
77 * entropy turned off. The first one we skip, becuase we have no
78 * knowledge of the time since the last read. We check that the
79 * remaining values fall in the window of values that should occur
80 * between LOGIC_TEST_CYCLES - 1 and LOGIC_TEST_CYCLES +
81 * LOGIC_TEST_BUG_MAX. As further protecion against false positives,
82 * we report success if the the number of mismatches does not exceed
83 * LOGIC_TEST_ERRORS_ALLOWED.
84 *
85 * When running on maramba systems, delays as high as 20000 were observed
86 * LOGIC_TEST_BUG_MAX was increased to twice this observed value since all
87 * that matters is that the hardware is indeed generating the expected values
88 * in diag mode. The code was also modified to exit as soon as the required
89 * number of matches is detected.
90 */
91
92 #define LOGIC_TEST_CYCLES 38859
93 #define LOGIC_TEST_EXPECTED_M1 0xb8820c7bd387e32cULL
94 #define LOGIC_TEST_BUG_MAX 40000
95 #define LOGIC_TEST_WORDS 8 /* includes first one, unused */
96 #define LOGIC_TEST_ERRORS_ALLOWED 1
97 #define LOGIC_TEST_MATCHES_NEEDED (LOGIC_TEST_WORDS - 1 - \
98 LOGIC_TEST_ERRORS_ALLOWED)
99
100 #define RNG_POLY 0x231dcee91262b8a3ULL
101 #define ENTDIVISOR (((1ULL << LOG_VAL_SCALE) + 500ULL) / 1000ULL)
102
103 #define ENCODEBIAS(osc, bias) (((bias) & 0x3) << (2 * (osc)))
104 #define EXTRACTBIAS(blob, osc) (((blob) >> (2 * (osc))) & 0x3)
105
106 extern int n2rng_herr2kerr(uint64_t hv_errcode);
107
108
109 /*
110 * Each value is a representation of the polynomail bit_i * x^i, where
111 * i=0 corresponds to the least significant bit of the word. The
112 * modulus polynomial is x^64 + the interpretation of poly. Out is
113 * set to in * x^exp mod moduluspolynomial. This corresponds to
114 * running the LFSR exp cycles. This implemenation directly simulates
115 * the lfsr. It's running time is O(exp), but the constant is small.
116 * (This code was taken verbatim from Legion.)
117 */
118 static void
lfsr64_adv_seq(uint64_t poly,uint64_t in,uint64_t exp,uint64_t * out)119 lfsr64_adv_seq(uint64_t poly, uint64_t in, uint64_t exp, uint64_t *out)
120 {
121 int i;
122 uint64_t res = in;
123
124 for (i = 0; i < exp; i++) {
125 if (res & 0x8000000000000000ULL) {
126 res = (res << 1) ^ poly;
127 } else {
128 res <<= 1;
129 }
130 }
131
132 *out = res;
133 }
134
135 int
n2rng_logic_test(n2rng_t * n2rng,int rngid)136 n2rng_logic_test(n2rng_t *n2rng, int rngid)
137 {
138 n2rng_setup_t logictest;
139 uint64_t buffer[LOGIC_TEST_WORDS];
140 uint64_t reg;
141 int rv;
142 int i, j;
143 int correctcount = 0;
144 rng_entry_t *rng = &n2rng->n_ctl_data->n_rngs[rngid];
145 int cycles[LOGIC_TEST_WORDS] =
146 {0, 0, 0, 0, 0, 0, 0, 0};
147
148 /*
149 * This test runs the RNG with no entropy for
150 * LOGIC_TEST_CYCLES cycles. Ideally the value would be be
151 * LOGIC_TEST_RESULT, but because of the RNG bug, the actual
152 * register read may be delayed by upto LOGIC_TEST_BUG_MAX
153 * cycles. So we simulate over that window, and a match
154 * occurs, we report success.
155 */
156
157 logictest.ctlwds[0].word = 0;
158 logictest.ctlwds[0].fields.rnc_anlg_sel = N2RNG_NOANALOGOUT;
159 logictest.ctlwds[1] = logictest.ctlwds[0];
160 logictest.ctlwds[2] = logictest.ctlwds[0];
161 logictest.ctlwds[3] = logictest.ctlwds[0];
162 logictest.ctlwds[3].fields.rnc_mode = 1;
163 logictest.ctlwds[3].fields.rnc_cnt = LOGIC_TEST_CYCLES - 2;
164
165 /* read LOGIC_TEST_WORDS 64-bit words */
166 rv = n2rng_collect_diag_bits(n2rng, rngid, &logictest, buffer,
167 LOGIC_TEST_WORDS * sizeof (uint64_t),
168 &rng->n_preferred_config, rng->n_rng_state);
169 if (rv) {
170 cmn_err(CE_WARN, "n2rng: n2rng_collect_diag_bits failed with "
171 "0x%x on rng(%d)", rv, rngid);
172 return (rv);
173 }
174
175 reg = LOGIC_TEST_EXPECTED_M1;
176 for (i = 0; i <= LOGIC_TEST_BUG_MAX; i++) {
177 for (j = 1; j < LOGIC_TEST_WORDS; ++j) {
178 if (buffer[j] == reg) {
179 ++correctcount;
180 cycles[j] = i;
181 }
182 }
183 /* exit loop if we have already found enough matches */
184 if (correctcount >= LOGIC_TEST_MATCHES_NEEDED) {
185 break;
186 }
187 /* advance reg by one step */
188 lfsr64_adv_seq(RNG_POLY, reg, 1, ®);
189 }
190
191 if (correctcount < LOGIC_TEST_MATCHES_NEEDED) {
192 /*
193 * Don't log a warning here since the calling routine will
194 * retry and log it's own warning if the retry fails.
195 */
196 DBG2(n2rng, DHEALTH, "n2rng: logic error on rng(%d), only %d "
197 "matches found", rngid, correctcount);
198 for (i = 0; i < LOGIC_TEST_WORDS; i++) {
199 DBG3(n2rng, DHEALTH, "buffer[%d] %016llx, cycles = %d",
200 i, buffer[i], cycles[i]);
201 }
202 return (EIO);
203 } else {
204 DBG3(n2rng, DHEALTH, "n2rng: rng(%d) logic test passed, "
205 "%d matches in %d cycles", rngid, correctcount, i);
206 for (i = 0; i < LOGIC_TEST_WORDS; i++) {
207 DBG3(n2rng, DCHATTY, "buffer[%d] %016llx, cycles = %d",
208 i, buffer[i], cycles[i]);
209 }
210 }
211
212 return (0);
213 }
214
215
216 /*
217 * gets the metric for the specified state.
218 */
219 int
n2rng_collect_metrics(n2rng_t * n2rng,int rngid,n2rng_setup_t * setupp,n2rng_setup_t * exit_setupp,uint64_t exit_state,n2rng_osc_perf_t * metricp)220 n2rng_collect_metrics(n2rng_t *n2rng, int rngid, n2rng_setup_t *setupp,
221 n2rng_setup_t *exit_setupp,
222 uint64_t exit_state, n2rng_osc_perf_t *metricp)
223 {
224 int rv;
225 int bufsize;
226 uint64_t *buffer = NULL;
227
228
229 bufsize = DATA_WORDS * sizeof (uint64_t);
230 buffer = (uint64_t *)contig_mem_alloc_align(bufsize,
231 CONTIG_ALIGNMENT);
232 if (buffer == NULL) {
233 return (ENOMEM);
234 }
235
236 rv = n2rng_collect_diag_bits(n2rng, rngid, setupp, buffer, bufsize,
237 exit_setupp, exit_state);
238 if (rv) {
239 cmn_err(CE_WARN,
240 "n2rng: n2rng_collect_bits returns 0x%x", rv);
241 } else {
242 n2rng_renyi_entropy(buffer, LOG2_DATA_WORDS, metricp);
243 }
244
245 contig_mem_free(buffer, bufsize);
246
247 return (rv);
248 }
249
250
251 /*
252 * Fills in table with the performance of each oscillator at each
253 * bias setting. A particular datum goes in table[osc][bias].
254 */
255 int
collect_rng_perf(n2rng_t * n2rng,int rngid,n2rng_osc_perf_table_t ptable)256 collect_rng_perf(n2rng_t *n2rng, int rngid, n2rng_osc_perf_table_t ptable)
257 {
258 int bias;
259 int osc;
260 n2rng_setup_t rngstate;
261 int rv;
262 rng_entry_t *rng = &n2rng->n_ctl_data->n_rngs[rngid];
263
264 rngstate.ctlwds[0].word = 0;
265 rngstate.ctlwds[0].fields.rnc_anlg_sel = N2RNG_NOANALOGOUT;
266 rngstate.ctlwds[1] = rngstate.ctlwds[0];
267 rngstate.ctlwds[2] = rngstate.ctlwds[0];
268 rngstate.ctlwds[3] = rngstate.ctlwds[0];
269
270 for (osc = 0; osc < N2RNG_NOSC; osc++) {
271 rngstate.ctlwds[3].fields.rnc_selbits = 1 << osc;
272 for (bias = 0; bias < N2RNG_NBIASES; bias++) {
273 rngstate.ctlwds[3].fields.rnc_vcoctl = bias;
274 rv = n2rng_collect_metrics(n2rng, rngid, &rngstate,
275 &rng->n_preferred_config, rng->n_rng_state,
276 &(ptable[osc][bias]));
277 if (rv) {
278 return (rv);
279 }
280 }
281 }
282
283 return (rv);
284 }
285
286 /*
287 * The following 2 functions test the performance of each noise cell
288 * and select the bias settings. They implement the following
289 * policies:
290 *
291 * 1. No two cells may be set to the same bias. (Cells with the same bias,
292 * which controls frequency, may beat together, with long
293 * runs of no entropy as a pair when they are nearly synchronized.)
294 * 2. The entropy of each cell is determined (for now) by the Renyi H2
295 * entropy of a collection of samples of raw bits.
296 * 3. The selected configuration is the one that has the largest total
297 * entropy, computed as stated above.
298 * 4. The delay is hard coded.
299 */
300
301
302 /*
303 * Finds the preferred configuration from perf data. Sets the
304 * preferred configuration in the n2rng structure.
305 */
306 int
n2rng_noise_gen_preferred(n2rng_t * n2rng,int rngid)307 n2rng_noise_gen_preferred(n2rng_t *n2rng, int rngid)
308 {
309 int rv;
310 int rventropy = 0; /* EIO if entropy is too low */
311 int b0, b1, b2;
312 int osc;
313 int bset;
314 n2rng_osc_perf_t *candidates[N2RNG_NOSC];
315 uint64_t bestcellentropy[N2RNG_NOSC] = {0};
316 uint64_t bestentropy = 0;
317 n2rng_ctl_t rng_ctl = {0};
318 int i;
319 rng_entry_t *rng = &n2rng->n_ctl_data->n_rngs[rngid];
320
321 rv = collect_rng_perf(n2rng, rngid, rng->n_perftable);
322 if (rv) {
323 return (rv);
324 }
325
326 /*
327 * bset is the bias setting of all 3 oscillators packed into a
328 * word, 2 bits for each: b2:b1:b0. First we set up an
329 * arbitrary assignment, because in an earlier version of
330 * this code, there were cases where the assignment would
331 * never happen. Also, that way we don't need to prove
332 * assignment to prove we never have uninitalized variables,
333 * and hence it might avoid lint warnings.
334 *
335 * This block of code picks the "best" setting of the biases,
336 * where "best" is defined by the rules in the big comment
337 * block above.
338 *
339 * There are only 24 possible combinations such that no two
340 * oscillators get the same bias. We just do a brute force
341 * exhaustive search of the entire space.
342 */
343 bset = ENCODEBIAS(2, 2) | ENCODEBIAS(1, 1) | ENCODEBIAS(0, 0);
344 for (b0 = 0; b0 < N2RNG_NBIASES; b0++) {
345 candidates[0] = &rng->n_perftable[0][b0];
346 for (b1 = 0; b1 < N2RNG_NBIASES; b1++) {
347 if (b0 == b1) continue;
348 candidates[1] = &rng->n_perftable[1][b1];
349 for (b2 = 0; b2 < N2RNG_NBIASES; b2++) {
350 uint64_t totalentropy = 0;
351
352 if (b0 == b2 || b1 == b2) continue;
353 candidates[2] = &rng->n_perftable[2][b2];
354 for (i = 0; i < N2RNG_NOSC; i++) {
355 totalentropy += candidates[i]->H2;
356 }
357 if (totalentropy > bestentropy) {
358 bestentropy = totalentropy;
359 bset = ENCODEBIAS(0, b0) |
360 ENCODEBIAS(1, b1) |
361 ENCODEBIAS(2, b2);
362 for (i = 0; i < N2RNG_NOSC; i++) {
363 bestcellentropy[i] =
364 candidates[i]->H2;
365 }
366
367 }
368
369 }
370 }
371 }
372
373 if (bestentropy < ENTROPY_PASS_VALUE) {
374 cmn_err(CE_WARN,
375 "n2rng: RNG hardware producing insufficient "
376 "entropy (producing %ld, need %lld)",
377 bestentropy, ENTROPY_PASS_VALUE);
378 rventropy = EIO;
379 }
380
381 /*
382 * Set up fields of control words that will be the same for all
383 * osciallators and for final value that selects all
384 * oscillators.
385 */
386 rng_ctl.fields.rnc_cnt = n2rng->n_ctl_data->n_accumulate_cycles;
387 rng_ctl.fields.rnc_mode = 1; /* set normal mode */
388 rng_ctl.fields.rnc_anlg_sel = N2RNG_NOANALOGOUT;
389
390
391 /*
392 * Now set the oscillator biases.
393 */
394 for (osc = 0; osc < N2RNG_NOSC; osc++) {
395 rng_ctl.fields.rnc_selbits = 1 << osc;
396 rng_ctl.fields.rnc_vcoctl = EXTRACTBIAS(bset, osc);
397 rng->n_preferred_config.ctlwds[osc] = rng_ctl;
398 }
399
400 rng_ctl.fields.rnc_cnt = n2rng->n_ctl_data->n_accumulate_cycles;
401 rng_ctl.fields.rnc_vcoctl = 0;
402 rng_ctl.fields.rnc_selbits = 0x7;
403 rng->n_preferred_config.ctlwds[3] = rng_ctl;
404
405 if (rventropy == 0) {
406
407 /* Save bias and entropy results for kstats */
408 for (i = 0; i < N2RNG_NOSC; i++) {
409 rng->n_bias_info[i].bias =
410 (uint64_t)EXTRACTBIAS(bset, i);
411 rng->n_bias_info[i].entropy =
412 (uint64_t)(bestcellentropy[i] / ENTDIVISOR);
413 DBG4(n2rng, DCHATTY,
414 "n2rng_noise_gen_preferred: rng %d cell %d bias "
415 "%ld: %ld", rngid, i, rng->n_bias_info[i].bias,
416 rng->n_bias_info[i].entropy);
417 }
418 } else {
419
420 /* Clear bias and entropy results for kstats */
421 for (i = 0; i < N2RNG_NOSC; i++) {
422 rng->n_bias_info[i].bias = 0;
423 rng->n_bias_info[i].entropy = 0;
424 }
425 }
426
427 return (rv ? rv : rventropy);
428 }
429
430 /*
431 * Do a logic test, then find and set the best bias confuration
432 * (failing if insufficient entropy is generated, then set state to
433 * configured. This function should only be called when running in
434 * the control domain.
435 */
436 int
n2rng_do_health_check(n2rng_t * n2rng,int rngid)437 n2rng_do_health_check(n2rng_t *n2rng, int rngid)
438 {
439 int rv = EIO;
440 rng_entry_t *rng = &n2rng->n_ctl_data->n_rngs[rngid];
441 int attempts;
442
443 for (attempts = 0;
444 (attempts < RNG_MAX_LOGIC_TEST_ATTEMPTS) && rv; attempts++) {
445 rv = n2rng_logic_test(n2rng, rngid);
446 }
447
448 if (rv) {
449 cmn_err(CE_WARN, "n2rng: n2rng_logic_test failed %d attempts",
450 RNG_MAX_LOGIC_TEST_ATTEMPTS);
451 goto errorexit;
452 } else if (attempts > 1) {
453 DBG1(n2rng, DHEALTH,
454 "n2rng: n2rng_logic_test failed %d attempts",
455 attempts - 1);
456 goto errorexit;
457 }
458
459 rv = n2rng_noise_gen_preferred(n2rng, rngid);
460 if (rv) {
461 DBG0(n2rng, DHEALTH,
462 "n2rng: n2rng_noise_gen_preferred failed");
463 goto errorexit;
464 }
465
466 /* Push the selected config into HW */
467 rv = n2rng_collect_diag_bits(n2rng, rngid, NULL, NULL, 0,
468 &rng->n_preferred_config, CTL_STATE_CONFIGURED);
469 if (rv) {
470 DBG0(n2rng, DHEALTH,
471 "n2rng: n2rng_collect_diag_bits failed");
472 goto errorexit;
473 }
474
475 return (rv);
476
477 errorexit:
478 /* Push the selected config into HW with an error state */
479 (void) n2rng_collect_diag_bits(n2rng, rngid, NULL, NULL, 0,
480 &rng->n_preferred_config, CTL_STATE_ERROR);
481
482 return (rv);
483 }
484