Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
638d957
Documentation
arch
alpha
arm
avr32
blackfin
c6x
cris
frv
h8300
hexagon
ia64
m32r
m68k
microblaze
mips
mn10300
openrisc
parisc
powerpc
s390
score
sh
sparc
tile
um
unicore32
x86
boot
configs
crypto
ia32
include
kernel
kvm
lguest
lib
math-emu
mm
net
oprofile
pci
platform
power
realmode
rm
Makefile
init.c
rmpiggy.S
syscalls
tools
um
vdso
video
xen
.gitignore
Kbuild
Kconfig
Kconfig.cpu
Kconfig.debug
Makefile
Makefile.um
Makefile_32.cpu
xtensa
.gitignore
Kconfig
block
crypto
drivers
firmware
fs
include
init
ipc
kernel
lib
mm
net
samples
scripts
security
sound
tools
usr
virt
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
REPORTING-BUGS
Breadcrumbs
linux
/
arch
/
x86
/
realmode
/
init.c
Blame
Blame
Latest commit
History
History
115 lines (95 loc) · 3.06 KB
Breadcrumbs
linux
/
arch
/
x86
/
realmode
/
init.c
Top
File metadata and controls
Code
Blame
115 lines (95 loc) · 3.06 KB
Raw
#include <linux/io.h> #include <linux/memblock.h> #include <asm/cacheflush.h> #include <asm/pgtable.h> #include <asm/realmode.h> struct real_mode_header *real_mode_header; u32 *trampoline_cr4_features; void __init setup_real_mode(void) { phys_addr_t mem; u16 real_mode_seg; u32 *rel; u32 count; u32 *ptr; u16 *seg; int i; unsigned char *base; struct trampoline_header *trampoline_header; size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob); #ifdef CONFIG_X86_64 u64 *trampoline_pgd; u64 efer; #endif /* Has to be in very low memory so we can execute real-mode AP code. */ mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE); if (!mem) panic("Cannot allocate trampoline\n"); base = __va(mem); memblock_reserve(mem, size); real_mode_header = (struct real_mode_header *) base; printk(KERN_DEBUG "Base memory trampoline at [%p] %llx size %zu\n", base, (unsigned long long)mem, size); memcpy(base, real_mode_blob, size); real_mode_seg = __pa(base) >> 4; rel = (u32 *) real_mode_relocs; /* 16-bit segment relocations. */ count = rel[0]; rel = &rel[1]; for (i = 0; i < count; i++) { seg = (u16 *) (base + rel[i]); *seg = real_mode_seg; } /* 32-bit linear relocations. */ count = rel[i]; rel = &rel[i + 1]; for (i = 0; i < count; i++) { ptr = (u32 *) (base + rel[i]); *ptr += __pa(base); } /* Must be perfomed *after* relocation. */ trampoline_header = (struct trampoline_header *) __va(real_mode_header->trampoline_header); #ifdef CONFIG_X86_32 trampoline_header->start = __pa(startup_32_smp); trampoline_header->gdt_limit = __BOOT_DS + 7; trampoline_header->gdt_base = __pa(boot_gdt); #else /* * Some AMD processors will #GP(0) if EFER.LMA is set in WRMSR * so we need to mask it out. */ rdmsrl(MSR_EFER, efer); trampoline_header->efer = efer & ~EFER_LMA; trampoline_header->start = (u64) secondary_startup_64; trampoline_cr4_features = &trampoline_header->cr4; *trampoline_cr4_features = read_cr4(); trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd); trampoline_pgd[0] = __pa(level3_ident_pgt) + _KERNPG_TABLE; trampoline_pgd[511] = __pa(level3_kernel_pgt) + _KERNPG_TABLE; #endif } /* * set_real_mode_permissions() gets called very early, to guarantee the * availability of low memory. This is before the proper kernel page * tables are set up, so we cannot set page permissions in that * function. Thus, we use an arch_initcall instead. */ static int __init set_real_mode_permissions(void) { unsigned char *base = (unsigned char *) real_mode_header; size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob); size_t ro_size = PAGE_ALIGN(real_mode_header->ro_end) - __pa(base); size_t text_size = PAGE_ALIGN(real_mode_header->ro_end) - real_mode_header->text_start; unsigned long text_start = (unsigned long) __va(real_mode_header->text_start); set_memory_nx((unsigned long) base, size >> PAGE_SHIFT); set_memory_ro((unsigned long) base, ro_size >> PAGE_SHIFT); set_memory_x((unsigned long) text_start, text_size >> PAGE_SHIFT); return 0; } arch_initcall(set_real_mode_permissions);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
You can’t perform that action at this time.