diff options
24 files changed, 359 insertions, 562 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index eaff4790ed96..eec240e12091 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
| @@ -306,7 +306,7 @@ struct apic { | |||
| 306 | unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid); | 306 | unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid); |
| 307 | unsigned long (*check_apicid_present)(int apicid); | 307 | unsigned long (*check_apicid_present)(int apicid); |
| 308 | 308 | ||
| 309 | void (*vector_allocation_domain)(int cpu, struct cpumask *retmask); | 309 | bool (*vector_allocation_domain)(int cpu, struct cpumask *retmask); |
| 310 | void (*init_apic_ldr)(void); | 310 | void (*init_apic_ldr)(void); |
| 311 | 311 | ||
| 312 | void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap); | 312 | void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap); |
| @@ -331,9 +331,9 @@ struct apic { | |||
| 331 | unsigned long (*set_apic_id)(unsigned int id); | 331 | unsigned long (*set_apic_id)(unsigned int id); |
| 332 | unsigned long apic_id_mask; | 332 | unsigned long apic_id_mask; |
| 333 | 333 | ||
| 334 | unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask); | 334 | int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, |
| 335 | unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, | 335 | const struct cpumask *andmask, |
| 336 | const struct cpumask *andmask); | 336 | unsigned int *apicid); |
| 337 | 337 | ||
| 338 | /* ipi */ | 338 | /* ipi */ |
| 339 | void (*send_IPI_mask)(const struct cpumask *mask, int vector); | 339 | void (*send_IPI_mask)(const struct cpumask *mask, int vector); |
| @@ -537,6 +537,11 @@ static inline const struct cpumask *default_target_cpus(void) | |||
| 537 | #endif | 537 | #endif |
| 538 | } | 538 | } |
| 539 | 539 | ||
| 540 | static inline const struct cpumask *online_target_cpus(void) | ||
| 541 | { | ||
| 542 | return cpu_online_mask; | ||
| 543 | } | ||
| 544 | |||
| 540 | DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); | 545 | DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); |
| 541 | 546 | ||
| 542 | 547 | ||
| @@ -586,21 +591,50 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) | |||
| 586 | 591 | ||
| 587 | #endif | 592 | #endif |
| 588 | 593 | ||
| 589 | static inline unsigned int | 594 | static inline int |
| 590 | default_cpu_mask_to_apicid(const struct cpumask *cpumask) | 595 | flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
| 596 | const struct cpumask *andmask, | ||
| 597 | unsigned int *apicid) | ||
| 591 | { | 598 | { |
| 592 | return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; | 599 | unsigned long cpu_mask = cpumask_bits(cpumask)[0] & |
| 600 | cpumask_bits(andmask)[0] & | ||
| 601 | cpumask_bits(cpu_online_mask)[0] & | ||
| 602 | APIC_ALL_CPUS; | ||
| 603 | |||
| 604 | if (likely(cpu_mask)) { | ||
| 605 | *apicid = (unsigned int)cpu_mask; | ||
| 606 | return 0; | ||
| 607 | } else { | ||
| 608 | return -EINVAL; | ||
| 609 | } | ||
| 593 | } | 610 | } |
| 594 | 611 | ||
| 595 | static inline unsigned int | 612 | extern int |
| 596 | default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 613 | default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
| 597 | const struct cpumask *andmask) | 614 | const struct cpumask *andmask, |
| 615 | unsigned int *apicid); | ||
| 616 | |||
| 617 | static inline bool | ||
| 618 | flat_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
| 598 | { | 619 | { |
| 599 | unsigned long mask1 = cpumask_bits(cpumask)[0]; | 620 | /* Careful. Some cpus do not strictly honor the set of cpus |
| 600 | unsigned long mask2 = cpumask_bits(andmask)[0]; | 621 | * specified in the interrupt destination when using lowest |
| 601 | unsigned long mask3 = cpumask_bits(cpu_online_mask)[0]; | 622 | * priority interrupt delivery mode. |
| 623 | * | ||
| 624 | * In particular there was a hyperthreading cpu observed to | ||
| 625 | * deliver interrupts to the wrong hyperthread when only one | ||
| 626 | * hyperthread was specified in the interrupt desitination. | ||
| 627 | */ | ||
| 628 | cpumask_clear(retmask); | ||
| 629 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
| 630 | return false; | ||
| 631 | } | ||
| 602 | 632 | ||
| 603 | return (unsigned int)(mask1 & mask2 & mask3); | 633 | static inline bool |
| 634 | default_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
| 635 | { | ||
| 636 | cpumask_copy(retmask, cpumask_of(cpu)); | ||
| 637 | return true; | ||
| 604 | } | 638 | } |
| 605 | 639 | ||
| 606 | static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid) | 640 | static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid) |
diff --git a/arch/x86/include/asm/x2apic.h b/arch/x86/include/asm/x2apic.h index 92e54abf89e0..f90f0a587c66 100644 --- a/arch/x86/include/asm/x2apic.h +++ b/arch/x86/include/asm/x2apic.h | |||
| @@ -9,15 +9,6 @@ | |||
| 9 | #include <asm/ipi.h> | 9 | #include <asm/ipi.h> |
| 10 | #include <linux/cpumask.h> | 10 | #include <linux/cpumask.h> |
| 11 | 11 | ||
| 12 | /* | ||
| 13 | * Need to use more than cpu 0, because we need more vectors | ||
| 14 | * when MSI-X are used. | ||
| 15 | */ | ||
| 16 | static const struct cpumask *x2apic_target_cpus(void) | ||
| 17 | { | ||
| 18 | return cpu_online_mask; | ||
| 19 | } | ||
| 20 | |||
| 21 | static int x2apic_apic_id_valid(int apicid) | 12 | static int x2apic_apic_id_valid(int apicid) |
| 22 | { | 13 | { |
| 23 | return 1; | 14 | return 1; |
| @@ -28,15 +19,6 @@ static int x2apic_apic_id_registered(void) | |||
| 28 | return 1; | 19 | return 1; |
| 29 | } | 20 | } |
| 30 | 21 | ||
| 31 | /* | ||
| 32 | * For now each logical cpu is in its own vector allocation domain. | ||
| 33 | */ | ||
| 34 | static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
| 35 | { | ||
| 36 | cpumask_clear(retmask); | ||
| 37 | cpumask_set_cpu(cpu, retmask); | ||
| 38 | } | ||
| 39 | |||
| 40 | static void | 22 | static void |
| 41 | __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest) | 23 | __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest) |
| 42 | { | 24 | { |
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index c377d9ccb696..38155f667144 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h | |||
| @@ -156,7 +156,6 @@ struct x86_cpuinit_ops { | |||
| 156 | /** | 156 | /** |
| 157 | * struct x86_platform_ops - platform specific runtime functions | 157 | * struct x86_platform_ops - platform specific runtime functions |
| 158 | * @calibrate_tsc: calibrate TSC | 158 | * @calibrate_tsc: calibrate TSC |
| 159 | * @wallclock_init: init the wallclock device | ||
| 160 | * @get_wallclock: get time from HW clock like RTC etc. | 159 | * @get_wallclock: get time from HW clock like RTC etc. |
| 161 | * @set_wallclock: set time back to HW clock | 160 | * @set_wallclock: set time back to HW clock |
| 162 | * @is_untracked_pat_range exclude from PAT logic | 161 | * @is_untracked_pat_range exclude from PAT logic |
| @@ -168,7 +167,6 @@ struct x86_cpuinit_ops { | |||
| 168 | */ | 167 | */ |
| 169 | struct x86_platform_ops { | 168 | struct x86_platform_ops { |
| 170 | unsigned long (*calibrate_tsc)(void); | ||
