diff options
| -rw-r--r-- | arch/x86/boot/compressed/head_32.S | 3 | ||||
| -rw-r--r-- | arch/x86/boot/compressed/head_64.S | 3 | ||||
| -rw-r--r-- | arch/x86/boot/compressed/vmlinux.lds.S | 6 | ||||
| -rw-r--r-- | arch/x86/include/asm/pgtable_types.h | 1 | ||||
| -rw-r--r-- | arch/x86/include/asm/topology.h | 10 | ||||
| -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 | ||||
| -rw-r--r-- | arch/x86/mm/Makefile | 3 | ||||
| -rw-r--r-- | arch/x86/mm/init.c | 63 | ||||
| -rw-r--r-- | arch/x86/mm/pat.c | 7 | ||||
| -rw-r--r-- | arch/x86/mm/setup_nx.c | 69 | ||||
| -rw-r--r-- | arch/x86/xen/enlighten.c | 10 |
19 files changed, 180 insertions, 188 deletions
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index 75e4f001e706..f543b70ffae2 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S | |||
| @@ -23,13 +23,14 @@ | |||
| 23 | */ | 23 | */ |
| 24 | .text | 24 | .text |
| 25 | 25 | ||
| 26 | #include <linux/init.h> | ||
| 26 | #include <linux/linkage.h> | 27 | #include <linux/linkage.h> |
| 27 | #include <asm/segment.h> | 28 | #include <asm/segment.h> |
| 28 | #include <asm/page_types.h> | 29 | #include <asm/page_types.h> |
| 29 | #include <asm/boot.h> | 30 | #include <asm/boot.h> |
| 30 | #include <asm/asm-offsets.h> | 31 | #include <asm/asm-offsets.h> |
| 31 | 32 | ||
| 32 | .section ".text.head","ax",@progbits | 33 | __HEAD |
| 33 | ENTRY(startup_32) | 34 | ENTRY(startup_32) |
| 34 | cld | 35 | cld |
| 35 | /* | 36 | /* |
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index f62c284db9eb..077e1b69198e 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | .code32 | 24 | .code32 |
| 25 | .text | 25 | .text |
| 26 | 26 | ||
| 27 | #include <linux/init.h> | ||
| 27 | #include <linux/linkage.h> | 28 | #include <linux/linkage.h> |
| 28 | #include <asm/segment.h> | 29 | #include <asm/segment.h> |
| 29 | #include <asm/pgtable_types.h> | 30 | #include <asm/pgtable_types.h> |
| @@ -33,7 +34,7 @@ | |||
| 33 | #include <asm/processor-flags.h> | 34 | #include <asm/processor-flags.h> |
| 34 | #include <asm/asm-offsets.h> | 35 | #include <asm/asm-offsets.h> |
| 35 | 36 | ||
| 36 | .section ".text.head" | 37 | __HEAD |
| 37 | .code32 | 38 | .code32 |
| 38 | ENTRY(startup_32) | 39 | ENTRY(startup_32) |
| 39 | cld | 40 | cld |
diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S index cc353e1b3ffd..f4193bb48782 100644 --- a/arch/x86/boot/compressed/vmlinux.lds.S +++ b/arch/x86/boot/compressed/vmlinux.lds.S | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | #include <asm-generic/vmlinux.lds.h> | ||
| 2 | |||
| 1 | OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT) | 3 | OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT) |
| 2 | 4 | ||
| 3 | #undef i386 | 5 | #undef i386 |
| @@ -18,9 +20,9 @@ SECTIONS | |||
| 18 | * address 0. | 20 | * address 0. |
| 19 | */ | 21 | */ |
| 20 | . = 0; | 22 | . = 0; |
| 21 | .text.head : { | 23 | .head.text : { |
| 22 | _head = . ; | 24 | _head = . ; |
| 23 | *(.text.head) | 25 | HEAD_TEXT |
| 24 | _ehead = . ; | 26 | _ehead = . ; |
| 25 | } | 27 | } |
| 26 | .rodata.compressed : { | 28 | .rodata.compressed : { |
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index 7b467bf3c680..d1f4a760be23 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h | |||
| @@ -277,6 +277,7 @@ static inline pteval_t pte_flags(pte_t pte) | |||
| 277 | typedef struct page *pgtable_t; | 277 | typedef struct page *pgtable_t; |
| 278 | 278 | ||
| 279 | extern pteval_t __supported_pte_mask; | 279 | extern pteval_t __supported_pte_mask; |
| 280 | extern void set_nx(void); | ||
| 280 | extern int nx_enabled; | 281 | extern int nx_enabled; |
| 281 | 282 | ||
| 282 | #define pgprot_writecombine pgprot_writecombine | 283 | #define pgprot_writecombine pgprot_writecombine |
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 6f0695d744bf..25a92842dd99 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h | |||
| @@ -165,21 +165,11 @@ static inline int numa_node_id(void) | |||
| 165 | return 0; | 165 | return 0; |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | static inline int cpu_to_node(int cpu) | ||
| 169 | { | ||
| 170 | return 0; | ||
| 171 | } | ||
| 172 | |||
| 173 | static inline int early_cpu_to_node(int cpu) | 168 | static inline int early_cpu_to_node(int cpu) |
| 174 | { | 169 | { |
| 175 | return 0; | 170 | return 0; |
| 176 | } | 171 | } |
| 177 | 172 | ||
| 178 | static inline const struct cpumask *cpumask_of_node(int node) | ||
| 179 | { | ||
| 180 | return cpu_online_mask; | ||
| 181 | } | ||
| 182 | |||
| 183 | static inline void setup_node_to_cpumask_map(void) { } | 173 | static inline void setup_node_to_cpumask_map(void) { } |
| 184 | 174 | ||
| 185 | #endif | 175 | #endif |
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 |
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index 9b5a9f59a478..06630d26e56d 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ | 1 | obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ |
| 2 | pat.o pgtable.o physaddr.o gup.o | 2 | pat.o pgtable.o physaddr.o gup.o setup_nx.o |
| 3 | 3 | ||
| 4 | # Make sure __phys_addr has no stackprotector | 4 | # Make sure __phys_addr has no stackprotector |
| 5 | nostackp := $(call cc-option, -fno-stack-protector) | 5 | nostackp := $(call cc-option, -fno-stack-protector) |
| 6 | CFLAGS_physaddr.o := $(nostackp) | 6 | CFLAGS_physaddr.o := $(nostackp) |
| 7 | CFLAGS_setup_nx.o := $(nostackp) | ||
| 7 | 8 | ||
| 8 | obj-$(CONFIG_SMP) += tlb.o | 9 | obj-$(CONFIG_SMP) += tlb.o |
| 9 | 10 | ||
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 0607119cef94..73ffd5536f62 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
| @@ -28,69 +28,6 @@ int direct_gbpages | |||
| 28 | #endif | 28 | #endif |
| 29 | ; | 29 | ; |
| 30 | 30 | ||
| 31 | int nx_enabled; | ||
| 32 | |||
| 33 | #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) | ||
| 34 | static int disable_nx __cpuinitdata; | ||
| 35 | |||
| 36 | /* | ||
| 37 | * noexec = on|off | ||
| 38 | * | ||
| 39 | * Control non-executable mappings for processes. | ||
| 40 | * | ||
| 41 | * on Enable | ||
| 42 | * off Disable | ||
| 43 | */ | ||
| 44 | static int __init noexec_setup(char *str) | ||
| 45 | { | ||
| 46 | if (!str) | ||
| 47 | return -EINVAL; | ||
| 48 | if (!strncmp(str, "on", 2)) { | ||
| 49 | __supported_pte_mask |= _PAGE_NX; | ||
| 50 | disable_nx = 0; | ||
| 51 | } else if (!strncmp(str, "off", 3)) { | ||
| 52 | disable_nx = 1; | ||
| 53 | __supported_pte_mask &= ~_PAGE_NX; | ||
| 54 | } | ||
| 55 | return 0; | ||
| 56 | } | ||
| 57 | early_param("noexec", noexec_setup); | ||
| 58 | #endif | ||
| 59 | |||
| 60 | #ifdef CONFIG_X86_PAE | ||
| 61 | static void __init set_nx(void) | ||
| 62 | { | ||
| 63 | unsigned int v[4], l, h; | ||
| 64 | |||
| 65 | if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) { | ||
| 66 | cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]); | ||
| 67 | |||
| 68 | if ((v[3] & (1 << 20)) && !disable_nx) { | ||
| 69 | rdmsr(MSR_EFER, l, h); | ||
| 70 | l |= EFER_NX; | ||
| 71 | wrmsr(MSR_EFER, l, h); | ||
| 72 | nx_enabled = 1; | ||
| 73 | __supported_pte_mask |= _PAGE_NX; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | } | ||
| 77 | #else | ||
| 78 | static inline void set_nx(void) | ||
| 79 | { | ||
| 80 | } | ||
| 81 | #endif | ||
| 82 | |||
| 83 | #ifdef CONFIG_X86_64 | ||
| 84 | void __cpuinit check_efer(void) | ||
| 85 | { | ||
| 86 | unsigned long efer; | ||
| 87 | |||
| 88 | rdmsrl(MSR_EFER, efer); | ||
| 89 | if (!(efer & EFER_NX) || disable_nx) | ||
| 90 | __supported_pte_mask &= ~_PAGE_NX; | ||
| 91 | } | ||
| 92 | #endif | ||
| 93 | |||
| 94 | static void __init find_early_table_space(unsigned long end, int use_pse, | 31 | static void __init find_early_table_space(unsigned long end, int use_pse, |
| 95 | int use_gbpages) | 32 | int use_gbpages) |
| 96 | { | 33 | { |
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 7257cf3decf9..e78cd0ec2bcf 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
| @@ -81,6 +81,7 @@ enum { | |||
| 81 | void pat_init(void) | 81 | void pat_init(void) |
| 82 | { | 82 | { |
| 83 | u64 pat; | 83 | u64 pat; |
| 84 | bool boot_cpu = !boot_pat_state; | ||
| 84 | 85 | ||
| 85 | if (!pat_enabled) | 86 | if (!pat_enabled) |
| 86 | return; | 87 | return; |
| @@ -122,8 +123,10 @@ void pat_init(void) | |||
| 122 | rdmsrl(MSR_IA32_CR_PAT, boot_pat_state); | 123 | rdmsrl(MSR_IA32_CR_PAT, boot_pat_state); |
| 123 | 124 | ||
| 124 | wrmsrl(MSR_IA32_CR_PAT, pat); | 125 | wrmsrl(MSR_IA32_CR_PAT, pat); |
| 125 | printk(KERN_INFO "x86 PAT enabled: cpu %d, old 0x%Lx, new 0x%Lx\n", | 126 | |
| 126 | smp_processor_id(), boot_pat_state, pat); | 127 | if (boot_cpu) |
| 128 | printk(KERN_INFO "x86 PAT enabled: cpu %d, old 0x%Lx, new 0x%Lx\n", | ||
| 129 | smp_processor_id(), boot_pat_state, pat); | ||
| 127 | } | 130 | } |
| 128 | 131 | ||
| 129 | #undef PAT | 132 | #undef PAT |
diff --git a/arch/x86/mm/setup_nx.c b/arch/x86/mm/setup_nx.c new file mode 100644 index 000000000000..513d8ed5d2ec --- /dev/null +++ b/arch/x86/mm/setup_nx.c | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | #include <linux/spinlock.h> | ||
| 2 | #include <linux/errno.h> | ||
| 3 | #include <linux/init.h> | ||
| 4 | |||
| 5 | #include <asm/pgtable.h> | ||
| 6 | |||
| 7 | int nx_enabled; | ||
| 8 | |||
| 9 | #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) | ||
| 10 | static int disable_nx __cpuinitdata; | ||
| 11 | |||
| 12 | /* | ||
| 13 | * noexec = on|off | ||
| 14 | * | ||
| 15 | * Control non-executable mappings for processes. | ||
| 16 | * | ||
| 17 | * on Enable | ||
| 18 | * off Disable | ||
| 19 | */ | ||
| 20 | static int __init noexec_setup(char *str) | ||
| 21 | { | ||
| 22 | if (!str) | ||
| 23 | return -EINVAL; | ||
| 24 | if (!strncmp(str, "on", 2)) { | ||
| 25 | __supported_pte_mask |= _PAGE_NX; | ||
| 26 | disable_nx = 0; | ||
| 27 | } else if (!strncmp(str, "off", 3)) { | ||
| 28 | disable_nx = 1; | ||
| 29 | __supported_pte_mask &= ~_PAGE_NX; | ||
| 30 | } | ||
| 31 | return 0; | ||
| 32 | } | ||
| 33 | early_param("noexec", noexec_setup); | ||
| 34 | #endif | ||
| 35 | |||
| 36 | #ifdef CONFIG_X86_PAE | ||
| 37 | void __init set_nx(void) | ||
| 38 | { | ||
| 39 | unsigned int v[4], l, h; | ||
| 40 | |||
| 41 | if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) { | ||
| 42 | cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]); | ||
| 43 | |||
| 44 | if ((v[3] & (1 << 20)) && !disable_nx) { | ||
| 45 | rdmsr(MSR_EFER, l, h); | ||
| 46 | l |= EFER_NX; | ||
| 47 | wrmsr(MSR_EFER, l, h); | ||
| 48 | nx_enabled = 1; | ||
| 49 | __supported_pte_mask |= _PAGE_NX; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | } | ||
| 53 | #else | ||
| 54 | void set_nx(void) | ||
| 55 | { | ||
| 56 | } | ||
| 57 | #endif | ||
| 58 | |||
| 59 | #ifdef CONFIG_X86_64 | ||
| 60 | void __cpuinit check_efer(void) | ||
| 61 | { | ||
| 62 | unsigned long efer; | ||
| 63 | |||
| 64 | rdmsrl(MSR_EFER, efer); | ||
| 65 | if (!(efer & EFER_NX) || disable_nx) | ||
| 66 | __supported_pte_mask &= ~_PAGE_NX; | ||
| 67 | } | ||
| 68 | #endif | ||
| 69 | |||
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 544eb7496531..3439616d69f1 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
| @@ -1082,6 +1082,11 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 1082 | 1082 | ||
| 1083 | __supported_pte_mask |= _PAGE_IOMAP; | 1083 | __supported_pte_mask |= _PAGE_IOMAP; |
| 1084 | 1084 | ||
| 1085 | #ifdef CONFIG_X86_64 | ||
| 1086 | /* Work out if we support NX */ | ||
| 1087 | check_efer(); | ||
| 1088 | #endif | ||
| 1089 | |||
| 1085 | xen_setup_features(); | 1090 | xen_setup_features(); |
| 1086 | 1091 | ||
| 1087 | /* Get mfn list */ | 1092 | /* Get mfn list */ |
| @@ -1123,11 +1128,6 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 1123 | 1128 | ||
| 1124 | pgd = (pgd_t *)xen_start_info->pt_base; | 1129 | pgd = (pgd_t *)xen_start_info->pt_base; |
| 1125 | 1130 | ||
| 1126 | #ifdef CONFIG_X86_64 | ||
| 1127 | /* Work out if we support NX */ | ||
| 1128 | check_efer(); | ||
| 1129 | #endif | ||
| 1130 | |||
| 1131 | /* Don't do the full vcpu_info placement stuff until we have a | 1131 | /* Don't do the full vcpu_info placement stuff until we have a |
| 1132 | possible map and a non-dummy shared_info. */ | 1132 | possible map and a non-dummy shared_info. */ |
| 1133 | per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; | 1133 | per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; |
