~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/lib/kaslr.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * Entropy functions used on early boot for KASLR base and memory
  4  * randomization. The base randomization is done in the compressed
  5  * kernel and memory randomization is done early when the regular
  6  * kernel starts. This file is included in the compressed kernel and
  7  * normally linked in the regular.
  8  */
  9 #include <asm/asm.h>
 10 #include <asm/kaslr.h>
 11 #include <asm/msr.h>
 12 #include <asm/archrandom.h>
 13 #include <asm/e820/api.h>
 14 #include <asm/shared/io.h>
 15 
 16 /*
 17  * When built for the regular kernel, several functions need to be stubbed out
 18  * or changed to their regular kernel equivalent.
 19  */
 20 #ifndef KASLR_COMPRESSED_BOOT
 21 #include <asm/cpufeature.h>
 22 #include <asm/setup.h>
 23 
 24 #define debug_putstr(v) early_printk("%s", v)
 25 #define has_cpuflag(f) boot_cpu_has(f)
 26 #define get_boot_seed() kaslr_offset()
 27 #endif
 28 
 29 #define I8254_PORT_CONTROL      0x43
 30 #define I8254_PORT_COUNTER0     0x40
 31 #define I8254_CMD_READBACK      0xC0
 32 #define I8254_SELECT_COUNTER0   0x02
 33 #define I8254_STATUS_NOTREADY   0x40
 34 static inline u16 i8254(void)
 35 {
 36         u16 status, timer;
 37 
 38         do {
 39                 outb(I8254_CMD_READBACK | I8254_SELECT_COUNTER0,
 40                      I8254_PORT_CONTROL);
 41                 status = inb(I8254_PORT_COUNTER0);
 42                 timer  = inb(I8254_PORT_COUNTER0);
 43                 timer |= inb(I8254_PORT_COUNTER0) << 8;
 44         } while (status & I8254_STATUS_NOTREADY);
 45 
 46         return timer;
 47 }
 48 
 49 unsigned long kaslr_get_random_long(const char *purpose)
 50 {
 51 #ifdef CONFIG_X86_64
 52         const unsigned long mix_const = 0x5d6008cbf3848dd3UL;
 53 #else
 54         const unsigned long mix_const = 0x3f39e593UL;
 55 #endif
 56         unsigned long raw, random = get_boot_seed();
 57         bool use_i8254 = true;
 58 
 59         if (purpose) {
 60                 debug_putstr(purpose);
 61                 debug_putstr(" KASLR using");
 62         }
 63 
 64         if (has_cpuflag(X86_FEATURE_RDRAND)) {
 65                 if (purpose)
 66                         debug_putstr(" RDRAND");
 67                 if (rdrand_long(&raw)) {
 68                         random ^= raw;
 69                         use_i8254 = false;
 70                 }
 71         }
 72 
 73         if (has_cpuflag(X86_FEATURE_TSC)) {
 74                 if (purpose)
 75                         debug_putstr(" RDTSC");
 76                 raw = rdtsc();
 77 
 78                 random ^= raw;
 79                 use_i8254 = false;
 80         }
 81 
 82         if (use_i8254) {
 83                 if (purpose)
 84                         debug_putstr(" i8254");
 85                 random ^= i8254();
 86         }
 87 
 88         /* Circular multiply for better bit diffusion */
 89         asm(_ASM_MUL "%3"
 90             : "=a" (random), "=d" (raw)
 91             : "a" (random), "rm" (mix_const));
 92         random += raw;
 93 
 94         if (purpose)
 95                 debug_putstr("...\n");
 96 
 97         return random;
 98 }
 99 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php