XenevaOS
Loading...
Searching...
No Matches
hw_random.h
Go to the documentation of this file.
1#ifndef LINUX_HWRANDOM_H_
2#define LINUX_HWRANDOM_H_
3
4/*
5 * DCL <linux/hw_random.h> -- struct hwrng and the register/unregister pair.
6 *
7 * Field order is copied from mainline v7.2 include/linux/hw_random.h and must
8 * stay that way: DCL/linux_kmod_shim.c hands the registered rng back out as an
9 * opaque pointer and reads ->name / ->read off it, so the two definitions are
10 * one ABI in two files. If a field moves here, the shim reads the wrong one
11 * and every hwrng read returns garbage -- quietly, because the types are all
12 * still pointers.
13 *
14 * The prototypes match mainline exactly, in particular
15 *
16 * int (*read)(struct hwrng *rng, void *data, size_t max, bool wait);
17 *
18 * `size_t`, not `unsigned long`: this target is aarch64 *Windows*, LLP64, so
19 * unsigned long is 4 bytes while size_t is 8. A shim copy declaring `unsigned
20 * long max` still lines up as a struct (every member above it is a pointer)
21 * but passes a 32-bit argument where the callee reads 64, which only works
22 * while the compiler happens to zero-extend. That mismatch was found while
23 * bringing virtio-rng in through the vendored build; the shim copy now
24 * follows this header rather than the other way round.
25 *
26 * ### The private tail is deliberately absent
27 *
28 * mainline continues with `struct list_head list; struct kref ref; struct
29 * work_struct cleanup_work; struct completion cleanup_done; struct completion
30 * dying;` -- all of it bookkeeping for hwrng core's unregister-delay machinery.
31 * DCL's hwrng_register() (linux_kmod_shim.c) is a fixed-size table of
32 * pointers: it stores the address and never touches the tail, so the fields
33 * would be allocation nobody reads. Keeping them would also mean including
34 * <linux/list.h> here to give `list` a complete type, which puts mainline's
35 * `list_add(list_head*, list_head*)` into every translation unit that reaches
36 * this header -- and Xeneva's own <list.h> spells `list_add(list_t*, void*)`,
37 * so any TU that ever sees both fails to compile (that is the stage-1 gotcha,
38 * recorded in the tracker). One unused member is not worth that.
39 *
40 * If DCL ever ports the real hwrng core, add the tail back and accept the
41 * list.h inclusion -- but then, and only then.
42 */
43
44#include <linux/kernel.h> /* size_t, bool, u32 */
45
46struct hwrng {
47 /* Unique RNG name. */
48 const char* name;
49 /* Initialization callback (can be NULL). */
50 int (*init)(struct hwrng* rng);
51 /* Cleanup callback (can be NULL). */
52 void (*cleanup)(struct hwrng* rng);
53 /*
54 * data_present / data_read are mainline's *OBSOLETE* API, kept because
55 * a driver may still implement either. Nothing in DCL calls them: the
56 * shim reads through ->read only.
57 */
58 int (*data_present)(struct hwrng* rng, int wait);
59 int (*data_read)(struct hwrng* rng, u32* data);
60 /*
61 * New API: fill up to max bytes. mainline documents max as a multiple
62 * of 4 and >= 32; nothing here enforces that -- hwrng_selftest() passes
63 * 32 against a 32-byte buffer, and /dev/urandom passes whatever chunk
64 * its caller asked for. The field is only the type signature.
65 */
66 int (*read)(struct hwrng* rng, void* data, size_t max, bool wait);
67 /*
68 * DCL delta: mainline has `unsigned long priv;`, which is pointer-sized
69 * on LP64 (Linux/arm64) and therefore cannot be reproduced on this
70 * target -- aarch64-unknown-windows is LLP64, `unsigned long` is 4
71 * bytes, and this field holds `struct virtrng_info *`, which lives in
72 * the kernel high half at 0xFFFFC000.... A 32-bit `priv` would silently
73 * drop the top half of every pointer stored into it.
74 *
75 * uintptr_t is the same "integer that holds a pointer" the field is
76 * for, and it is pointer-sized here. This is one half of a two-part
77 * fix -- the other is the matching cast in virtio-rng.c:171, in the
78 * vendored source, which cannot be fixed from a header.
79 *
80 * Changing this does not move anything: the field is last-but-one in
81 * the public part of struct hwrng (quality follows), and DCL's hwrng
82 * core has no private tail to be positioned against -- see the note at
83 * the top of this header.
84 */
86 /*
87 * Bits of entropy per 1024 bits of input; 1..1024, or 0 for maximum.
88 * virtio-rng leaves this 0 (its own read path reports nothing).
89 */
90 unsigned short quality;
91};
92
93/*
94 * DCL/linux_kmod_shim.c defines both. Declared (not defined) here so a
95 * driver can call them the way it does upstream, and so the compiler checks
96 * the argument type instead of accepting an implicit int.
97 */
98extern int hwrng_register(struct hwrng* rng);
99extern void hwrng_unregister(struct hwrng* rng);
100
101#endif /* LINUX_HWRANDOM_H_ */
unsigned int uintptr_t
Definition stdint.h:94
void hwrng_unregister(void)
void hwrng_register(void)
void * data
Definition kthread.h:30
uint32_t u32
Definition kernel.h:16
#define max(a, b)
Definition minmax.h:28
Definition hw_random.h:46
int(* read)(struct hwrng *rng, void *data, size_t max, bool wait)
Definition hw_random.h:66
const char * name
Definition hw_random.h:48
uintptr_t priv
Definition hw_random.h:85
int(* data_read)(struct hwrng *rng, u32 *data)
Definition hw_random.h:59
int(* init)(struct hwrng *rng)
Definition hw_random.h:50
void(* cleanup)(struct hwrng *rng)
Definition hw_random.h:52
int(* data_present)(struct hwrng *rng, int wait)
Definition hw_random.h:58
unsigned short quality
Definition hw_random.h:90