diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-10 13:59:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-10 13:59:07 -0400 |
commit | 5fa0eb0b4d4780fbd6d8a09850cc4fd539e9fe65 (patch) | |
tree | dc046871a73abd4f9d5f39f5379234cead2607e7 | |
parent | c48ce9f190266b763e809dd79fcf4152f558793c (diff) | |
parent | d4b05923f579c234137317cdf9a5eb69ddab76d1 (diff) |
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 updates from Thomas Gleixner:
"A pile of regression fixes and updates:
- address the fallout of the patches which made the cpuid - nodeid
relation permanent: Handling of invalid APIC ids and preventing
pointless warning messages.
- force eager FPU when protection keys are enabled. Protection keys
are not generating FPU exceptions so they cannot work with the lazy
FPU mechanism.
- prevent force migration of interrupts which are not part of the CPU
vector domain.
- handle the fact that APIC ids are not updated in the ACPI/MADT
tables on physical CPU hotplug
- remove bash-isms from syscall table generator script
- use the hypervisor supplied APIC frequency when running on VMware"
* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/pkeys: Make protection keys an "eager" feature
x86/apic: Prevent pointless warning messages
x86/acpi: Prevent LAPIC id 0xff from being accounted
arch/x86: Handle non enumerated CPU after physical hotplug
x86/unwind: Fix oprofile module link error
x86/vmware: Skip lapic calibration on VMware
x86/syscalls: Remove bash-isms in syscall table generator
x86/irq: Prevent force migration of irqs which are not in the vector domain
-rw-r--r-- | arch/x86/entry/syscalls/syscalltbl.sh | 15 | ||||
-rw-r--r-- | arch/x86/include/asm/fpu/xstate.h | 7 | ||||
-rw-r--r-- | arch/x86/include/asm/unwind.h | 14 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 8 | ||||
-rw-r--r-- | arch/x86/kernel/apic/vector.c | 23 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/vmware.c | 12 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot.c | 18 | ||||
-rw-r--r-- | arch/x86/kernel/unwind_guess.c | 10 |
9 files changed, 79 insertions, 32 deletions
diff --git a/arch/x86/entry/syscalls/syscalltbl.sh b/arch/x86/entry/syscalls/syscalltbl.sh index cd3d3015d7df..751d1f992630 100644 --- a/arch/x86/entry/syscalls/syscalltbl.sh +++ b/arch/x86/entry/syscalls/syscalltbl.sh | |||
@@ -10,8 +10,11 @@ syscall_macro() { | |||
10 | 10 | ||
11 | # Entry can be either just a function name or "function/qualifier" | 11 | # Entry can be either just a function name or "function/qualifier" |
12 | real_entry="${entry%%/*}" | 12 | real_entry="${entry%%/*}" |
13 | qualifier="${entry:${#real_entry}}" # Strip the function name | 13 | if [ "$entry" = "$real_entry" ]; then |
14 | qualifier="${qualifier:1}" # Strip the slash, if any | 14 | qualifier= |
15 | else | ||
16 | qualifier=${entry#*/} | ||
17 | fi | ||
15 | 18 | ||
16 | echo "__SYSCALL_${abi}($nr, $real_entry, $qualifier)" | 19 | echo "__SYSCALL_${abi}($nr, $real_entry, $qualifier)" |
17 | } | 20 | } |
@@ -22,7 +25,7 @@ emit() { | |||
22 | entry="$3" | 25 | entry="$3" |
23 | compat="$4" | 26 | compat="$4" |
24 | 27 | ||
25 | if [ "$abi" == "64" -a -n "$compat" ]; then | 28 | if [ "$abi" = "64" -a -n "$compat" ]; then |
26 | echo "a compat entry for a 64-bit syscall makes no sense" >&2 | 29 | echo "a compat entry for a 64-bit syscall makes no sense" >&2 |
27 | exit 1 | 30 | exit 1 |
28 | fi | 31 | fi |
@@ -45,17 +48,17 @@ emit() { | |||
45 | grep '^[0-9]' "$in" | sort -n | ( | 48 | grep '^[0-9]' "$in" | sort -n | ( |
46 | while read nr abi name entry compat; do | 49 | while read nr abi name entry compat; do |
47 | abi=`echo "$abi" | tr '[a-z]' '[A-Z]'` | 50 | abi=`echo "$abi" | tr '[a-z]' '[A-Z]'` |
48 | if [ "$abi" == "COMMON" -o "$abi" == "64" ]; then | 51 | if [ "$abi" = "COMMON" -o "$abi" = "64" ]; then |
49 | # COMMON is the same as 64, except that we don't expect X32 | 52 | # COMMON is the same as 64, except that we don't expect X32 |
50 | # programs to use it. Our expectation has nothing to do with | 53 | # programs to use it. Our expectation has nothing to do with |
51 | # any generated code, so treat them the same. | 54 | # any generated code, so treat them the same. |
52 | emit 64 "$nr" "$entry" "$compat" | 55 | emit 64 "$nr" "$entry" "$compat" |
53 | elif [ "$abi" == "X32" ]; then | 56 | elif [ "$abi" = "X32" ]; then |
54 | # X32 is equivalent to 64 on an X32-compatible kernel. | 57 | # X32 is equivalent to 64 on an X32-compatible kernel. |
55 | echo "#ifdef CONFIG_X86_X32_ABI" | 58 | echo "#ifdef CONFIG_X86_X32_ABI" |
56 | emit 64 "$nr" "$entry" "$compat" | 59 | emit 64 "$nr" "$entry" "$compat" |
57 | echo "#endif" | 60 | echo "#endif" |
58 | elif [ "$abi" == "I386" ]; then | 61 | elif [ "$abi" = "I386" ]; then |
59 | emit "$abi" "$nr" "$entry" "$compat" | 62 | emit "$abi" "$nr" "$entry" "$compat" |
60 | else | 63 | else |
61 | echo "Unknown abi $abi" >&2 | 64 | echo "Unknown abi $abi" >&2 |
diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h index d4957ac72b48..430bacf73074 100644 --- a/arch/x86/include/asm/fpu/xstate.h +++ b/arch/x86/include/asm/fpu/xstate.h | |||
@@ -27,11 +27,12 @@ | |||
27 | XFEATURE_MASK_YMM | \ | 27 | XFEATURE_MASK_YMM | \ |
28 | XFEATURE_MASK_OPMASK | \ | 28 | XFEATURE_MASK_OPMASK | \ |
29 | XFEATURE_MASK_ZMM_Hi256 | \ | 29 | XFEATURE_MASK_ZMM_Hi256 | \ |
30 | XFEATURE_MASK_Hi16_ZMM | \ | 30 | XFEATURE_MASK_Hi16_ZMM) |
31 | XFEATURE_MASK_PKRU) | ||
32 | 31 | ||
33 | /* Supported features which require eager state saving */ | 32 | /* Supported features which require eager state saving */ |
34 | #define XFEATURE_MASK_EAGER (XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR) | 33 | #define XFEATURE_MASK_EAGER (XFEATURE_MASK_BNDREGS | \ |
34 | XFEATURE_MASK_BNDCSR | \ | ||
35 | XFEATURE_MASK_PKRU) | ||
35 | 36 | ||
36 | /* All currently supported features */ | 37 | /* All currently supported features */ |
37 | #define XCNTXT_MASK (XFEATURE_MASK_LAZY | XFEATURE_MASK_EAGER) | 38 | #define XCNTXT_MASK (XFEATURE_MASK_LAZY | XFEATURE_MASK_EAGER) |
diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h index c4b6d1cafa46..46de9ac4b990 100644 --- a/arch/x86/include/asm/unwind.h +++ b/arch/x86/include/asm/unwind.h | |||
@@ -23,6 +23,8 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, | |||
23 | 23 | ||
24 | bool unwind_next_frame(struct unwind_state *state); | 24 | bool unwind_next_frame(struct unwind_state *state); |
25 | 25 | ||
26 | unsigned long unwind_get_return_address(struct unwind_state *state); | ||
27 | |||
26 | static inline bool unwind_done(struct unwind_state *state) | 28 | static inline bool unwind_done(struct unwind_state *state) |
27 | { | 29 | { |
28 | return state->stack_info.type == STACK_TYPE_UNKNOWN; | 30 | return state->stack_info.type == STACK_TYPE_UNKNOWN; |
@@ -48,8 +50,6 @@ unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) | |||
48 | return state->bp + 1; | 50 | return state->bp + 1; |
49 | } | 51 | } |
50 | 52 | ||
51 | unsigned long unwind_get_return_address(struct unwind_state *state); | ||
52 | |||
53 | #else /* !CONFIG_FRAME_POINTER */ | 53 | #else /* !CONFIG_FRAME_POINTER */ |
54 | 54 | ||
55 | static inline | 55 | static inline |
@@ -58,16 +58,6 @@ unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) | |||
58 | return NULL; | 58 | return NULL; |
59 | } | 59 | } |
60 | 60 | ||
61 | static inline | ||
62 | unsigned long unwind_get_return_address(struct unwind_state *state) | ||
63 | { | ||
64 | if (unwind_done(state)) | ||
65 | return 0; | ||
66 | |||
67 | return ftrace_graph_ret_addr(state->task, &state->graph_idx, | ||
68 | *state->sp, state->sp); | ||
69 | } | ||
70 | |||
71 | #endif /* CONFIG_FRAME_POINTER */ | 61 | #endif /* CONFIG_FRAME_POINTER */ |
72 | 62 | ||
73 | #endif /* _ASM_X86_UNWIND_H */ | 63 | #endif /* _ASM_X86_UNWIND_H */ |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 32a7d70913ac..8a5abaa7d453 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -233,6 +233,10 @@ acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) | |||
233 | 233 | ||
234 | acpi_table_print_madt_entry(header); | 234 | acpi_table_print_madt_entry(header); |
235 | 235 | ||
236 | /* Ignore invalid ID */ | ||
237 | if (processor->id == 0xff) | ||
238 | return 0; | ||
239 | |||
236 | /* | 240 | /* |
237 | * We need to register disabled CPU as well to permit | 241 | * We need to register disabled CPU as well to permit |
238 | * counting disabled CPUs. This allows us to size | 242 | * counting disabled CPUs. This allows us to size |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index f266b8a92a9e..88c657b057e2 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -2128,9 +2128,11 @@ int __generic_processor_info(int apicid, int version, bool enabled) | |||
2128 | if (num_processors >= nr_cpu_ids) { | 2128 | if (num_processors >= nr_cpu_ids) { |
2129 | int thiscpu = max + disabled_cpus; | 2129 | int thiscpu = max + disabled_cpus; |
2130 | 2130 | ||
2131 | pr_warning( | 2131 | if (enabled) { |
2132 | "APIC: NR_CPUS/possible_cpus limit of %i reached." | 2132 | pr_warning("APIC: NR_CPUS/possible_cpus limit of %i " |
2133 | " Processor %d/0x%x ignored.\n", max, thiscpu, apicid); | 2133 | "reached. Processor %d/0x%x ignored.\n", |
2134 | max, thiscpu, apicid); | ||
2135 | } | ||
2134 | 2136 | ||
2135 | disabled_cpus++; | 2137 | disabled_cpus++; |
2136 | return -EINVAL; | 2138 | return -EINVAL; |
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index 6066d945c40e..5d30c5e42bb1 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c | |||
@@ -661,11 +661,28 @@ void irq_complete_move(struct irq_cfg *cfg) | |||
661 | */ | 661 | */ |
662 | void irq_force_complete_move(struct irq_desc *desc) | 662 | void irq_force_complete_move(struct irq_desc *desc) |
663 | { | 663 | { |
664 | struct irq_data *irqdata = irq_desc_get_irq_data(desc); | 664 | struct irq_data *irqdata; |
665 | struct apic_chip_data *data = apic_chip_data(irqdata); | 665 | struct apic_chip_data *data; |
666 | struct irq_cfg *cfg = data ? &data->cfg : NULL; | 666 | struct irq_cfg *cfg; |
667 | unsigned int cpu; | 667 | unsigned int cpu; |
668 | 668 | ||
669 | /* | ||
670 | * The function is called for all descriptors regardless of which | ||
671 | * irqdomain they belong to. For example if an IRQ is provided by | ||
672 | * an irq_chip as part of a GPIO driver, the chip data for that | ||
673 | * descriptor is specific to the irq_chip in question. | ||
674 | * | ||
675 | * Check first that the chip_data is what we expect | ||
676 | * (apic_chip_data) before touching it any further. | ||
677 | */ | ||
678 | irqdata = irq_domain_get_irq_data(x86_vector_domain, | ||
679 | irq_desc_get_irq(desc)); | ||
680 | if (!irqdata) | ||
681 | return; | ||
682 | |||
683 | data = apic_chip_data(irqdata); | ||
684 | cfg = data ? &data->cfg : NULL; | ||
685 | |||
669 | if (!cfg) | 686 | if (!cfg) |
670 | return; | 687 | return; |
671 | 688 | ||
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 1ff0598d309c..81160578b91a 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/div64.h> | 27 | #include <asm/div64.h> |
28 | #include <asm/x86_init.h> | 28 | #include <asm/x86_init.h> |
29 | #include <asm/hypervisor.h> | 29 | #include <asm/hypervisor.h> |
30 | #include <asm/apic.h> | ||
30 | 31 | ||
31 | #define CPUID_VMWARE_INFO_LEAF 0x40000000 | 32 | #define CPUID_VMWARE_INFO_LEAF 0x40000000 |
32 | #define VMWARE_HYPERVISOR_MAGIC 0x564D5868 | 33 | #define VMWARE_HYPERVISOR_MAGIC 0x564D5868 |
@@ -82,10 +83,17 @@ static void __init vmware_platform_setup(void) | |||
82 | 83 | ||
83 | VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); | 84 | VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); |
84 | 85 | ||
85 | if (ebx != UINT_MAX) | 86 | if (ebx != UINT_MAX) { |
86 | x86_platform.calibrate_tsc = vmware_get_tsc_khz; | 87 | x86_platform.calibrate_tsc = vmware_get_tsc_khz; |
87 | else | 88 | #ifdef CONFIG_X86_LOCAL_APIC |
89 | /* Skip lapic calibration since we know the bus frequency. */ | ||
90 | lapic_timer_frequency = ecx / HZ; | ||
91 | pr_info("Host bus clock speed read from hypervisor : %u Hz\n", | ||
92 | ecx); | ||
93 | #endif | ||
94 | } else { | ||
88 | pr_warn("Failed to get TSC freq from the hypervisor\n"); | 95 | pr_warn("Failed to get TSC freq from the hypervisor\n"); |
96 | } | ||
89 | } | 97 | } |
90 | 98 | ||
91 | /* | 99 | /* |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 42a93621f5b0..951f093a96fe 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -1407,9 +1407,21 @@ __init void prefill_possible_map(void) | |||
1407 | { | 1407 | { |
1408 | int i, possible; | 1408 | int i, possible; |
1409 | 1409 | ||
1410 | /* no processor from mptable or madt */ | 1410 | /* No boot processor was found in mptable or ACPI MADT */ |
1411 | if (!num_processors) | 1411 | if (!num_processors) { |
1412 | num_processors = 1; | 1412 | int apicid = boot_cpu_physical_apicid; |
1413 | int cpu = hard_smp_processor_id(); | ||
1414 | |||
1415 | pr_warn("Boot CPU (id %d) not listed by BIOS\n", cpu); | ||
1416 | |||
1417 | /* Make sure boot cpu is enumerated */ | ||
1418 | if (apic->cpu_present_to_apicid(0) == BAD_APICID && | ||
1419 | apic->apic_id_valid(apicid)) | ||
1420 | generic_processor_info(apicid, boot_cpu_apic_version); | ||
1421 | |||
1422 | if (!num_processors) | ||
1423 | num_processors = 1; | ||
1424 | } | ||
1413 | 1425 | ||
1414 | i = setup_max_cpus ?: 1; | 1426 | i = setup_max_cpus ?: 1; |
1415 | if (setup_possible_cpus == -1) { | 1427 | if (setup_possible_cpus == -1) { |
diff --git a/arch/x86/kernel/unwind_guess.c b/arch/x86/kernel/unwind_guess.c index b5a834c93065..9298993dc8b7 100644 --- a/arch/x86/kernel/unwind_guess.c +++ b/arch/x86/kernel/unwind_guess.c | |||
@@ -5,6 +5,16 @@ | |||
5 | #include <asm/stacktrace.h> | 5 | #include <asm/stacktrace.h> |
6 | #include <asm/unwind.h> | 6 | #include <asm/unwind.h> |
7 | 7 | ||
8 | unsigned long unwind_get_return_address(struct unwind_state *state) | ||
9 | { | ||
10 | if (unwind_done(state)) | ||
11 | return 0; | ||
12 | |||
13 | return ftrace_graph_ret_addr(state->task, &state->graph_idx, | ||
14 | *state->sp, state->sp); | ||
15 | } | ||
16 | EXPORT_SYMBOL_GPL(unwind_get_return_address); | ||
17 | |||
8 | bool unwind_next_frame(struct unwind_state *state) | 18 | bool unwind_next_frame(struct unwind_state *state) |
9 | { | 19 | { |
10 | struct stack_info *info = &state->stack_info; | 20 | struct stack_info *info = &state->stack_info; |