Commit | Line | Data |
---|---|---|
8ab3820f KC |
1 | #include "misc.h" |
2 | ||
3 | #ifdef CONFIG_RANDOMIZE_BASE | |
5bfce5ef KC |
4 | #include <asm/msr.h> |
5 | #include <asm/archrandom.h> | |
6 | ||
7 | #define I8254_PORT_CONTROL 0x43 | |
8 | #define I8254_PORT_COUNTER0 0x40 | |
9 | #define I8254_CMD_READBACK 0xC0 | |
10 | #define I8254_SELECT_COUNTER0 0x02 | |
11 | #define I8254_STATUS_NOTREADY 0x40 | |
12 | static inline u16 i8254(void) | |
13 | { | |
14 | u16 status, timer; | |
15 | ||
16 | do { | |
17 | outb(I8254_PORT_CONTROL, | |
18 | I8254_CMD_READBACK | I8254_SELECT_COUNTER0); | |
19 | status = inb(I8254_PORT_COUNTER0); | |
20 | timer = inb(I8254_PORT_COUNTER0); | |
21 | timer |= inb(I8254_PORT_COUNTER0) << 8; | |
22 | } while (status & I8254_STATUS_NOTREADY); | |
23 | ||
24 | return timer; | |
25 | } | |
26 | ||
27 | static unsigned long get_random_long(void) | |
28 | { | |
29 | unsigned long random; | |
30 | ||
31 | if (has_cpuflag(X86_FEATURE_RDRAND)) { | |
32 | debug_putstr("KASLR using RDRAND...\n"); | |
33 | if (rdrand_long(&random)) | |
34 | return random; | |
35 | } | |
36 | ||
37 | if (has_cpuflag(X86_FEATURE_TSC)) { | |
38 | uint32_t raw; | |
39 | ||
40 | debug_putstr("KASLR using RDTSC...\n"); | |
41 | rdtscl(raw); | |
42 | ||
43 | /* Only use the low bits of rdtsc. */ | |
44 | random = raw & 0xffff; | |
45 | } else { | |
46 | debug_putstr("KASLR using i8254...\n"); | |
47 | random = i8254(); | |
48 | } | |
49 | ||
50 | /* Extend timer bits poorly... */ | |
51 | random |= (random << 16); | |
52 | #ifdef CONFIG_X86_64 | |
53 | random |= (random << 32); | |
54 | #endif | |
55 | return random; | |
56 | } | |
8ab3820f KC |
57 | |
58 | unsigned char *choose_kernel_location(unsigned char *input, | |
59 | unsigned long input_size, | |
60 | unsigned char *output, | |
61 | unsigned long output_size) | |
62 | { | |
63 | unsigned long choice = (unsigned long)output; | |
64 | ||
65 | if (cmdline_find_option_bool("nokaslr")) { | |
66 | debug_putstr("KASLR disabled...\n"); | |
67 | goto out; | |
68 | } | |
69 | ||
70 | /* XXX: choose random location. */ | |
71 | ||
72 | out: | |
73 | return (unsigned char *)choice; | |
74 | } | |
75 | ||
76 | #endif /* CONFIG_RANDOMIZE_BASE */ |