diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-26 13:13:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-26 13:13:35 -0400 |
commit | 5bb241b325d7d91bc4ec0b394f31dffb17fe7978 (patch) | |
tree | 1bd68903871185173c47a95fef1bf76c848a1c62 /arch/x86/kernel | |
parent | 76e0134f4154aeadac833c2daea32102c64c0bb0 (diff) | |
parent | 704daf55c7297e727021063cb5d8ba1c55b84426 (diff) |
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
x86: Remove redundant non-NUMA topology functions
x86: early_printk: Protect against using the same device twice
x86: Reduce verbosity of "PAT enabled" kernel message
x86: Reduce verbosity of "TSC is reliable" message
x86: mce: Use safer ways to access MCE registers
x86: mce, inject: Use real inject-msg in raise_local
x86: mce: Fix thermal throttling message storm
x86: mce: Clean up thermal throttling state tracking code
x86: split NX setup into separate file to limit unstack-protected code
xen: check EFER for NX before setting up GDT mapping
x86: Cleanup linker script using new linker script macros.
x86: Use section .data.page_aligned for the idt_table.
x86: convert to use __HEAD and HEAD_TEXT macros.
x86: convert compressed loader to use __HEAD and HEAD_TEXT macros.
x86: fix fragile computation of vsyscall address
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce-inject.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 23 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/therm_throt.c | 67 | ||||
-rw-r--r-- | arch/x86/kernel/early_printk.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/head_32.S | 2 | ||||
-rw-r--r-- | arch/x86/kernel/head_64.S | 2 | ||||
-rw-r--r-- | arch/x86/kernel/traps.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/tsc_sync.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/vmlinux.lds.S | 79 |
9 files changed, 90 insertions, 103 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c index 7029f0e2acad..472763d92098 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-inject.c +++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c | |||
@@ -98,8 +98,9 @@ static struct notifier_block mce_raise_nb = { | |||
98 | }; | 98 | }; |
99 | 99 | ||
100 | /* Inject mce on current CPU */ | 100 | /* Inject mce on current CPU */ |
101 | static int raise_local(struct mce *m) | 101 | static int raise_local(void) |
102 | { | 102 | { |
103 | struct mce *m = &__get_cpu_var(injectm); | ||
103 | int context = MCJ_CTX(m->inject_flags); | 104 | int context = MCJ_CTX(m->inject_flags); |
104 | int ret = 0; | 105 | int ret = 0; |
105 | int cpu = m->extcpu; | 106 | int cpu = m->extcpu; |
@@ -167,12 +168,12 @@ static void raise_mce(struct mce *m) | |||
167 | } | 168 | } |
168 | cpu_relax(); | 169 | cpu_relax(); |
169 | } | 170 | } |
170 | raise_local(m); | 171 | raise_local(); |
171 | put_cpu(); | 172 | put_cpu(); |
172 | put_online_cpus(); | 173 | put_online_cpus(); |
173 | } else | 174 | } else |
174 | #endif | 175 | #endif |
175 | raise_local(m); | 176 | raise_local(); |
176 | } | 177 | } |
177 | 178 | ||
178 | /* Error injection interface */ | 179 | /* Error injection interface */ |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 2f5aab26320e..4b2af86e3e8d 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -305,13 +305,25 @@ static int msr_to_offset(u32 msr) | |||
305 | static u64 mce_rdmsrl(u32 msr) | 305 | static u64 mce_rdmsrl(u32 msr) |
306 | { | 306 | { |
307 | u64 v; | 307 | u64 v; |
308 | |||
308 | if (__get_cpu_var(injectm).finished) { | 309 | if (__get_cpu_var(injectm).finished) { |
309 | int offset = msr_to_offset(msr); | 310 | int offset = msr_to_offset(msr); |
311 | |||
310 | if (offset < 0) | 312 | if (offset < 0) |
311 | return 0; | 313 | return 0; |
312 | return *(u64 *)((char *)&__get_cpu_var(injectm) + offset); | 314 | return *(u64 *)((char *)&__get_cpu_var(injectm) + offset); |
313 | } | 315 | } |
314 | rdmsrl(msr, v); | 316 | |
317 | if (rdmsrl_safe(msr, &v)) { | ||
318 | WARN_ONCE(1, "mce: Unable to read msr %d!\n", msr); | ||
319 | /* | ||
320 | * Return zero in case the access faulted. This should | ||
321 | * not happen normally but can happen if the CPU does | ||
322 | * something weird, or if the code is buggy. | ||
323 | */ | ||
324 | v = 0; | ||
325 | } | ||
326 | |||
315 | return v; | 327 | return v; |
316 | } | 328 | } |
317 | 329 | ||
@@ -319,6 +331,7 @@ static void mce_wrmsrl(u32 msr, u64 v) | |||
319 | { | 331 | { |
320 | if (__get_cpu_var(injectm).finished) { | 332 | if (__get_cpu_var(injectm).finished) { |
321 | int offset = msr_to_offset(msr); | 333 | int offset = msr_to_offset(msr); |
334 | |||
322 | if (offset >= 0) | 335 | if (offset >= 0) |
323 | *(u64 *)((char *)&__get_cpu_var(injectm) + offset) = v; | 336 | *(u64 *)((char *)&__get_cpu_var(injectm) + offset) = v; |
324 | return; | 337 | return; |
@@ -415,7 +428,7 @@ static inline void mce_get_rip(struct mce *m, struct pt_regs *regs) | |||
415 | m->ip = mce_rdmsrl(rip_msr); | 428 | m->ip = mce_rdmsrl(rip_msr); |
416 | } | 429 | } |
417 | 430 | ||
418 | #ifdef CONFIG_X86_LOCAL_APIC | 431 | #ifdef CONFIG_X86_LOCAL_APIC |
419 | /* | 432 | /* |
420 | * Called after interrupts have been reenabled again | 433 | * Called after interrupts have been reenabled again |
421 | * when a MCE happened during an interrupts off region | 434 | * when a MCE happened during an interrupts off region |
@@ -1172,6 +1185,7 @@ static int mce_banks_init(void) | |||
1172 | return -ENOMEM; | 1185 | return -ENOMEM; |
1173 | for (i = 0; i < banks; i++) { | 1186 | for (i = 0; i < banks; i++) { |
1174 | struct mce_bank *b = &mce_banks[i]; | 1187 | struct mce_bank *b = &mce_banks[i]; |
1188 | |||
1175 | b->ctl = -1ULL; | 1189 | b->ctl = -1ULL; |
1176 | b->init = 1; | 1190 | b->init = 1; |
1177 | } | 1191 | } |
@@ -1203,6 +1217,7 @@ static int __cpuinit mce_cap_init(void) | |||
1203 | banks = b; | 1217 | banks = b; |
1204 | if (!mce_banks) { | 1218 | if (!mce_banks) { |
1205 | int err = mce_banks_init(); | 1219 | int err = mce_banks_init(); |
1220 | |||
1206 | if (err) | 1221 | if (err) |
1207 | return err; | 1222 | return err; |
1208 | } | 1223 | } |
@@ -1237,6 +1252,7 @@ static void mce_init(void) | |||
1237 | 1252 | ||
1238 | for (i = 0; i < banks; i++) { | 1253 | for (i = 0; i < banks; i++) { |
1239 | struct mce_bank *b = &mce_banks[i]; | 1254 | struct mce_bank *b = &mce_banks[i]; |
1255 | |||
1240 | if (!b->init) | 1256 | if (!b->init) |
1241 | continue; | 1257 | continue; |
1242 | wrmsrl(MSR_IA32_MCx_CTL(i), b->ctl); | 1258 | wrmsrl(MSR_IA32_MCx_CTL(i), b->ctl); |
@@ -1626,6 +1642,7 @@ static int mce_disable(void) | |||
1626 | 1642 | ||
1627 | for (i = 0; i < banks; i++) { | 1643 | for (i = 0; i < banks; i++) { |
1628 | struct mce_bank *b = &mce_banks[i]; | 1644 | struct mce_bank *b = &mce_banks[i]; |
1645 | |||
1629 | if (b->init) | 1646 | if (b->init) |
1630 | wrmsrl(MSR_IA32_MCx_CTL(i), 0); | 1647 | wrmsrl(MSR_IA32_MCx_CTL(i), 0); |
1631 | } | 1648 | } |
@@ -1911,6 +1928,7 @@ static void mce_disable_cpu(void *h) | |||
1911 | cmci_clear(); | 1928 | cmci_clear(); |
1912 | for (i = 0; i < banks; i++) { | 1929 | for (i = 0; i < banks; i++) { |
1913 | struct mce_bank *b = &mce_banks[i]; | 1930 | struct mce_bank *b = &mce_banks[i]; |
1931 | |||
1914 | if (b->init) | 1932 | if (b->init) |
1915 | wrmsrl(MSR_IA32_MCx_CTL(i), 0); | 1933 | wrmsrl(MSR_IA32_MCx_CTL(i), 0); |
1916 | } | 1934 | } |
@@ -1928,6 +1946,7 @@ static void mce_reenable_cpu(void *h) | |||
1928 | cmci_reenable(); | 1946 | cmci_reenable(); |
1929 | for (i = 0; i < banks; i++) { | 1947 | for (i = 0; i < banks; i++) { |
1930 | struct mce_bank *b = &mce_banks[i]; | 1948 | struct mce_bank *b = &mce_banks[i]; |
1949 | |||
1931 | if (b->init) | 1950 | if (b->init) |
1932 | wrmsrl(MSR_IA32_MCx_CTL(i), b->ctl); | 1951 | wrmsrl(MSR_IA32_MCx_CTL(i), b->ctl); |
1933 | } | 1952 | } |
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index 63a56d147e4a..b3a1dba75330 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c | |||
@@ -34,20 +34,31 @@ | |||
34 | /* How long to wait between reporting thermal events */ | 34 | /* How long to wait between reporting thermal events */ |
35 | #define CHECK_INTERVAL (300 * HZ) | 35 | #define CHECK_INTERVAL (300 * HZ) |
36 | 36 | ||
37 | static DEFINE_PER_CPU(__u64, next_check) = INITIAL_JIFFIES; | 37 | /* |
38 | static DEFINE_PER_CPU(unsigned long, thermal_throttle_count); | 38 | * Current thermal throttling state: |
39 | static DEFINE_PER_CPU(bool, thermal_throttle_active); | 39 | */ |
40 | struct thermal_state { | ||
41 | bool is_throttled; | ||
42 | |||
43 | u64 next_check; | ||
44 | unsigned long throttle_count; | ||
45 | unsigned long last_throttle_count; | ||
46 | }; | ||
47 | |||
48 | static DEFINE_PER_CPU(struct thermal_state, thermal_state); | ||
40 | 49 | ||
41 | static atomic_t therm_throt_en = ATOMIC_INIT(0); | 50 | static atomic_t therm_throt_en = ATOMIC_INIT(0); |
42 | 51 | ||
43 | #ifdef CONFIG_SYSFS | 52 | #ifdef CONFIG_SYSFS |
44 | #define define_therm_throt_sysdev_one_ro(_name) \ | 53 | #define define_therm_throt_sysdev_one_ro(_name) \ |
45 | static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL) | 54 | static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL) |
46 | 55 | ||
47 | #define define_therm_throt_sysdev_show_func(name) \ | 56 | #define define_therm_throt_sysdev_show_func(name) \ |
48 | static ssize_t therm_throt_sysdev_show_##name(struct sys_device *dev, \ | 57 | \ |
49 | struct sysdev_attribute *attr, \ | 58 | static ssize_t therm_throt_sysdev_show_##name( \ |
50 | char *buf) \ | 59 | struct sys_device *dev, \ |
60 | struct sysdev_attribute *attr, \ | ||
61 | char *buf) \ | ||
51 | { \ | 62 | { \ |
52 | unsigned int cpu = dev->id; \ | 63 | unsigned int cpu = dev->id; \ |
53 | ssize_t ret; \ | 64 | ssize_t ret; \ |
@@ -55,7 +66,7 @@ static ssize_t therm_throt_sysdev_show_##name(struct sys_device *dev, \ | |||
55 | preempt_disable(); /* CPU hotplug */ \ | 66 | preempt_disable(); /* CPU hotplug */ \ |
56 | if (cpu_online(cpu)) \ | 67 | if (cpu_online(cpu)) \ |
57 | ret = sprintf(buf, "%lu\n", \ | 68 | ret = sprintf(buf, "%lu\n", \ |
58 | per_cpu(thermal_throttle_##name, cpu)); \ | 69 | per_cpu(thermal_state, cpu).name); \ |
59 | else \ | 70 | else \ |
60 | ret = 0; \ | 71 | ret = 0; \ |
61 | preempt_enable(); \ | 72 | preempt_enable(); \ |
@@ -63,11 +74,11 @@ static ssize_t therm_throt_sysdev_show_##name(struct sys_device *dev, \ | |||
63 | return ret; \ | 74 | return ret; \ |
64 | } | 75 | } |
65 | 76 | ||
66 | define_therm_throt_sysdev_show_func(count); | 77 | define_therm_throt_sysdev_show_func(throttle_count); |
67 | define_therm_throt_sysdev_one_ro(count); | 78 | define_therm_throt_sysdev_one_ro(throttle_count); |
68 | 79 | ||
69 | static struct attribute *thermal_throttle_attrs[] = { | 80 | static struct attribute *thermal_throttle_attrs[] = { |
70 | &attr_count.attr, | 81 | &attr_throttle_count.attr, |
71 | NULL | 82 | NULL |
72 | }; | 83 | }; |
73 | 84 | ||
@@ -93,33 +104,39 @@ static struct attribute_group thermal_throttle_attr_group = { | |||
93 | * 1 : Event should be logged further, and a message has been | 104 | * 1 : Event should be logged further, and a message has been |
94 | * printed to the syslog. | 105 | * printed to the syslog. |
95 | */ | 106 | */ |
96 | static int therm_throt_process(int curr) | 107 | static int therm_throt_process(bool is_throttled) |
97 | { | 108 | { |
98 | unsigned int cpu = smp_processor_id(); | 109 | struct thermal_state *state; |
99 | __u64 tmp_jiffs = get_jiffies_64(); | 110 | unsigned int this_cpu; |
100 | bool was_throttled = __get_cpu_var(thermal_throttle_active); | 111 | bool was_throttled; |
101 | bool is_throttled = __get_cpu_var(thermal_throttle_active) = curr; | 112 | u64 now; |
113 | |||
114 | this_cpu = smp_processor_id(); | ||
115 | now = get_jiffies_64(); | ||
116 | state = &per_cpu(thermal_state, this_cpu); | ||
117 | |||
118 | was_throttled = state->is_throttled; | ||
119 | state->is_throttled = is_throttled; | ||
102 | 120 | ||
103 | if (is_throttled) | 121 | if (is_throttled) |
104 | __get_cpu_var(thermal_throttle_count)++; | 122 | state->throttle_count++; |
105 | 123 | ||
106 | if (!(was_throttled ^ is_throttled) && | 124 | if (time_before64(now, state->next_check) && |
107 | time_before64(tmp_jiffs, __get_cpu_var(next_check))) | 125 | state->throttle_count != state->last_throttle_count) |
108 | return 0; | 126 | return 0; |
109 | 127 | ||
110 | __get_cpu_var(next_check) = tmp_jiffs + CHECK_INTERVAL; | 128 | state->next_check = now + CHECK_INTERVAL; |
129 | state->last_throttle_count = state->throttle_count; | ||
111 | 130 | ||
112 | /* if we just entered the thermal event */ | 131 | /* if we just entered the thermal event */ |
113 | if (is_throttled) { | 132 | if (is_throttled) { |
114 | printk(KERN_CRIT "CPU%d: Temperature above threshold, " | 133 | printk(KERN_CRIT "CPU%d: Temperature above threshold, cpu clock throttled (total events = %lu)\n", this_cpu, state->throttle_count); |
115 | "cpu clock throttled (total events = %lu)\n", | ||
116 | cpu, __get_cpu_var(thermal_throttle_count)); | ||
117 | 134 | ||
118 | add_taint(TAINT_MACHINE_CHECK); | 135 | add_taint(TAINT_MACHINE_CHECK); |
119 | return 1; | 136 | return 1; |
120 | } | 137 | } |
121 | if (was_throttled) { | 138 | if (was_throttled) { |
122 | printk(KERN_INFO "CPU%d: Temperature/speed normal\n", cpu); | 139 | printk(KERN_INFO "CPU%d: Temperature/speed normal\n", this_cpu); |
123 | return 1; | 140 | return 1; |
124 | } | 141 | } |
125 | 142 | ||
@@ -213,7 +230,7 @@ static void intel_thermal_interrupt(void) | |||
213 | __u64 msr_val; | 230 | __u64 msr_val; |
214 | 231 | ||
215 | rdmsrl(MSR_IA32_THERM_STATUS, msr_val); | 232 | rdmsrl(MSR_IA32_THERM_STATUS, msr_val); |
216 | if (therm_throt_process(msr_val & THERM_STATUS_PROCHOT)) | 233 | if (therm_throt_process((msr_val & THERM_STATUS_PROCHOT) != 0)) |
217 | mce_log_therm_throt_event(msr_val); | 234 | mce_log_therm_throt_event(msr_val); |
218 | } | 235 | } |
219 | 236 | ||
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 2acfd3fdc0cc..41fd965c80c6 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c | |||
@@ -178,6 +178,11 @@ asmlinkage void early_printk(const char *fmt, ...) | |||
178 | 178 | ||
179 | static inline void early_console_register(struct console *con, int keep_early) | 179 | static inline void early_console_register(struct console *con, int keep_early) |
180 | { | 180 | { |
181 | if (early_console->index != -1) { | ||
182 | printk(KERN_CRIT "ERROR: earlyprintk= %s already used\n", | ||
183 | con->name); | ||
184 | return; | ||
185 | } | ||
181 | early_console = con; | 186 | early_console = con; |
182 | if (keep_early) | 187 | if (keep_early) |
183 | early_console->flags &= ~CON_BOOT; | 188 | early_console->flags &= ~CON_BOOT; |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 218aad7ee76e..050c278481b1 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -79,7 +79,7 @@ RESERVE_BRK(pagetables, INIT_MAP_SIZE) | |||
79 | * any particular GDT layout, because we load our own as soon as we | 79 | * any particular GDT layout, because we load our own as soon as we |
80 | * can. | 80 | * can. |
81 | */ | 81 | */ |
82 | .section .text.head,"ax",@progbits | 82 | __HEAD |
83 | ENTRY(startup_32) | 83 | ENTRY(startup_32) |
84 | /* test KEEP_SEGMENTS flag to see if the bootloader is asking | 84 | /* test KEEP_SEGMENTS flag to see if the bootloader is asking |
85 | us to not reload segments */ | 85 | us to not reload segments */ |
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index d0bc0a13a437..780cd928fcd5 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S | |||
@@ -40,7 +40,7 @@ L4_START_KERNEL = pgd_index(__START_KERNEL_map) | |||
40 | L3_START_KERNEL = pud_index(__START_KERNEL_map) | 40 | L3_START_KERNEL = pud_index(__START_KERNEL_map) |
41 | 41 | ||
42 | .text | 42 | .text |
43 | .section .text.head | 43 | __HEAD |
44 | .code64 | 44 | .code64 |
45 | .globl startup_64 | 45 | .globl startup_64 |
46 | startup_64: | 46 | startup_64: |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index a665c71352b8..7e37dcee0cc3 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -72,11 +72,9 @@ char ignore_fpu_irq; | |||
72 | 72 | ||
73 | /* | 73 | /* |
74 | * The IDT has to be page-aligned to simplify the Pentium | 74 | * The IDT has to be page-aligned to simplify the Pentium |
75 | * F0 0F bug workaround.. We have a special link segment | 75 | * F0 0F bug workaround. |
76 | * for this. | ||
77 | */ | 76 | */ |
78 | gate_desc idt_table[NR_VECTORS] | 77 | gate_desc idt_table[NR_VECTORS] __page_aligned_data = { { { { 0, 0 } } }, }; |
79 | __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; | ||
80 | #endif | 78 | #endif |
81 | 79 | ||
82 | DECLARE_BITMAP(used_vectors, NR_VECTORS); | 80 | DECLARE_BITMAP(used_vectors, NR_VECTORS); |
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c index 027b5b498993..f37930954d15 100644 --- a/arch/x86/kernel/tsc_sync.c +++ b/arch/x86/kernel/tsc_sync.c | |||
@@ -114,7 +114,7 @@ void __cpuinit check_tsc_sync_source(int cpu) | |||
114 | return; | 114 | return; |
115 | 115 | ||
116 | if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) { | 116 | if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) { |
117 | pr_info("Skipping synchronization checks as TSC is reliable.\n"); | 117 | printk_once(KERN_INFO "Skipping synchronization checks as TSC is reliable.\n"); |
118 | return; | 118 | return; |
119 | } | 119 | } |
120 | 120 | ||
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index a46acccec38a..92929fb3f9fa 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S | |||
@@ -65,17 +65,11 @@ SECTIONS | |||
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | /* Text and read-only data */ | 67 | /* Text and read-only data */ |
68 | |||
69 | /* bootstrapping code */ | ||
70 | .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) { | ||
71 | _text = .; | ||
72 | *(.text.head) | ||
73 | } :text = 0x9090 | ||
74 | |||
75 | /* The rest of the text */ | ||
76 | .text : AT(ADDR(.text) - LOAD_OFFSET) { | 68 | .text : AT(ADDR(.text) - LOAD_OFFSET) { |
69 | _text = .; | ||
70 | /* bootstrapping code */ | ||
71 | HEAD_TEXT | ||
77 | #ifdef CONFIG_X86_32 | 72 | #ifdef CONFIG_X86_32 |
78 | /* not really needed, already page aligned */ | ||
79 | . = ALIGN(PAGE_SIZE); | 73 | . = ALIGN(PAGE_SIZE); |
80 | *(.text.page_aligned) | 74 | *(.text.page_aligned) |
81 | #endif | 75 | #endif |
@@ -94,13 +88,7 @@ SECTIONS | |||
94 | 88 | ||
95 | NOTES :text :note | 89 | NOTES :text :note |
96 | 90 | ||
97 | /* Exception table */ | 91 | EXCEPTION_TABLE(16) :text = 0x9090 |
98 | . = ALIGN(16); | ||
99 | __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { | ||
100 | __start___ex_table = .; | ||
101 | *(__ex_table) | ||
102 | __stop___ex_table = .; | ||
103 | } :text = 0x9090 | ||
104 | 92 | ||
105 | RO_DATA(PAGE_SIZE) | 93 | RO_DATA(PAGE_SIZE) |
106 | 94 | ||
@@ -118,7 +106,6 @@ SECTIONS | |||
118 | #endif | 106 | #endif |
119 | 107 | ||
120 | PAGE_ALIGNED_DATA(PAGE_SIZE) | 108 | PAGE_ALIGNED_DATA(PAGE_SIZE) |
121 | *(.data.idt) | ||
122 | 109 | ||
123 | CACHELINE_ALIGNED_DATA(CONFIG_X86_L1_CACHE_BYTES) | 110 | CACHELINE_ALIGNED_DATA(CONFIG_X86_L1_CACHE_BYTES) |
124 | 111 | ||
@@ -135,24 +122,21 @@ SECTIONS | |||
135 | #ifdef CONFIG_X86_64 | 122 | #ifdef CONFIG_X86_64 |
136 | 123 | ||
137 | #define VSYSCALL_ADDR (-10*1024*1024) | 124 | #define VSYSCALL_ADDR (-10*1024*1024) |
138 | #define VSYSCALL_PHYS_ADDR ((LOADADDR(.data) + SIZEOF(.data) + \ | ||
139 | PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) | ||
140 | #define VSYSCALL_VIRT_ADDR ((ADDR(.data) + SIZEOF(.data) + \ | ||
141 | PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) | ||
142 | 125 | ||
143 | #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR) | 126 | #define VLOAD_OFFSET (VSYSCALL_ADDR - __vsyscall_0 + LOAD_OFFSET) |
144 | #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET) | 127 | #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET) |
145 | 128 | ||
146 | #define VVIRT_OFFSET (VSYSCALL_ADDR - VSYSCALL_VIRT_ADDR) | 129 | #define VVIRT_OFFSET (VSYSCALL_ADDR - __vsyscall_0) |
147 | #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET) | 130 | #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET) |
148 | 131 | ||
132 | . = ALIGN(4096); | ||
133 | __vsyscall_0 = .; | ||
134 | |||
149 | . = VSYSCALL_ADDR; | 135 | . = VSYSCALL_ADDR; |
150 | .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) { | 136 | .vsyscall_0 : AT(VLOAD(.vsyscall_0)) { |
151 | *(.vsyscall_0) | 137 | *(.vsyscall_0) |
152 | } :user | 138 | } :user |
153 | 139 | ||
154 | __vsyscall_0 = VSYSCALL_VIRT_ADDR; | ||
155 | |||
156 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); | 140 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); |
157 | .vsyscall_fn : AT(VLOAD(.vsyscall_fn)) { | 141 | .vsyscall_fn : AT(VLOAD(.vsyscall_fn)) { |
158 | *(.vsyscall_fn) | 142 | *(.vsyscall_fn) |
@@ -192,11 +176,9 @@ SECTIONS | |||
192 | *(.vsyscall_3) | 176 | *(.vsyscall_3) |
193 | } | 177 | } |
194 | 178 | ||
195 | . = VSYSCALL_VIRT_ADDR + PAGE_SIZE; | 179 | . = __vsyscall_0 + PAGE_SIZE; |
196 | 180 | ||
197 | #undef VSYSCALL_ADDR | 181 | #undef VSYSCALL_ADDR |
198 | #undef VSYSCALL_PHYS_ADDR | ||
199 | #undef VSYSCALL_VIRT_ADDR | ||
200 | #undef VLOAD_OFFSET | 182 | #undef VLOAD_OFFSET |
201 | #undef VLOAD | 183 | #undef VLOAD |
202 | #undef VVIRT_OFFSET | 184 | #undef VVIRT_OFFSET |
@@ -219,36 +201,12 @@ SECTIONS | |||
219 | PERCPU_VADDR(0, :percpu) | 201 | PERCPU_VADDR(0, :percpu) |
220 | #endif | 202 | #endif |
221 | 203 | ||
222 | .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { | 204 | INIT_TEXT_SECTION(PAGE_SIZE) |
223 | _sinittext = .; | ||
224 | INIT_TEXT | ||
225 | _einittext = .; | ||
226 | } | ||
227 | #ifdef CONFIG_X86_64 | 205 | #ifdef CONFIG_X86_64 |
228 | :init | 206 | :init |
229 | #endif | 207 | #endif |
230 | 208 | ||
231 | .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { | 209 | INIT_DATA_SECTION(16) |
232 | INIT_DATA | ||
233 | } | ||
234 | |||
235 | . = ALIGN(16); | ||
236 | .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { | ||
237 | __setup_start = .; | ||
238 | *(.init.setup) | ||
239 | __setup_end = .; | ||
240 | } | ||
241 | .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { | ||
242 | __initcall_start = .; | ||
243 | INITCALLS | ||
244 | __initcall_end = .; | ||
245 | } | ||
246 | |||
247 | .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { | ||
248 | __con_initcall_start = .; | ||
249 | *(.con_initcall.init) | ||
250 | __con_initcall_end = .; | ||
251 | } | ||
252 | 210 | ||
253 | .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) { | 211 | .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) { |
254 | __x86_cpu_dev_start = .; | 212 | __x86_cpu_dev_start = .; |
@@ -256,8 +214,6 @@ SECTIONS | |||
256 | __x86_cpu_dev_end = .; | 214 | __x86_cpu_dev_end = .; |
257 | } | 215 | } |
258 | 216 | ||
259 | SECURITY_INIT | ||
260 | |||
261 | . = ALIGN(8); | 217 | . = ALIGN(8); |
262 | .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { | 218 | .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { |
263 | __parainstructions = .; | 219 | __parainstructions = .; |
@@ -288,15 +244,6 @@ SECTIONS | |||
288 | EXIT_DATA | 244 | EXIT_DATA |
289 | } | 245 | } |
290 | 246 | ||
291 | #ifdef CONFIG_BLK_DEV_INITRD | ||
292 | . = ALIGN(PAGE_SIZE); | ||
293 | .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { | ||
294 | __initramfs_start = .; | ||
295 | *(.init.ramfs) | ||
296 | __initramfs_end = .; | ||
297 | } | ||
298 | #endif | ||
299 | |||
300 | #if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP) | 247 | #if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP) |
301 | PERCPU(PAGE_SIZE) | 248 | PERCPU(PAGE_SIZE) |
302 | #endif | 249 | #endif |