Pull x86 fixes from Thomas Gleixner: "A couple of fixes and updates related to x86: - Fix the W+X check regression on XEN - The real fix for the low identity map trainwreck - Probe legacy PIC early instead of unconditionally allocating legacy irqs - Add cpu verification to long mode entry - Adjust the cache topology to AMD Fam17H systems - Let Merrifield use the TSC across S3" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/cpu: Call verify_cpu() after having entered long mode too x86/setup: Fix low identity map for >= 2GB kernel range x86/mm: Skip the hypervisor range when walking PGD x86/AMD: Fix last level cache topology for AMD Fam17h systems x86/irq: Probe for PIC presence before allocating descs for legacy IRQs x86/cpu/intel: Enable X86_FEATURE_NONSTOP_TSC_S3 for Merrifield
Unified · Split
| @@ -60,6 +60,7 @@ struct legacy_pic { · 59 unmodified lines | ||
| 60 | 60 | void (*mask_all)(void); |
| 61 | 61 | void (*restore_mask)(void); |
| 62 | 62 | void (*init)(int auto_eoi); |
| 63 | + int (*probe)(void); | |
| 63 | 64 | int (*irq_pending)(unsigned int irq); |
| 64 | 65 | void (*make_irq)(unsigned int irq); |
| 65 | 66 | }; |
| @@ -361,7 +361,11 @@ int __init arch_probe_nr_irqs(void) · 360 unmodified lines | ||
| 361 | 361 | if (nr < nr_irqs) |
| 362 | 362 | nr_irqs = nr; |
| 363 | 363 | |
| 364 | − return nr_legacy_irqs(); | |
| 364 | + /* | |
| 365 | + * We don't know if PIC is present at this point so we need to do | |
| 366 | + * probe() to get the right number of legacy IRQs. | |
| 367 | + */ | |
| 368 | + return legacy_pic->probe(); | |
| 365 | 369 | } |
| 366 | 370 | |
| 367 | 371 | #ifdef CONFIG_X86_IO_APIC |
| @@ -352,6 +352,7 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c) · 351 unmodified lines | ||
| 352 | 352 | #ifdef CONFIG_SMP |
| 353 | 353 | unsigned bits; |
| 354 | 354 | int cpu = smp_processor_id(); |
| 355 | + unsigned int socket_id, core_complex_id; | |
| 355 | 356 | |
| 356 | 357 | bits = c->x86_coreid_bits; |
| 357 | 358 | /* Low order bits define the core id (index of core in socket) */ |
| @@ -361,6 +362,18 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c) · 3 unmodified lines | ||
| 361 | 362 | /* use socket ID also for last level cache */ |
| 362 | 363 | per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; |
| 363 | 364 | amd_get_topology(c); |
| 365 | + | |
| 366 | + /* | |
| 367 | + * Fix percpu cpu_llc_id here as LLC topology is different | |
| 368 | + * for Fam17h systems. | |
| 369 | + */ | |
| 370 | + if (c->x86 != 0x17 || !cpuid_edx(0x80000006)) | |
| 371 | + return; | |
| 372 | + | |
| 373 | + socket_id = (c->apicid >> bits) - 1; | |
| 374 | + core_complex_id = (c->apicid & ((1 << bits) - 1)) >> 3; | |
| 375 | + | |
| 376 | + per_cpu(cpu_llc_id, cpu) = (socket_id << 3) | core_complex_id; | |
| 364 | 377 | #endif |
| 365 | 378 | } |
| 366 | 379 | |
| @@ -97,6 +97,7 @@ static void early_init_intel(struct cpuinfo_x86 *c) · 96 unmodified lines | ||
| 97 | 97 | switch (c->x86_model) { |
| 98 | 98 | case 0x27: /* Penwell */ |
| 99 | 99 | case 0x35: /* Cloverview */ |
| 100 | + case 0x4a: /* Merrifield */ | |
| 100 | 101 | set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC_S3); |
| 101 | 102 | break; |
| 102 | 103 | default: |
| @@ -65,6 +65,9 @@ startup_64: · 64 unmodified lines | ||
| 65 | 65 | * tables and then reload them. |
| 66 | 66 | */ |
| 67 | 67 | |
| 68 | + /* Sanitize CPU configuration */ | |
| 69 | + call verify_cpu | |
| 70 | + | |
| 68 | 71 | /* |
| 69 | 72 | * Compute the delta between the address I am compiled to run at and the |
| 70 | 73 | * address I am actually running at. |
| @@ -174,6 +177,9 @@ ENTRY(secondary_startup_64) · 103 unmodified lines | ||
| 174 | 177 | * after the boot processor executes this code. |
| 175 | 178 | */ |
| 176 | 179 | |
| 180 | + /* Sanitize CPU configuration */ | |
| 181 | + call verify_cpu | |
| 182 | + | |
| 177 | 183 | movq $(init_level4_pgt - __START_KERNEL_map), %rax |
| 178 | 184 | 1: |
| 179 | 185 | |
| @@ -288,6 +294,8 @@ ENTRY(secondary_startup_64) · 108 unmodified lines | ||
| 288 | 294 | pushq %rax # target address in negative space |
| 289 | 295 | lretq |
| 290 | 296 | |
| 297 | +#include "verify_cpu.S" | |
| 298 | + | |
| 291 | 299 | #ifdef CONFIG_HOTPLUG_CPU |
| 292 | 300 | /* |
| 293 | 301 | * Boot CPU0 entry point. It's called from play_dead(). Everything has been set |
| @@ -295,16 +295,11 @@ static void unmask_8259A(void) · 294 unmodified lines | ||
| 295 | 295 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
| 296 | 296 | } |
| 297 | 297 | |
| 298 | −static void init_8259A(int auto_eoi) | |
| 298 | +static int probe_8259A(void) | |
| 299 | 299 | { |
| 300 | 300 | unsigned long flags; |
| 301 | 301 | unsigned char probe_val = ~(1 << PIC_CASCADE_IR); |
| 302 | 302 | unsigned char new_val; |
| 303 | − | |
| 304 | − i8259A_auto_eoi = auto_eoi; | |
| 305 | − | |
| 306 | − raw_spin_lock_irqsave(&i8259A_lock, flags); | |
| 307 | − | |
| 308 | 303 | /* |
| 309 | 304 | * Check to see if we have a PIC. |
| 310 | 305 | * Mask all except the cascade and read |
| @@ -312,16 +307,28 @@ static void init_8259A(int auto_eoi) · 1 unmodified line | ||
| 312 | 307 | * have a PIC, we will read 0xff as opposed to the |
| 313 | 308 | * value we wrote. |
| 314 | 309 | */ |
| 310 | + raw_spin_lock_irqsave(&i8259A_lock, flags); | |
| 311 | + | |
| 315 | 312 | outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ |
| 316 | 313 | outb(probe_val, PIC_MASTER_IMR); |
| 317 | 314 | new_val = inb(PIC_MASTER_IMR); |
| 318 | 315 | if (new_val != probe_val) { |
| 319 | 316 | printk(KERN_INFO "Using NULL legacy PIC\n"); |
| 320 | 317 | legacy_pic = &null_legacy_pic; |
| 321 | − raw_spin_unlock_irqrestore(&i8259A_lock, flags); | |
| 322 | − return; | |
| 323 | 318 | } |
| 324 | 319 | |
| 320 | + raw_spin_unlock_irqrestore(&i8259A_lock, flags); | |
| 321 | + return nr_legacy_irqs(); | |
| 322 | +} | |
| 323 | + | |
| 324 | +static void init_8259A(int auto_eoi) | |
| 325 | +{ | |
| 326 | + unsigned long flags; | |
| 327 | + | |
| 328 | + i8259A_auto_eoi = auto_eoi; | |
| 329 | + | |
| 330 | + raw_spin_lock_irqsave(&i8259A_lock, flags); | |
| 331 | + | |
| 325 | 332 | outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ |
| 326 | 333 | |
| 327 | 334 | /* |
| @@ -379,6 +386,10 @@ static int legacy_pic_irq_pending_noop(unsigned int irq) · 51 unmodified lines | ||
| 379 | 386 | { |
| 380 | 387 | return 0; |
| 381 | 388 | } |
| 389 | +static int legacy_pic_probe(void) | |
| 390 | +{ | |
| 391 | + return 0; | |
| 392 | +} | |
| 382 | 393 | |
| 383 | 394 | struct legacy_pic null_legacy_pic = { |
| 384 | 395 | .nr_legacy_irqs = 0, |
| @@ -388,6 +399,7 @@ struct legacy_pic null_legacy_pic = { · 3 unmodified lines | ||
| 388 | 399 | .mask_all = legacy_pic_noop, |
| 389 | 400 | .restore_mask = legacy_pic_noop, |
| 390 | 401 | .init = legacy_pic_int_noop, |
| 402 | + .probe = legacy_pic_probe, | |
| 391 | 403 | .irq_pending = legacy_pic_irq_pending_noop, |
| 392 | 404 | .make_irq = legacy_pic_uint_noop, |
| 393 | 405 | }; |
| @@ -400,6 +412,7 @@ struct legacy_pic default_legacy_pic = { · 6 unmodified lines | ||
| 400 | 412 | .mask_all = mask_8259A, |
| 401 | 413 | .restore_mask = unmask_8259A, |
| 402 | 414 | .init = init_8259A, |
| 415 | + .probe = probe_8259A, | |
| 403 | 416 | .irq_pending = i8259A_irq_pending, |
| 404 | 417 | .make_irq = make_8259A_irq, |
| 405 | 418 | }; |
| @@ -1188,7 +1188,7 @@ void __init setup_arch(char **cmdline_p) · 1187 unmodified lines | ||
| 1188 | 1188 | */ |
| 1189 | 1189 | clone_pgd_range(initial_page_table, |
| 1190 | 1190 | swapper_pg_dir + KERNEL_PGD_BOUNDARY, |
| 1191 | − KERNEL_PGD_PTRS); | |
| 1191 | + min(KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY)); | |
| 1192 | 1192 | #endif |
| 1193 | 1193 | |
| 1194 | 1194 | tboot_probe(); |
| @@ -34,10 +34,11 @@ · 33 unmodified lines | ||
| 34 | 34 | #include <asm/msr-index.h> |
| 35 | 35 | |
| 36 | 36 | verify_cpu: |
| 37 | − pushfl # Save caller passed flags | |
| 38 | − pushl $0 # Kill any dangerous flags | |
| 39 | − popfl | |
| 37 | + pushf # Save caller passed flags | |
| 38 | + push $0 # Kill any dangerous flags | |
| 39 | + popf | |
| 40 | 40 | |
| 41 | +#ifndef __x86_64__ | |
| 41 | 42 | pushfl # standard way to check for cpuid |
| 42 | 43 | popl %eax |
| 43 | 44 | movl %eax,%ebx |
| @@ -48,6 +49,7 @@ verify_cpu: · 4 unmodified lines | ||
| 48 | 49 | popl %eax |
| 49 | 50 | cmpl %eax,%ebx |
| 50 | 51 | jz verify_cpu_no_longmode # cpu has no cpuid |
| 52 | +#endif | |
| 51 | 53 | |
| 52 | 54 | movl $0x0,%eax # See if cpuid 1 is implemented |
| 53 | 55 | cpuid |
| @@ -130,10 +132,10 @@ verify_cpu_sse_test: · 76 unmodified lines | ||
| 130 | 132 | jmp verify_cpu_sse_test # try again |
| 131 | 133 | |
| 132 | 134 | verify_cpu_no_longmode: |
| 133 | − popfl # Restore caller passed flags | |
| 135 | + popf # Restore caller passed flags | |
| 134 | 136 | movl $1,%eax |
| 135 | 137 | ret |
| 136 | 138 | verify_cpu_sse_ok: |
| 137 | − popfl # Restore caller passed flags | |
| 139 | + popf # Restore caller passed flags | |
| 138 | 140 | xorl %eax, %eax |
| 139 | 141 | ret |
| @@ -358,6 +358,21 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t addr, · 357 unmodified lines | ||
| 358 | 358 | #define pgd_none(a) pud_none(__pud(pgd_val(a))) |
| 359 | 359 | #endif |
| 360 | 360 | |
| 361 | +#ifdef CONFIG_X86_64 | |
| 362 | +static inline bool is_hypervisor_range(int idx) | |
| 363 | +{ | |
| 364 | + /* | |
| 365 | + * ffff800000000000 - ffff87ffffffffff is reserved for | |
| 366 | + * the hypervisor. | |
| 367 | + */ | |
| 368 | + return paravirt_enabled() && | |
| 369 | + (idx >= pgd_index(__PAGE_OFFSET) - 16) && | |
| 370 | + (idx < pgd_index(__PAGE_OFFSET)); | |
| 371 | +} | |
| 372 | +#else | |
| 373 | +static inline bool is_hypervisor_range(int idx) { return false; } | |
| 374 | +#endif | |
| 375 | + | |
| 361 | 376 | static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd, |
| 362 | 377 | bool checkwx) |
| 363 | 378 | { |
| @@ -381,7 +396,7 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd, · 17 unmodified lines | ||
| 381 | 396 | |
| 382 | 397 | for (i = 0; i < PTRS_PER_PGD; i++) { |
| 383 | 398 | st.current_address = normalize_addr(i * PGD_LEVEL_MULT); |
| 384 | − if (!pgd_none(*start)) { | |
| 399 | + if (!pgd_none(*start) && !is_hypervisor_range(i)) { | |
| 385 | 400 | if (pgd_large(*start) || !pgd_present(*start)) { |
| 386 | 401 | prot = pgd_flags(*start); |
| 387 | 402 | note_page(m, &st, __pgprot(prot), 1); |