aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-04 20:43:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-04 20:43:56 -0400
commit24e700e291d52bd200212487e2b654c0aa3f07a2 (patch)
tree56dfa9d5cdf5f753abbaac91dd68295e32ad2d85
parentf57091767add2b79d76aac41b83b192d8ba1dce7 (diff)
parentc6ef89421e236d75693ae968d80d44a52409889d (diff)
Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 apic updates from Thomas Gleixner: "This update provides: - Cleanup of the IDT management including the removal of the extra tracing IDT. A first step to cleanup the vector management code. - The removal of the paravirt op adjust_exception_frame. This is a XEN specific issue, but merged through this branch to avoid nasty merge collisions - Prevent dmesg spam about the TSC DEADLINE bug, when the CPU has disabled the TSC DEADLINE timer in CPUID. - Adjust a debug message in the ioapic code to print out the information correctly" * 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (51 commits) x86/idt: Fix the X86_TRAP_BP gate x86/xen: Get rid of paravirt op adjust_exception_frame x86/eisa: Add missing include x86/idt: Remove superfluous ALIGNment x86/apic: Silence "FW_BUG TSC_DEADLINE disabled due to Errata" on CPUs without the feature x86/idt: Remove the tracing IDT leftovers x86/idt: Hide set_intr_gate() x86/idt: Simplify alloc_intr_gate() x86/idt: Deinline setup functions x86/idt: Remove unused functions/inlines x86/idt: Move interrupt gate initialization to IDT code x86/idt: Move APIC gate initialization to tables x86/idt: Move regular trap init to tables x86/idt: Move IST stack based traps to table init x86/idt: Move debug stack init to table based x86/idt: Switch early trap init to IDT tables x86/idt: Prepare for table based init x86/idt: Move early IDT setup out of 32-bit asm x86/idt: Move early IDT handler setup to IDT code x86/idt: Consolidate IDT invalidation ...
-rw-r--r--arch/x86/boot/compressed/eboot.c8
-rw-r--r--arch/x86/entry/entry_32.S20
-rw-r--r--arch/x86/entry/entry_64.S49
-rw-r--r--arch/x86/entry/entry_64_compat.S1
-rw-r--r--arch/x86/entry/vdso/vma.c2
-rw-r--r--arch/x86/include/asm/desc.h248
-rw-r--r--arch/x86/include/asm/desc_defs.h122
-rw-r--r--arch/x86/include/asm/entry_arch.h17
-rw-r--r--arch/x86/include/asm/hw_irq.h20
-rw-r--r--arch/x86/include/asm/irq.h4
-rw-r--r--arch/x86/include/asm/irq_work.h8
-rw-r--r--arch/x86/include/asm/paravirt.h5
-rw-r--r--arch/x86/include/asm/paravirt_types.h3
-rw-r--r--arch/x86/include/asm/proto.h3
-rw-r--r--arch/x86/include/asm/segment.h4
-rw-r--r--arch/x86/include/asm/trace/common.h16
-rw-r--r--arch/x86/include/asm/trace/exceptions.h8
-rw-r--r--arch/x86/include/asm/trace/irq_vectors.h51
-rw-r--r--arch/x86/include/asm/traps.h50
-rw-r--r--arch/x86/include/asm/xen/hypercall.h6
-rw-r--r--arch/x86/kernel/Makefile3
-rw-r--r--arch/x86/kernel/apic/apic.c76
-rw-r--r--arch/x86/kernel/apic/io_apic.c2
-rw-r--r--arch/x86/kernel/apic/vector.c2
-rw-r--r--arch/x86/kernel/asm-offsets_64.c1
-rw-r--r--arch/x86/kernel/cpu/common.c9
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd.c16
-rw-r--r--arch/x86/kernel/cpu/mcheck/therm_throt.c20
-rw-r--r--arch/x86/kernel/cpu/mcheck/threshold.c16
-rw-r--r--arch/x86/kernel/cpu/mshyperv.c9
-rw-r--r--arch/x86/kernel/eisa.c19
-rw-r--r--arch/x86/kernel/head32.c4
-rw-r--r--arch/x86/kernel/head64.c6
-rw-r--r--arch/x86/kernel/head_32.S44
-rw-r--r--arch/x86/kernel/idt.c371
-rw-r--r--arch/x86/kernel/irq.c40
-rw-r--r--arch/x86/kernel/irq_work.c20
-rw-r--r--arch/x86/kernel/irqinit.c102
-rw-r--r--arch/x86/kernel/kvm.c4
-rw-r--r--arch/x86/kernel/machine_kexec_32.c14
-rw-r--r--arch/x86/kernel/paravirt.c3
-rw-r--r--arch/x86/kernel/reboot.c4
-rw-r--r--arch/x86/kernel/setup.c4
-rw-r--r--arch/x86/kernel/setup_percpu.c9
-rw-r--r--arch/x86/kernel/smp.c81
-rw-r--r--arch/x86/kernel/tls.c2
-rw-r--r--arch/x86/kernel/tracepoint.c57
-rw-r--r--arch/x86/kernel/traps.c107
-rw-r--r--arch/x86/kvm/vmx.c2
-rw-r--r--arch/x86/math-emu/fpu_entry.c11
-rw-r--r--arch/x86/math-emu/fpu_system.h48
-rw-r--r--arch/x86/math-emu/get_address.c17
-rw-r--r--arch/x86/mm/fault.c49
-rw-r--r--arch/x86/xen/enlighten_pv.c110
-rw-r--r--arch/x86/xen/irq.c3
-rw-r--r--arch/x86/xen/xen-asm_64.S41
-rw-r--r--arch/x86/xen/xen-ops.h1
-rw-r--r--drivers/xen/events/events_base.c6
58 files changed, 901 insertions, 1077 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index e007887a33b0..926c2cc4facc 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -1058,7 +1058,7 @@ struct boot_params *efi_main(struct efi_config *c,
1058 desc->s = DESC_TYPE_CODE_DATA; 1058 desc->s = DESC_TYPE_CODE_DATA;
1059 desc->dpl = 0; 1059 desc->dpl = 0;
1060 desc->p = 1; 1060 desc->p = 1;
1061 desc->limit = 0xf; 1061 desc->limit1 = 0xf;
1062 desc->avl = 0; 1062 desc->avl = 0;
1063 desc->l = 0; 1063 desc->l = 0;
1064 desc->d = SEG_OP_SIZE_32BIT; 1064 desc->d = SEG_OP_SIZE_32BIT;
@@ -1078,7 +1078,7 @@ struct boot_params *efi_main(struct efi_config *c,
1078 desc->s = DESC_TYPE_CODE_DATA; 1078 desc->s = DESC_TYPE_CODE_DATA;
1079 desc->dpl = 0; 1079 desc->dpl = 0;
1080 desc->p = 1; 1080 desc->p = 1;
1081 desc->limit = 0xf; 1081 desc->limit1 = 0xf;
1082 desc->avl = 0; 1082 desc->avl = 0;
1083 if (IS_ENABLED(CONFIG_X86_64)) { 1083 if (IS_ENABLED(CONFIG_X86_64)) {
1084 desc->l = 1; 1084 desc->l = 1;
@@ -1099,7 +1099,7 @@ struct boot_params *efi_main(struct efi_config *c,
1099 desc->s = DESC_TYPE_CODE_DATA; 1099 desc->s = DESC_TYPE_CODE_DATA;
1100 desc->dpl = 0; 1100 desc->dpl = 0;
1101 desc->p = 1; 1101 desc->p = 1;
1102 desc->limit = 0xf; 1102 desc->limit1 = 0xf;
1103 desc->avl = 0; 1103 desc->avl = 0;
1104 desc->l = 0; 1104 desc->l = 0;
1105 desc->d = SEG_OP_SIZE_32BIT; 1105 desc->d = SEG_OP_SIZE_32BIT;
@@ -1116,7 +1116,7 @@ struct boot_params *efi_main(struct efi_config *c,
1116 desc->s = 0; 1116 desc->s = 0;
1117 desc->dpl = 0; 1117 desc->dpl = 0;
1118 desc->p = 1; 1118 desc->p = 1;
1119 desc->limit = 0x0; 1119 desc->limit1 = 0x0;
1120 desc->avl = 0; 1120 desc->avl = 0;
1121 desc->l = 0; 1121 desc->l = 0;
1122 desc->d = 0; 1122 desc->d = 0;
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index 48ef7bb32c42..8a13d468635a 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -673,16 +673,8 @@ ENTRY(name) \
673 jmp ret_from_intr; \ 673 jmp ret_from_intr; \
674ENDPROC(name) 674ENDPROC(name)
675 675
676
677#ifdef CONFIG_TRACING
678# define TRACE_BUILD_INTERRUPT(name, nr) BUILD_INTERRUPT3(trace_##name, nr, smp_trace_##name)
679#else
680# define TRACE_BUILD_INTERRUPT(name, nr)
681#endif
682
683#define BUILD_INTERRUPT(name, nr) \ 676#define BUILD_INTERRUPT(name, nr) \
684 BUILD_INTERRUPT3(name, nr, smp_##name); \ 677 BUILD_INTERRUPT3(name, nr, smp_##name); \
685 TRACE_BUILD_INTERRUPT(name, nr)
686 678
687/* The include is where all of the SMP etc. interrupts come from */ 679/* The include is where all of the SMP etc. interrupts come from */
688#include <asm/entry_arch.h> 680#include <asm/entry_arch.h>
@@ -880,25 +872,17 @@ ENTRY(xen_failsafe_callback)
880ENDPROC(xen_failsafe_callback) 872ENDPROC(xen_failsafe_callback)
881 873
882BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR, 874BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR,
883 xen_evtchn_do_upcall) 875 xen_evtchn_do_upcall)
884 876
885#endif /* CONFIG_XEN */ 877#endif /* CONFIG_XEN */
886 878
887#if IS_ENABLED(CONFIG_HYPERV) 879#if IS_ENABLED(CONFIG_HYPERV)
888 880
889BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR, 881BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR,
890 hyperv_vector_handler) 882 hyperv_vector_handler)
891 883
892#endif /* CONFIG_HYPERV */ 884#endif /* CONFIG_HYPERV */
893 885
894#ifdef CONFIG_TRACING
895ENTRY(trace_page_fault)
896 ASM_CLAC
897 pushl $trace_do_page_fault
898 jmp common_exception
899END(trace_page_fault)
900#endif
901
902ENTRY(page_fault) 886ENTRY(page_fault)
903 ASM_CLAC 887 ASM_CLAC
904 pushl $do_page_fault 888 pushl $do_page_fault
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index ca0b250eefc4..49167258d587 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -748,18 +748,6 @@ ENTRY(\sym)
748END(\sym) 748END(\sym)
749.endm 749.endm
750 750
751#ifdef CONFIG_TRACING
752#define trace(sym) trace_##sym
753#define smp_trace(sym) smp_trace_##sym
754
755.macro trace_apicinterrupt num sym
756apicinterrupt3 \num trace(\sym) smp_trace(\sym)
757.endm
758#else
759.macro trace_apicinterrupt num sym do_sym
760.endm
761#endif
762
763/* Make sure APIC interrupt handlers end up in the irqentry section: */ 751/* Make sure APIC interrupt handlers end up in the irqentry section: */
764#define PUSH_SECTION_IRQENTRY .pushsection .irqentry.text, "ax" 752#define PUSH_SECTION_IRQENTRY .pushsection .irqentry.text, "ax"
765#define POP_SECTION_IRQENTRY .popsection 753#define POP_SECTION_IRQENTRY .popsection
@@ -767,7 +755,6 @@ apicinterrupt3 \num trace(\sym) smp_trace(\sym)
767.macro apicinterrupt num sym do_sym 755.macro apicinterrupt num sym do_sym
768PUSH_SECTION_IRQENTRY 756PUSH_SECTION_IRQENTRY
769apicinterrupt3 \num \sym \do_sym 757apicinterrupt3 \num \sym \do_sym
770trace_apicinterrupt \num \sym
771POP_SECTION_IRQENTRY 758POP_SECTION_IRQENTRY
772.endm 759.endm
773 760
@@ -829,7 +816,6 @@ ENTRY(\sym)
829 .endif 816 .endif
830 817
831 ASM_CLAC 818 ASM_CLAC
832 PARAVIRT_ADJUST_EXCEPTION_FRAME
833 819
834 .ifeq \has_error_code 820 .ifeq \has_error_code
835 pushq $-1 /* ORIG_RAX: no syscall to restart */ 821 pushq $-1 /* ORIG_RAX: no syscall to restart */
@@ -913,17 +899,6 @@ ENTRY(\sym)
913END(\sym) 899END(\sym)
914.endm 900.endm
915 901
916#ifdef CONFIG_TRACING
917.macro trace_idtentry sym do_sym has_error_code:req
918idtentry trace(\sym) trace(\do_sym) has_error_code=\has_error_code
919idtentry \sym \do_sym has_error_code=\has_error_code
920.endm
921#else
922.macro trace_idtentry sym do_sym has_error_code:req
923idtentry \sym \do_sym has_error_code=\has_error_code
924.endm
925#endif
926
927idtentry divide_error do_divide_error has_error_code=0 902idtentry divide_error do_divide_error has_error_code=0
928idtentry overflow do_overflow has_error_code=0 903idtentry overflow do_overflow has_error_code=0
929idtentry bounds do_bounds has_error_code=0 904idtentry bounds do_bounds has_error_code=0
@@ -986,7 +961,7 @@ ENTRY(do_softirq_own_stack)
986ENDPROC(do_softirq_own_stack) 961ENDPROC(do_softirq_own_stack)
987 962
988#ifdef CONFIG_XEN 963#ifdef CONFIG_XEN
989idtentry xen_hypervisor_callback xen_do_hypervisor_callback has_error_code=0 964idtentry hypervisor_callback xen_do_hypervisor_callback has_error_code=0
990 965
991/* 966/*
992 * A note on the "critical region" in our callback handler. 967 * A note on the "critical region" in our callback handler.
@@ -1053,8 +1028,6 @@ ENTRY(xen_failsafe_callback)
1053 movq 8(%rsp), %r11 1028 movq 8(%rsp), %r11
1054 addq $0x30, %rsp 1029 addq $0x30, %rsp
1055 pushq $0 /* RIP */ 1030 pushq $0 /* RIP */
1056 pushq %r11
1057 pushq %rcx
1058 UNWIND_HINT_IRET_REGS offset=8 1031 UNWIND_HINT_IRET_REGS offset=8
1059 jmp general_protection 1032 jmp general_protection
10601: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */ 10331: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */
@@ -1085,13 +1058,12 @@ idtentry int3 do_int3 has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK
1085idtentry stack_segment do_stack_segment has_error_code=1 1058idtentry stack_segment do_stack_segment has_error_code=1
1086 1059
1087#ifdef CONFIG_XEN 1060#ifdef CONFIG_XEN
1088idtentry xen_debug do_debug has_error_code=0 1061idtentry xendebug do_debug has_error_code=0
1089idtentry xen_int3 do_int3 has_error_code=0 1062idtentry xenint3 do_int3 has_error_code=0
1090idtentry xen_stack_segment do_stack_segment has_error_code=1
1091#endif 1063#endif
1092 1064
1093idtentry general_protection do_general_protection has_error_code=1 1065idtentry general_protection do_general_protection has_error_code=1
1094trace_idtentry page_fault do_page_fault has_error_code=1 1066idtentry page_fault do_page_fault has_error_code=1
1095 1067
1096#ifdef CONFIG_KVM_GUEST 1068#ifdef CONFIG_KVM_GUEST
1097idtentry async_page_fault do_async_page_fault has_error_code=1 1069idtentry async_page_fault do_async_page_fault has_error_code=1
@@ -1251,21 +1223,10 @@ ENTRY(error_exit)
1251END(error_exit) 1223END(error_exit)
1252 1224
1253/* Runs on exception stack */ 1225/* Runs on exception stack */
1226/* XXX: broken on Xen PV */
1254ENTRY(nmi) 1227ENTRY(nmi)
1255 UNWIND_HINT_IRET_REGS 1228 UNWIND_HINT_IRET_REGS
1256 /* 1229 /*
1257 * Fix up the exception frame if we're on Xen.
1258 * PARAVIRT_ADJUST_EXCEPTION_FRAME is guaranteed to push at most
1259 * one value to the stack on native, so it may clobber the rdx
1260 * scratch slot, but it won't clobber any of the important
1261 * slots past it.
1262 *
1263 * Xen is a different story, because the Xen frame itself overlaps
1264 * the "NMI executing" variable.
1265 */
1266 PARAVIRT_ADJUST_EXCEPTION_FRAME
1267
1268 /*
1269 * We allow breakpoints in NMIs. If a breakpoint occurs, then 1230 * We allow breakpoints in NMIs. If a breakpoint occurs, then
1270 * the iretq it performs will take us out of NMI context. 1231 * the iretq it performs will take us out of NMI context.
1271 * This means that we can have nested NMIs where the next 1232 * This means that we can have nested NMIs where the next
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index 4b86d8da3ea3..e26c25ca7756 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -293,7 +293,6 @@ ENTRY(entry_INT80_compat)
293 /* 293 /*
294 * Interrupts are off on entry. 294 * Interrupts are off on entry.
295 */ 295 */
296 PARAVIRT_ADJUST_EXCEPTION_FRAME
297 ASM_CLAC /* Do this early to minimize exposure */ 296 ASM_CLAC /* Do this early to minimize exposure */
298 SWAPGS 297 SWAPGS
299 298
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 726355ce8497..1911310959f8 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -351,7 +351,7 @@ static void vgetcpu_cpu_init(void *arg)
351 * and 8 bits for the node) 351 * and 8 bits for the node)
352 */ 352 */
353 d.limit0 = cpu | ((node & 0xf) << 12); 353 d.limit0 = cpu | ((node & 0xf) << 12);
354 d.limit = node >> 4; 354 d.limit1 = node >> 4;
355 d.type = 5; /* RO data, expand down, accessed */ 355 d.type = 5; /* RO data, expand down, accessed */
356 d.dpl = 3; /* Visible to user code */ 356 d.dpl = 3; /* Visible to user code */
357 d.s = 1; /* Not a system segment */ 357 d.s = 1; /* Not a system segment */
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index d0a21b12dd58..1a2ba368da39 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -5,6 +5,7 @@
5#include <asm/ldt.h> 5#include <asm/ldt.h>
6#include <asm/mmu.h> 6#include <asm/mmu.h>
7#include <asm/fixmap.h> 7#include <asm/fixmap.h>
8#include <asm/irq_vectors.h>
8 9
9#include <linux/smp.h> 10#include <linux/smp.h>
10#include <linux/percpu.h> 11#include <linux/percpu.h>
@@ -22,7 +23,7 @@ static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *in
22 desc->s = 1; 23 desc->s = 1;
23 desc->dpl = 0x3; 24 desc->dpl = 0x3;
24 desc->p = info->seg_not_present ^ 1; 25 desc->p = info->seg_not_present ^ 1;
25 desc->limit = (info->limit & 0xf0000) >> 16; 26 desc->limit1 = (info->limit & 0xf0000) >> 16;
26 desc->avl = info->useable; 27 desc->avl = info->useable;
27 desc->d = info->seg_32bit; 28 desc->d = info->seg_32bit;
28 desc->g = info->limit_in_pages; 29 desc->g = info->limit_in_pages;
@@ -83,33 +84,25 @@ static inline phys_addr_t get_cpu_gdt_paddr(unsigned int cpu)
83 return per_cpu_ptr_to_phys(get_cpu_gdt_rw(cpu)); 84 return per_cpu_ptr_to_phys(get_cpu_gdt_rw(cpu));
84} 85}
85 86
86#ifdef CONFIG_X86_64
87
88static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, 87static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
89 unsigned dpl, unsigned ist, unsigned seg) 88 unsigned dpl, unsigned ist, unsigned seg)
90{ 89{
91 gate->offset_low = PTR_LOW(func); 90 gate->offset_low = (u16) func;
91 gate->bits.p = 1;
92 gate->bits.dpl = dpl;
93 gate->bits.zero = 0;
94 gate->bits.type = type;
95 gate->offset_middle = (u16) (func >> 16);
96#ifdef CONFIG_X86_64
92 gate->segment = __KERNEL_CS; 97 gate->segment = __KERNEL_CS;
93 gate->ist = ist; 98 gate->bits.ist = ist;
94 gate->p = 1; 99 gate->reserved = 0;
95 gate->dpl = dpl; 100 gate->offset_high = (u32) (func >> 32);
96 gate->zero0 = 0;
97 gate->zero1 = 0;
98 gate->type = type;
99 gate->offset_middle = PTR_MIDDLE(func);
100 gate->offset_high = PTR_HIGH(func);
101}
102
103#else 101#else
104static inline void pack_gate(gate_desc *gate, unsigned char type, 102 gate->segment = seg;
105 unsigned long base, unsigned dpl, unsigned flags, 103 gate->bits.ist = 0;
106 unsigned short seg)
107{
108 gate->a = (seg << 16) | (base & 0xffff);
109 gate->b = (base & 0xffff0000) | (((0x80 | type | (dpl << 5)) & 0xff) << 8);
110}
111
112#endif 104#endif
105}
113 106
114static inline int desc_empty(const void *ptr) 107static inline int desc_empty(const void *ptr)
115{ 108{
@@ -173,35 +166,22 @@ native_write_gdt_entry(struct desc_struct *gdt, int entry, const void *desc, int
173 memcpy(&gdt[entry], desc, size); 166 memcpy(&gdt[entry], desc, size);
174} 167}
175 168
176static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, 169static inline void set_tssldt_descriptor(void *d, unsigned long addr,
177 unsigned long limit, unsigned char type, 170 unsigned type, unsigned size)
178 unsigned char flags)
179{
180 desc->a = ((base & 0xffff) << 16) | (limit & 0xffff);
181 desc->b = (base & 0xff000000) | ((base & 0xff0000) >> 16) |
182 (limit & 0x000f0000) | ((type & 0xff) << 8) |
183 ((flags & 0xf) << 20);
184 desc->p = 1;
185}
186
187
188static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned type, unsigned size)
189{ 171{
190#ifdef CONFIG_X86_64 172 struct ldttss_desc *desc = d;
191 struct ldttss_desc64 *desc = d;
192 173
193 memset(desc, 0, sizeof(*desc)); 174 memset(desc, 0, sizeof(*desc));
194 175
195 desc->limit0 = size & 0xFFFF; 176 desc->limit0 = (u16) size;
196 desc->base0 = PTR_LOW(addr); 177 desc->base0 = (u16) addr;
197 desc->base1 = PTR_MIDDLE(addr) & 0xFF; 178 desc->base1 = (addr >> 16) & 0xFF;
198 desc->type = type; 179 desc->type = type;
199 desc->p = 1; 180 desc->p = 1;
200 desc->limit1 = (size >> 16) & 0xF; 181 desc->limit1 = (size >> 16) & 0xF;
201 desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF; 182 desc->base2 = (addr >> 24) & 0xFF;
202 desc->base3 = PTR_HIGH(addr); 183#ifdef CONFIG_X86_64
203#else 184 desc->base3 = (u32) (addr >> 32);
204 pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0);
205#endif 185#endif
206} 186}
207 187
@@ -401,147 +381,20 @@ static inline void set_desc_base(struct desc_struct *desc, unsigned long base)
401 381
402static inline unsigned long get_desc_limit(const struct desc_struct *desc) 382static inline unsigned long get_desc_limit(const struct desc_struct *desc)
403{ 383{
404 return desc->limit0 | (desc->limit << 16); 384 return desc->limit0 | (desc->limit1 << 16);
405} 385}
406 386
407static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit) 387static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit)
408{ 388{
409 desc->limit0 = limit & 0xffff; 389 desc->limit0 = limit & 0xffff;
410 desc->limit = (limit >> 16) & 0xf; 390 desc->limit1 = (limit >> 16) & 0xf;
411}
412
413#ifdef CONFIG_X86_64
414static inline void set_nmi_gate(int gate, void *addr)
415{
416 gate_desc s;
417
418 pack_gate(&s, GATE_INTERRUPT, (unsigned long)addr, 0, 0, __KERNEL_CS);
419 write_idt_entry(debug_idt_table, gate, &s);
420} 391}
421#endif
422 392
423#ifdef CONFIG_TRACING 393void update_intr_gate(unsigned int n, const void *addr);
424extern struct desc_ptr trace_idt_descr; 394void alloc_intr_gate(unsigned int n, const void *addr);
425extern gate_desc trace_idt_table[];
426static inline void write_trace_idt_entry(int entry, const gate_desc *gate)
427{
428 write_idt_entry(trace_idt_table, entry, gate);
429}
430 395
431static inline void _trace_set_gate(int gate, unsigned type, void *addr,
432 unsigned dpl, unsigned ist, unsigned seg)
433{
434 gate_desc s;
435
436 pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg);
437 /*
438 * does not need to be atomic because it is only done once at
439 * setup time
440 */
441 write_trace_idt_entry(gate, &s);
442}
443#else
444static inline void write_trace_idt_entry(int entry, const gate_desc *gate)
445{
446}
447
448#define _trace_set_gate(gate, type, addr, dpl, ist, seg)
449#endif
450
451static inline void _set_gate(int gate, unsigned type, void *addr,
452 unsigned dpl, unsigned ist, unsigned seg)
453{
454 gate_desc s;
455
456 pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg);
457 /*
458 * does not need to be atomic because it is only done once at
459 * setup time
460 */
461 write_idt_entry(idt_table, gate, &s);
462 write_trace_idt_entry(gate, &s);
463}
464
465/*
466 * This needs to use 'idt_table' rather than 'idt', and
467 * thus use the _nonmapped_ version of the IDT, as the
468 * Pentium F0 0F bugfix can have resulted in the mapped
469 * IDT being write-protected.
470 */
471#define set_intr_gate_notrace(n, addr) \
472 do { \
473 BUG_ON((unsigned)n > 0xFF); \
474 _set_gate(n, GATE_INTERRUPT, (void *)addr, 0, 0, \
475 __KERNEL_CS); \
476 } while (0)
477
478#define set_intr_gate(n, addr) \
479 do { \
480 set_intr_gate_notrace(n, addr); \
481 _trace_set_gate(n, GATE_INTERRUPT, (void *)trace_##addr,\
482 0, 0, __KERNEL_CS); \
483 } while (0)
484
485extern int first_system_vector;
486/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */
487extern unsigned long used_vectors[]; 396extern unsigned long used_vectors[];
488 397
489static inline void alloc_system_vector(int vector)
490{
491 if (!test_bit(vector, used_vectors)) {
492 set_bit(vector, used_vectors);
493 if (first_system_vector > vector)
494 first_system_vector = vector;
495 } else {
496 BUG();
497 }
498}
499
500#define alloc_intr_gate(n, addr) \
501 do { \
502 alloc_system_vector(n); \
503 set_intr_gate(n, addr); \
504 } while (0)
505
506/*
507 * This routine sets up an interrupt gate at directory privilege level 3.
508 */
509static inline void set_system_intr_gate(unsigned int n, void *addr)
510{
511 BUG_ON((unsigned)n > 0xFF);
512 _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS);
513}
514
515static inline void set_system_trap_gate(unsigned int n, void *addr)
516{
517 BUG_ON((unsigned)n > 0xFF);
518 _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS);
519}
520
521static inline void set_trap_gate(unsigned int n, void *addr)
522{
523 BUG_ON((unsigned)n > 0xFF);
524 _set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS);
525}
526
527static inline void set_task_gate(unsigned int n, unsigned int gdt_entry)
528{
529 BUG_ON((unsigned)n > 0xFF);
530 _set_gate(n, GATE_TASK, (void *)0, 0, 0, (gdt_entry<<3));
531}
532
533static inline void set_intr_gate_ist(int n, void *addr, unsigned ist)
534{
535 BUG_ON((unsigned)n > 0xFF);
536 _set_gate(n, GATE_INTERRUPT, addr, 0, ist, __KERNEL_CS);
537}
538
539static inline void set_system_intr_gate_ist(int n, void *addr, unsigned ist)
540{
541 BUG_ON((unsigned)n > 0xFF);
542 _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
543}
544
545#ifdef CONFIG_X86_64 398#ifdef CONFIG_X86_64
546DECLARE_PER_CPU(u32, debug_idt_ctr); 399DECLARE_PER_CPU(u32, debug_idt_ctr);
547static inline bool is_debug_idt_enabled(void) 400static inline bool is_debug_idt_enabled(void)
@@ -567,31 +420,6 @@ static inline void load_debug_idt(void)
567} 420}
568#endif 421#endif
569 422
570#ifdef CONFIG_TRACING
571extern atomic_t trace_idt_ctr;
572static inline bool is_trace_idt_enabled(void)
573{
574 if (atomic_read(&trace_idt_ctr))
575 return true;
576
577 return false;
578}
579
580static inline void load_trace_idt(void)
581{
582 load_idt((const struct desc_ptr *)&trace_idt_descr);
583}
584#else
585static inline bool is_trace_idt_enabled(void)
586{
587 return false;
588}
589
590static inline void load_trace_idt(void)
591{
592}
593#endif
594
595/* 423/*
596 * The load_current_idt() must be called with interrupts disabled 424 * The load_current_idt() must be called with interrupts disabled
597 * to avoid races. That way the IDT will always be set back to the expected 425 * to avoid races. That way the IDT will always be set back to the expected
@@ -603,9 +431,25 @@ static inline void load_current_idt(void)
603{ 431{
604 if (is_debug_idt_enabled()) 432 if (is_debug_idt_enabled())
605 load_debug_idt(); 433 load_debug_idt();
606 else if (is_trace_idt_enabled())
607 load_trace_idt();
608 else 434 else
609 load_idt((const struct desc_ptr *)&idt_descr); 435 load_idt((const struct desc_ptr *)&idt_descr);
610} 436}
437
438extern void idt_setup_early_handler(void);
439extern void idt_setup_early_traps(void);
440extern void idt_setup_traps(void);
441extern void idt_setup_apic_and_irq_gates(void);
442
443#ifdef CONFIG_X86_64
444extern void idt_setup_early_pf(void);
445extern void idt_setup_ist_traps(void);
446extern void idt_setup_debugidt_traps(void);
447#else
448static inline void idt_setup_early_pf(void) { }
449static inline void idt_setup_ist_traps(void) { }
450static inline void idt_setup_debugidt_traps(void) { }
451#endif
452
453extern void idt_invalidate(void *addr);
454
611#endif /* _ASM_X86_DESC_H */ 455#endif /* _ASM_X86_DESC_H */
diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h
index 49265345d4d2..346d252029b7 100644
--- a/arch/x86/include/asm/desc_defs.h
+++ b/arch/x86/include/asm/desc_defs.h
@@ -11,34 +11,30 @@
11 11
12#include <linux/types.h> 12#include <linux/types.h>
13 13
14/*
15 * FIXME: Accessing the desc_struct through its fields is more elegant,
16 * and should be the one valid thing to do. However, a lot of open code
17 * still touches the a and b accessors, and doing this allow us to do it
18 * incrementally. We keep the signature as a struct, rather than a union,
19 * so we can get rid of it transparently in the future -- glommer
20 */
21/* 8 byte segment descriptor */ 14/* 8 byte segment descriptor */
22struct desc_struct { 15struct desc_struct {
23 union { 16 u16 limit0;
24 struct { 17 u16 base0;
25 unsigned int a; 18 u16 base1: 8, type: 4, s: 1, dpl: 2, p: 1;
26 unsigned int b; 19 u16 limit1: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
27 };
28 struct {
29 u16 limit0;
30 u16 base0;
31 unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1;
32 unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
33 };
34 };
35} __attribute__((packed)); 20} __attribute__((packed));
36 21
37#define GDT_ENTRY_INIT(flags, base, limit) { { { \ 22#define GDT_ENTRY_INIT(flags, base, limit) \
38 .a = ((limit) & 0xffff) | (((base) & 0xffff) << 16), \ 23 { \
39 .b = (((base) & 0xff0000) >> 16) | (((flags) & 0xf0ff) << 8) | \ 24 .limit0 = (u16) (limit), \
40 ((limit) & 0xf0000) | ((base) & 0xff000000), \ 25 .limit1 = ((limit) >> 16) & 0x0F, \
41 } } } 26 .base0 = (u16) (base), \
27 .base1 = ((base) >> 16) & 0xFF, \
28 .base2 = ((base) >> 24) & 0xFF, \
29 .type = (flags & 0x0f), \
30 .s = (flags >> 4) & 0x01, \
31 .dpl = (flags >> 5) & 0x03, \
32 .p = (flags >> 7) & 0x01, \
33 .avl = (flags >> 12) & 0x01, \
34 .l = (flags >> 13) & 0x01, \
35 .d = (flags >> 14) & 0x01, \
36 .g = (flags >> 15) & 0x01, \
37 }
42 38
43enum { 39enum {
44 GATE_INTERRUPT = 0xE, 40 GATE_INTERRUPT = 0xE,
@@ -47,49 +43,63 @@ enum {
47 GATE_TASK = 0x5, 43 GATE_TASK = 0x5,
48}; 44};
49 45
50/* 16byte gate */
51struct gate_struct64 {
52 u16 offset_low;
53 u16 segment;
54 unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
55 u16 offset_middle;
56 u32 offset_high;
57 u32 zero1;
58} __attribute__((packed));
59
60#define PTR_LOW(x) ((unsigned long long)(x) & 0xFFFF)
61#define PTR_MIDDLE(x) (((unsigned long long)(x) >> 16) & 0xFFFF)
62#define PTR_HIGH(x) ((unsigned long long)(x) >> 32)
63
64enum { 46enum {
65 DESC_TSS = 0x9, 47 DESC_TSS = 0x9,
66 DESC_LDT = 0x2, 48 DESC_LDT = 0x2,
67 DESCTYPE_S = 0x10, /* !system */ 49 DESCTYPE_S = 0x10, /* !system */
68}; 50};
69 51
70/* LDT or TSS descriptor in the GDT. 16 bytes. */ 52/* LDT or TSS descriptor in the GDT. */
71struct ldttss_desc64 { 53struct ldttss_desc {
72 u16 limit0; 54 u16 limit0;
73 u16 base0; 55 u16 base0;
74 unsigned base1 : 8, type : 5, dpl : 2, p : 1; 56
75 unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8; 57 u16 base1 : 8, type : 5, dpl : 2, p : 1;
76 u32 base3; 58 u16 limit1 : 4, zero0 : 3, g : 1, base2 : 8;
77 u32 zero1; 59#ifdef CONFIG_X86_64
60 u32 base3;
61 u32 zero1;
62#endif
78} __attribute__((packed)); 63} __attribute__((packed));
79 64
65typedef struct ldttss_desc ldt_desc;
66typedef struct ldttss_desc tss_desc;
67
68struct idt_bits {
69 u16 ist : 3,
70 zero : 5,
71 type : 5,
72 dpl : 2,
73 p : 1;
74} __attribute__((packed));
75
76struct gate_struct {
77 u16 offset_low;
78 u16 segment;
79 struct idt_bits bits;
80 u16 offset_middle;
81#ifdef CONFIG_X86_64
82 u32 offset_high;
83 u32 reserved;
84#endif
85} __attribute__((packed));
86
87typedef struct gate_struct gate_desc;
88
89static inline unsigned long gate_offset(const gate_desc *g)
90{
80#ifdef CONFIG_X86_64 91#ifdef CONFIG_X86_64
81typedef struct gate_struct64 gate_desc; 92 return g->offset_low | ((unsigned long)g->offset_middle << 16) |
82typedef struct ldttss_desc64 ldt_desc; 93 ((unsigned long) g->offset_high << 32);
83typedef struct ldttss_desc64 tss_desc;
84#define gate_offset(g) ((g).offset_low | ((unsigned long)(g).offset_middle << 16) | ((unsigned long)(g).offset_high << 32))
85#define gate_segment(g) ((g).segment)
86#else 94#else
87typedef struct desc_struct gate_desc; 95 return g->offset_low | ((unsigned long)g->offset_middle << 16);
88typedef struct desc_struct ldt_desc;
89typedef struct desc_struct tss_desc;
90#define gate_offset(g) (((g).b & 0xffff0000) | ((g).a & 0x0000ffff))
91#define gate_segment(g) ((g).a >> 16)
92#endif 96#endif
97}
98
99static inline unsigned long gate_segment(const gate_desc *g)
100{
101 return g->segment;
102}
93 103
94struct desc_ptr { 104struct desc_ptr {
95 unsigned short size; 105 unsigned short size;
diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h
index 07b06955a05d..aa15d1f7e530 100644
--- a/arch/x86/include/asm/entry_arch.h
+++ b/arch/x86/include/asm/entry_arch.h
@@ -13,20 +13,14 @@
13BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) 13BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
14BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) 14BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
15BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) 15BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR)
16BUILD_INTERRUPT3(irq_move_cleanup_interrupt, IRQ_MOVE_CLEANUP_VECTOR, 16BUILD_INTERRUPT(irq_move_cleanup_interrupt, IRQ_MOVE_CLEANUP_VECTOR)
17 smp_irq_move_cleanup_interrupt) 17BUILD_INTERRUPT(reboot_interrupt, REBOOT_VECTOR)
18BUILD_INTERRUPT3(reboot_interrupt, REBOOT_VECTOR, smp_reboot_interrupt)
19#endif 18#endif
20 19
21BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR)
22
23#ifdef CONFIG_HAVE_KVM 20#ifdef CONFIG_HAVE_KVM
24BUILD_INTERRUPT3(kvm_posted_intr_ipi, POSTED_INTR_VECTOR, 21BUILD_INTERRUPT(kvm_posted_intr_ipi, POSTED_INTR_VECTOR)
25 smp_kvm_posted_intr_ipi) 22BUILD_INTERRUPT(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR)
26BUILD_INTERRUPT3(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR, 23BUILD_INTERRUPT(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR)
27 smp_kvm_posted_intr_wakeup_ipi)
28BUILD_INTERRUPT3(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR,
29 smp_kvm_posted_intr_nested_ipi)
30#endif 24#endif
31 25
32/* 26/*
@@ -41,6 +35,7 @@ BUILD_INTERRUPT3(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR,
41BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) 35BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
42BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) 36BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
43BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) 37BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
38BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR)
44 39
45#ifdef CONFIG_IRQ_WORK 40#ifdef CONFIG_IRQ_WORK
46BUILD_INTERRUPT(irq_work_interrupt, IRQ_WORK_VECTOR) 41BUILD_INTERRUPT(irq_work_interrupt, IRQ_WORK_VECTOR)
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index d6dbafbd4207..6dfe366a8804 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -46,26 +46,6 @@ extern asmlinkage void deferred_error_interrupt(void);
46extern asmlinkage void call_function_interrupt(void); 46extern asmlinkage void call_function_interrupt(void);
47extern asmlinkage void call_function_single_interrupt(void); 47extern asmlinkage void call_function_single_interrupt(void);
48 48
49#ifdef CONFIG_TRACING
50/* Interrupt handlers registered during init_IRQ */
51extern void trace_apic_timer_interrupt(void);
52extern void trace_x86_platform_ipi(void);
53extern void trace_error_interrupt(void);
54extern void trace_irq_work_interrupt(void);
55extern void trace_spurious_interrupt(void);
56extern void trace_thermal_interrupt(void);
57extern void trace_reschedule_interrupt(void);
58extern void trace_threshold_interrupt(void);
59extern void trace_deferred_error_interrupt(void);
60extern void trace_call_function_interrupt(void);
61extern void trace_call_function_single_interrupt(void);
62#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt
63#define trace_reboot_interrupt reboot_interrupt
64#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi
65#define trace_kvm_posted_intr_wakeup_ipi kvm_posted_intr_wakeup_ipi
66#define trace_kvm_posted_intr_nested_ipi kvm_posted_intr_nested_ipi
67#endif /* CONFIG_TRACING */
68
69#ifdef CONFIG_X86_LOCAL_APIC 49#ifdef CONFIG_X86_LOCAL_APIC
70struct irq_data; 50struct irq_data;
71struct pci_dev; 51struct pci_dev;
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index 668cca540025..9958ceea2fa3 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -42,10 +42,6 @@ extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs);
42 42
43extern __visible unsigned int do_IRQ(struct pt_regs *regs); 43extern __visible unsigned int do_IRQ(struct pt_regs *regs);
44 44
45/* Interrupt vector management */
46extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
47extern int vector_used_by_percpu_irq(unsigned int vector);
48
49extern void init_ISA_irqs(void); 45extern void init_ISA_irqs(void);
50 46
51#ifdef CONFIG_X86_LOCAL_APIC 47#ifdef CONFIG_X86_LOCAL_APIC
diff --git a/arch/x86/include/asm/irq_work.h b/arch/x86/include/asm/irq_work.h
index f70604125286..ddbb8ea0f5a9 100644
--- a/arch/x86/include/asm/irq_work.h
+++ b/arch/x86/include/asm/irq_work.h
@@ -3,9 +3,17 @@
3 3
4#include <asm/cpufeature.h> 4#include <asm/cpufeature.h>
5 5
6#ifdef CONFIG_X86_LOCAL_APIC
6static inline bool arch_irq_work_has_interrupt(void) 7static inline bool arch_irq_work_has_interrupt(void)
7{ 8{
8 return boot_cpu_has(X86_FEATURE_APIC); 9 return boot_cpu_has(X86_FEATURE_APIC);
9} 10}
11extern void arch_irq_work_raise(void);
12#else
13static inline bool arch_irq_work_has_interrupt(void)
14{
15 return false;
16}
17#endif
10 18
11#endif /* _ASM_IRQ_WORK_H */ 19#endif /* _ASM_IRQ_WORK_H */
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 9ccac1926587..c25dd22f7c70 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -960,11 +960,6 @@ extern void default_banner(void);
960#define GET_CR2_INTO_RAX \ 960#define GET_CR2_INTO_RAX \
961 call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2) 961 call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2)
962 962
963#define PARAVIRT_ADJUST_EXCEPTION_FRAME \
964 PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_adjust_exception_frame), \
965 CLBR_NONE, \
966 call PARA_INDIRECT(pv_irq_ops+PV_IRQ_adjust_exception_frame))
967
968#define USERGS_SYSRET64 \ 963#define USERGS_SYSRET64 \
969 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64), \ 964 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64), \
970 CLBR_NONE, \ 965 CLBR_NONE, \
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index 9ffc36bfe4cd..6b64fc6367f2 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -196,9 +196,6 @@ struct pv_irq_ops {
196 void (*safe_halt)(void); 196 void (*safe_halt)(void);
197 void (*halt)(void); 197 void (*halt)(void);
198 198
199#ifdef CONFIG_X86_64
200 void (*adjust_exception_frame)(void);
201#endif
202} __no_randomize_layout; 199} __no_randomize_layout;
203 200
204struct pv_mmu_ops { 201struct pv_mmu_ops {
diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h
index 8d3964fc5f91..b408b1886195 100644
--- a/arch/x86/include/asm/proto.h
+++ b/arch/x86/include/asm/proto.h
@@ -24,6 +24,9 @@ void entry_SYSENTER_compat(void);
24void __end_entry_SYSENTER_compat(void); 24void __end_entry_SYSENTER_compat(void);
25void entry_SYSCALL_compat(void); 25void entry_SYSCALL_compat(void);
26void entry_INT80_compat(void); 26void entry_INT80_compat(void);
27#if defined(CONFIG_X86_64) && defined(CONFIG_XEN_PV)
28void xen_entry_INT80_compat(void);
29#endif
27#endif 30#endif
28 31
29void x86_configure_nx(void); 32void x86_configure_nx(void);
diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h
index 1549caa098f0..066aaf813141 100644
--- a/arch/x86/include/asm/segment.h
+++ b/arch/x86/include/asm/segment.h
@@ -238,9 +238,7 @@
238#ifndef __ASSEMBLY__ 238#ifndef __ASSEMBLY__
239 239
240extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; 240extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE];
241#ifdef CONFIG_TRACING 241extern void early_ignore_irq(void);
242# define trace_early_idt_handler_array early_idt_handler_array
243#endif
244 242
245/* 243/*
246 * Load a segment. Fall back on loading the zero segment if something goes 244 * Load a segment. Fall back on loading the zero segment if something goes
diff --git a/arch/x86/include/asm/trace/common.h b/arch/x86/include/asm/trace/common.h
new file mode 100644
index 000000000000..57c8da027d99
--- /dev/null
+++ b/arch/x86/include/asm/trace/common.h
@@ -0,0 +1,16 @@
1#ifndef _ASM_TRACE_COMMON_H
2#define _ASM_TRACE_COMMON_H
3
4#ifdef CONFIG_TRACING
5DECLARE_STATIC_KEY_FALSE(trace_pagefault_key);
6#define trace_pagefault_enabled() \
7 static_branch_unlikely(&trace_pagefault_key)
8DECLARE_STATIC_KEY_FALSE(trace_resched_ipi_key);
9#define trace_resched_ipi_enabled() \
10 static_branch_unlikely(&trace_resched_ipi_key)
11#else
12static inline bool trace_pagefault_enabled(void) { return false; }
13static inline bool trace_resched_ipi_enabled(void) { return false; }
14#endif
15
16#endif
diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h
index 2422b14c50a7..5665bf205b8d 100644
--- a/arch/x86/include/asm/trace/exceptions.h
+++ b/arch/x86/include/asm/trace/exceptions.h
@@ -5,9 +5,10 @@
5#define _TRACE_PAGE_FAULT_H 5#define _TRACE_PAGE_FAULT_H
6 6
7#include <linux/tracepoint.h> 7#include <linux/tracepoint.h>
8#include <asm/trace/common.h>
8 9
9extern int trace_irq_vector_regfunc(void); 10extern int trace_pagefault_reg(void);
10extern void trace_irq_vector_unregfunc(void); 11extern void trace_pagefault_unreg(void);
11 12
12DECLARE_EVENT_CLASS(x86_exceptions, 13DECLARE_EVENT_CLASS(x86_exceptions,
13 14
@@ -37,8 +38,7 @@ DEFINE_EVENT_FN(x86_exceptions, name, \
37 TP_PROTO(unsigned long address, struct pt_regs *regs, \ 38 TP_PROTO(unsigned long address, struct pt_regs *regs, \
38 unsigned long error_code), \ 39 unsigned long error_code), \
39 TP_ARGS(address, regs, error_code), \ 40 TP_ARGS(address, regs, error_code), \
40 trace_irq_vector_regfunc, \ 41 trace_pagefault_reg, trace_pagefault_unreg);
41 trace_irq_vector_unregfunc);
42 42
43DEFINE_PAGE_FAULT_EVENT(page_fault_user); 43DEFINE_PAGE_FAULT_EVENT(page_fault_user);
44DEFINE_PAGE_FAULT_EVENT(page_fault_kernel); 44DEFINE_PAGE_FAULT_EVENT(page_fault_kernel);
diff --git a/arch/x86/include/asm/trace/irq_vectors.h b/arch/x86/include/asm/trace/irq_vectors.h
index 32dd6a9e343c..1599d394c8c1 100644
--- a/arch/x86/include/asm/trace/irq_vectors.h
+++ b/arch/x86/include/asm/trace/irq_vectors.h
@@ -5,9 +5,12 @@
5#define _TRACE_IRQ_VECTORS_H 5#define _TRACE_IRQ_VECTORS_H
6 6
7#include <linux/tracepoint.h> 7#include <linux/tracepoint.h>
8#include <asm/trace/common.h>
8 9
9extern int trace_irq_vector_regfunc(void); 10#ifdef CONFIG_X86_LOCAL_APIC
10extern void trace_irq_vector_unregfunc(void); 11
12extern int trace_resched_ipi_reg(void);
13extern void trace_resched_ipi_unreg(void);
11 14
12DECLARE_EVENT_CLASS(x86_irq_vector, 15DECLARE_EVENT_CLASS(x86_irq_vector,
13 16
@@ -28,15 +31,22 @@ DECLARE_EVENT_CLASS(x86_irq_vector,
28#define DEFINE_IRQ_VECTOR_EVENT(name) \ 31#define DEFINE_IRQ_VECTOR_EVENT(name) \
29DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ 32DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \
30 TP_PROTO(int vector), \ 33 TP_PROTO(int vector), \
34 TP_ARGS(vector), NULL, NULL); \
35DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \
36 TP_PROTO(int vector), \
37 TP_ARGS(vector), NULL, NULL);
38
39#define DEFINE_RESCHED_IPI_EVENT(name) \
40DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \
41 TP_PROTO(int vector), \
31 TP_ARGS(vector), \ 42 TP_ARGS(vector), \
32 trace_irq_vector_regfunc, \ 43 trace_resched_ipi_reg, \
33 trace_irq_vector_unregfunc); \ 44 trace_resched_ipi_unreg); \
34DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ 45DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \
35 TP_PROTO(int vector), \ 46 TP_PROTO(int vector), \
36 TP_ARGS(vector), \ 47 TP_ARGS(vector), \
37 trace_irq_vector_regfunc, \ 48 trace_resched_ipi_reg, \
38 trace_irq_vector_unregfunc); 49 trace_resched_ipi_unreg);
39
40 50
41/* 51/*
42 * local_timer - called when entering/exiting a local timer interrupt 52 * local_timer - called when entering/exiting a local timer interrupt
@@ -45,11 +55,6 @@ DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \
45DEFINE_IRQ_VECTOR_EVENT(local_timer); 55DEFINE_IRQ_VECTOR_EVENT(local_timer);
46 56
47/* 57/*
48 * reschedule - called when entering/exiting a reschedule vector handler
49 */
50DEFINE_IRQ_VECTOR_EVENT(reschedule);
51
52/*
53 * spurious_apic - called when entering/exiting a spurious apic vector handler 58 * spurious_apic - called when entering/exiting a spurious apic vector handler
54 */ 59 */
55DEFINE_IRQ_VECTOR_EVENT(spurious_apic); 60DEFINE_IRQ_VECTOR_EVENT(spurious_apic);
@@ -65,6 +70,7 @@ DEFINE_IRQ_VECTOR_EVENT(error_apic);
65 */ 70 */
66DEFINE_IRQ_VECTOR_EVENT(x86_platform_ipi); 71DEFINE_IRQ_VECTOR_EVENT(x86_platform_ipi);
67 72
73#ifdef CONFIG_IRQ_WORK
68/* 74/*
69 * irq_work - called when entering/exiting a irq work interrupt 75 * irq_work - called when entering/exiting a irq work interrupt
70 * vector handler 76 * vector handler
@@ -81,6 +87,18 @@ DEFINE_IRQ_VECTOR_EVENT(irq_work);
81 * 4) goto 1 87 * 4) goto 1
82 */ 88 */
83TRACE_EVENT_PERF_PERM(irq_work_exit, is_sampling_event(p_event) ? -EPERM : 0); 89TRACE_EVENT_PERF_PERM(irq_work_exit, is_sampling_event(p_event) ? -EPERM : 0);
90#endif
91
92/*
93 * The ifdef is required because that tracepoint macro hell emits tracepoint
94 * code in files which include this header even if the tracepoint is not
95 * enabled. Brilliant stuff that.
96 */
97#ifdef CONFIG_SMP
98/*
99 * reschedule - called when entering/exiting a reschedule vector handler
100 */
101DEFINE_RESCHED_IPI_EVENT(reschedule);
84 102
85/* 103/*
86 * call_function - called when entering/exiting a call function interrupt 104 * call_function - called when entering/exiting a call function interrupt
@@ -93,24 +111,33 @@ DEFINE_IRQ_VECTOR_EVENT(call_function);
93 * single interrupt vector handler 111 * single interrupt vector handler
94 */ 112 */
95DEFINE_IRQ_VECTOR_EVENT(call_function_single); 113DEFINE_IRQ_VECTOR_EVENT(call_function_single);
114#endif
96 115
116#ifdef CONFIG_X86_MCE_THRESHOLD
97/* 117/*
98 * threshold_apic - called when entering/exiting a threshold apic interrupt 118 * threshold_apic - called when entering/exiting a threshold apic interrupt
99 * vector handler 119 * vector handler
100 */ 120 */
101DEFINE_IRQ_VECTOR_EVENT(threshold_apic); 121DEFINE_IRQ_VECTOR_EVENT(threshold_apic);
122#endif
102 123
124#ifdef CONFIG_X86_MCE_AMD
103/* 125/*
104 * deferred_error_apic - called when entering/exiting a deferred apic interrupt 126 * deferred_error_apic - called when entering/exiting a deferred apic interrupt
105 * vector handler 127 * vector handler
106 */ 128 */
107DEFINE_IRQ_VECTOR_EVENT(deferred_error_apic); 129DEFINE_IRQ_VECTOR_EVENT(deferred_error_apic);
130#endif
108 131
132#ifdef CONFIG_X86_THERMAL_VECTOR
109/* 133/*
110 * thermal_apic - called when entering/exiting a thermal apic interrupt 134 * thermal_apic - called when entering/exiting a thermal apic interrupt
111 * vector handler 135 * vector handler
112 */ 136 */
113DEFINE_IRQ_VECTOR_EVENT(thermal_apic); 137DEFINE_IRQ_VECTOR_EVENT(thermal_apic);
138#endif
139
140#endif /* CONFIG_X86_LOCAL_APIC */
114 141
115#undef TRACE_INCLUDE_PATH 142#undef TRACE_INCLUDE_PATH
116#define TRACE_INCLUDE_PATH . 143#define TRACE_INCLUDE_PATH .
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index 01fd0a7f48cd..5545f6459bf5 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -13,9 +13,6 @@ asmlinkage void divide_error(void);
13asmlinkage void debug(void); 13asmlinkage void debug(void);
14asmlinkage void nmi(void); 14asmlinkage void nmi(void);
15asmlinkage void int3(void); 15asmlinkage void int3(void);
16asmlinkage void xen_debug(void);
17asmlinkage void xen_int3(void);
18asmlinkage void xen_stack_segment(void);
19asmlinkage void overflow(void); 16asmlinkage void overflow(void);
20asmlinkage void bounds(void); 17asmlinkage void bounds(void);
21asmlinkage void invalid_op(void); 18asmlinkage void invalid_op(void);
@@ -38,22 +35,29 @@ asmlinkage void machine_check(void);
38#endif /* CONFIG_X86_MCE */ 35#endif /* CONFIG_X86_MCE */
39asmlinkage void simd_coprocessor_error(void); 36asmlinkage void simd_coprocessor_error(void);
40 37
41#ifdef CONFIG_TRACING 38#if defined(CONFIG_X86_64) && defined(CONFIG_XEN_PV)
42asmlinkage void trace_page_fault(void); 39asmlinkage void xen_divide_error(void);
43#define trace_stack_segment stack_segment 40asmlinkage void xen_xendebug(void);
44#define trace_divide_error divide_error 41asmlinkage void xen_xenint3(void);
45#define trace_bounds bounds 42asmlinkage void xen_nmi(void);
46#define trace_invalid_op invalid_op 43asmlinkage void xen_overflow(void);
47#define trace_device_not_available device_not_available 44asmlinkage void xen_bounds(void);
48#define trace_coprocessor_segment_overrun coprocessor_segment_overrun 45asmlinkage void xen_invalid_op(void);
49#define trace_invalid_TSS invalid_TSS 46asmlinkage void xen_device_not_available(void);
50#define trace_segment_not_present segment_not_present 47asmlinkage void xen_double_fault(void);
51#define trace_general_protection general_protection 48asmlinkage void xen_coprocessor_segment_overrun(void);
52#define trace_spurious_interrupt_bug spurious_interrupt_bug 49asmlinkage void xen_invalid_TSS(void);
53#define trace_coprocessor_error coprocessor_error 50asmlinkage void xen_segment_not_present(void);
54#define trace_alignment_check alignment_check 51asmlinkage void xen_stack_segment(void);
55#define trace_simd_coprocessor_error simd_coprocessor_error 52asmlinkage void xen_general_protection(void);
56#define trace_async_page_fault async_page_fault 53asmlinkage void xen_page_fault(void);
54asmlinkage void xen_spurious_interrupt_bug(void);
55asmlinkage void xen_coprocessor_error(void);
56asmlinkage void xen_alignment_check(void);
57#ifdef CONFIG_X86_MCE
58asmlinkage void xen_machine_check(void);
59#endif /* CONFIG_X86_MCE */
60asmlinkage void xen_simd_coprocessor_error(void);
57#endif 61#endif
58 62
59dotraplinkage void do_divide_error(struct pt_regs *, long); 63dotraplinkage void do_divide_error(struct pt_regs *, long);
@@ -74,14 +78,6 @@ asmlinkage struct pt_regs *sync_regs(struct pt_regs *);
74#endif 78#endif
75dotraplinkage void do_general_protection(struct pt_regs *, long); 79dotraplinkage void do_general_protection(struct pt_regs *, long);
76dotraplinkage void do_page_fault(struct pt_regs *, unsigned long); 80dotraplinkage void do_page_fault(struct pt_regs *, unsigned long);
77#ifdef CONFIG_TRACING
78dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long);
79#else
80static inline void trace_do_page_fault(struct pt_regs *regs, unsigned long error)
81{
82 do_page_fault(regs, error);
83}
84#endif
85dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long); 81dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long);
86dotraplinkage void do_coprocessor_error(struct pt_regs *, long); 82dotraplinkage void do_coprocessor_error(struct pt_regs *, long);
87dotraplinkage void do_alignment_check(struct pt_regs *, long); 83dotraplinkage void do_alignment_check(struct pt_regs *, long);
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 11071fcd630e..9606688caa4b 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -552,6 +552,8 @@ static inline void
552MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr, 552MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr,
553 struct desc_struct desc) 553 struct desc_struct desc)
554{ 554{
555 u32 *p = (u32 *) &desc;
556
555 mcl->op = __HYPERVISOR_update_descriptor; 557 mcl->op = __HYPERVISOR_update_descriptor;
556 if (sizeof(maddr) == sizeof(long)) { 558 if (sizeof(maddr) == sizeof(long)) {
557 mcl->args[0] = maddr; 559 mcl->args[0] = maddr;
@@ -559,8 +561,8 @@ MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr,
559 } else { 561 } else {
560 mcl->args[0] = maddr; 562 mcl->args[0] = maddr;
561 mcl->args[1] = maddr >> 32; 563 mcl->args[1] = maddr >> 32;
562 mcl->args[2] = desc.a; 564 mcl->args[2] = *p++;
563 mcl->args[3] = desc.b; 565 mcl->args[3] = *p;
564 } 566 }
565 567
566 trace_xen_mc_entry(mcl, sizeof(maddr) == sizeof(long) ? 2 : 4); 568 trace_xen_mc_entry(mcl, sizeof(maddr) == sizeof(long) ? 2 : 4);
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 287eac7d207f..fd0a7895b63f 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -42,7 +42,7 @@ CFLAGS_irq.o := -I$(src)/../include/asm/trace
42 42
43obj-y := process_$(BITS).o signal.o 43obj-y := process_$(BITS).o signal.o
44obj-$(CONFIG_COMPAT) += signal_compat.o 44obj-$(CONFIG_COMPAT) += signal_compat.o
45obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o 45obj-y += traps.o idt.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
46obj-y += time.o ioport.o dumpstack.o nmi.o 46obj-y += time.o ioport.o dumpstack.o nmi.o
47obj-$(CONFIG_MODIFY_LDT_SYSCALL) += ldt.o 47obj-$(CONFIG_MODIFY_LDT_SYSCALL) += ldt.o
48obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o 48obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o
@@ -111,6 +111,7 @@ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o
111obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o 111obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o
112obj-$(CONFIG_X86_PMEM_LEGACY_DEVICE) += pmem.o 112obj-$(CONFIG_X86_PMEM_LEGACY_DEVICE) += pmem.o
113 113
114obj-$(CONFIG_EISA) += eisa.o
114obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o 115obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o
115 116
116obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o 117obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 98b3dd8cf2bf..7834f73efbf1 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -177,8 +177,6 @@ static int disable_apic_timer __initdata;
177int local_apic_timer_c2_ok; 177int local_apic_timer_c2_ok;
178EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); 178EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
179 179
180int first_system_vector = FIRST_SYSTEM_VECTOR;
181
182/* 180/*
183 * Debug level, exported for io_apic.c 181 * Debug level, exported for io_apic.c
184 */ 182 */
@@ -599,9 +597,13 @@ static const struct x86_cpu_id deadline_match[] = {
599 597
600static void apic_check_deadline_errata(void) 598static void apic_check_deadline_errata(void)
601{ 599{
602 const struct x86_cpu_id *m = x86_match_cpu(deadline_match); 600 const struct x86_cpu_id *m;
603 u32 rev; 601 u32 rev;
604 602
603 if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER))
604 return;
605
606 m = x86_match_cpu(deadline_match);
605 if (!m) 607 if (!m)
606 return; 608 return;
607 609
@@ -990,8 +992,7 @@ void setup_secondary_APIC_clock(void)
990 */ 992 */
991static void local_apic_timer_interrupt(void) 993static void local_apic_timer_interrupt(void)
992{ 994{
993 int cpu = smp_processor_id(); 995 struct clock_event_device *evt = this_cpu_ptr(&lapic_events);
994 struct clock_event_device *evt = &per_cpu(lapic_events, cpu);
995 996
996 /* 997 /*
997 * Normally we should not be here till LAPIC has been initialized but 998 * Normally we should not be here till LAPIC has been initialized but
@@ -1005,7 +1006,8 @@ static void local_apic_timer_interrupt(void)
1005 * spurious. 1006 * spurious.
1006 */ 1007 */
1007 if (!evt->event_handler) { 1008 if (!evt->event_handler) {
1008 pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", cpu); 1009 pr_warning("Spurious LAPIC timer interrupt on cpu %d\n",
1010 smp_processor_id());
1009 /* Switch it off */ 1011 /* Switch it off */
1010 lapic_timer_shutdown(evt); 1012 lapic_timer_shutdown(evt);
1011 return; 1013 return;
@@ -1040,25 +1042,6 @@ __visible void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs)
1040 * interrupt lock, which is the WrongThing (tm) to do. 1042 * interrupt lock, which is the WrongThing (tm) to do.
1041 */ 1043 */
1042 entering_ack_irq(); 1044 entering_ack_irq();
1043 local_apic_timer_interrupt();
1044 exiting_irq();
1045
1046 set_irq_regs(old_regs);
1047}
1048
1049__visible void __irq_entry smp_trace_apic_timer_interrupt(struct pt_regs *regs)
1050{
1051 struct pt_regs *old_regs = set_irq_regs(regs);
1052
1053 /*
1054 * NOTE! We'd better ACK the irq immediately,
1055 * because timer handling can be slow.
1056 *
1057 * update_process_times() expects us to have done irq_enter().
1058 * Besides, if we don't timer interrupts ignore the global
1059 * interrupt lock, which is the WrongThing (tm) to do.
1060 */
1061 entering_ack_irq();
1062 trace_local_timer_entry(LOCAL_TIMER_VECTOR); 1045 trace_local_timer_entry(LOCAL_TIMER_VECTOR);
1063 local_apic_timer_interrupt(); 1046 local_apic_timer_interrupt();
1064 trace_local_timer_exit(LOCAL_TIMER_VECTOR); 1047 trace_local_timer_exit(LOCAL_TIMER_VECTOR);
@@ -1920,10 +1903,14 @@ void __init register_lapic_address(unsigned long address)
1920/* 1903/*
1921 * This interrupt should _never_ happen with our APIC/SMP architecture 1904 * This interrupt should _never_ happen with our APIC/SMP architecture
1922 */ 1905 */
1923static void __smp_spurious_interrupt(u8 vector) 1906__visible void __irq_entry smp_spurious_interrupt(struct pt_regs *regs)
1924{ 1907{
1908 u8 vector = ~regs->orig_ax;
1925 u32 v; 1909 u32 v;
1926 1910
1911 entering_irq();
1912 trace_spurious_apic_entry(vector);
1913
1927 /* 1914 /*
1928 * Check if this really is a spurious interrupt and ACK it 1915 * Check if this really is a spurious interrupt and ACK it
1929 * if it is a vectored one. Just in case... 1916 * if it is a vectored one. Just in case...
@@ -1938,22 +1925,7 @@ static void __smp_spurious_interrupt(u8 vector)
1938 /* see sw-dev-man vol 3, chapter 7.4.13.5 */ 1925 /* see sw-dev-man vol 3, chapter 7.4.13.5 */
1939 pr_info("spurious APIC interrupt through vector %02x on CPU#%d, " 1926 pr_info("spurious APIC interrupt through vector %02x on CPU#%d, "
1940 "should never happen.\n", vector, smp_processor_id()); 1927 "should never happen.\n", vector, smp_processor_id());
1941}
1942 1928
1943__visible void __irq_entry smp_spurious_interrupt(struct pt_regs *regs)
1944{
1945 entering_irq();
1946 __smp_spurious_interrupt(~regs->orig_ax);
1947 exiting_irq();
1948}
1949
1950__visible void __irq_entry smp_trace_spurious_interrupt(struct pt_regs *regs)
1951{
1952 u8 vector = ~regs->orig_ax;
1953
1954 entering_irq();
1955 trace_spurious_apic_entry(vector);
1956 __smp_spurious_interrupt(vector);
1957 trace_spurious_apic_exit(vector); 1929 trace_spurious_apic_exit(vector);
1958 exiting_irq(); 1930 exiting_irq();
1959} 1931}
@@ -1961,10 +1933,8 @@ __visible void __irq_entry smp_trace_spurious_interrupt(struct pt_regs *regs)
1961/* 1933/*
1962 * This interrupt should never happen with our APIC/SMP architecture 1934 * This interrupt should never happen with our APIC/SMP architecture
1963 */ 1935 */
1964static void __smp_error_interrupt(struct pt_regs *regs) 1936__visible void __irq_entry smp_error_interrupt(struct pt_regs *regs)
1965{ 1937{
1966 u32 v;
1967 u32 i = 0;
1968 static const char * const error_interrupt_reason[] = { 1938 static const char * const error_interrupt_reason[] = {
1969 "Send CS error", /* APIC Error Bit 0 */ 1939 "Send CS error", /* APIC Error Bit 0 */
1970 "Receive CS error", /* APIC Error Bit 1 */ 1940 "Receive CS error", /* APIC Error Bit 1 */
@@ -1975,6 +1945,10 @@ static void __smp_error_interrupt(struct pt_regs *regs)
1975 "Received illegal vector", /* APIC Error Bit 6 */ 1945 "Received illegal vector", /* APIC Error Bit 6 */
1976 "Illegal register address", /* APIC Error Bit 7 */ 1946 "Illegal register address", /* APIC Error Bit 7 */
1977 }; 1947 };
1948 u32 v, i = 0;
1949
1950 entering_irq();
1951 trace_error_apic_entry(ERROR_APIC_VECTOR);
1978 1952
1979 /* First tickle the hardware, only then report what went on. -- REW */ 1953 /* First tickle the hardware, only then report what went on. -- REW */
1980 if (lapic_get_maxlvt() > 3) /* Due to the Pentium erratum 3AP. */ 1954 if (lapic_get_maxlvt() > 3) /* Due to the Pentium erratum 3AP. */
@@ -1996,20 +1970,6 @@ static void __smp_error_interrupt(struct pt_regs *regs)
1996 1970
1997 apic_printk(APIC_DEBUG, KERN_CONT "\n"); 1971 apic_printk(APIC_DEBUG, KERN_CONT "\n");
1998 1972
1999}
2000
2001__visible void __irq_entry smp_error_interrupt(struct pt_regs *regs)
2002{
2003 entering_irq();
2004 __smp_error_interrupt(regs);
2005 exiting_irq();
2006}
2007
2008__visible void __irq_entry smp_trace_error_interrupt(struct pt_regs *regs)
2009{
2010 entering_irq();
2011 trace_error_apic_entry(ERROR_APIC_VECTOR);
2012 __smp_error_interrupt(regs);
2013 trace_error_apic_exit(ERROR_APIC_VECTOR); 1973 trace_error_apic_exit(ERROR_APIC_VECTOR);
2014 exiting_irq(); 1974 exiting_irq();
2015} 1975}
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 237e9c2341c7..70e48aa6af98 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1243,7 +1243,7 @@ static void io_apic_print_entries(unsigned int apic, unsigned int nr_entries)
1243 entry.vector, entry.irr, entry.delivery_status); 1243 entry.vector, entry.irr, entry.delivery_status);
1244 if (ir_entry->format) 1244 if (ir_entry->format)
1245 printk(KERN_DEBUG "%s, remapped, I(%04X), Z(%X)\n", 1245 printk(KERN_DEBUG "%s, remapped, I(%04X), Z(%X)\n",
1246 buf, (ir_entry->index << 15) | ir_entry->index, 1246 buf, (ir_entry->index2 << 15) | ir_entry->index,
1247 ir_entry->zero); 1247 ir_entry->zero);
1248 else 1248 else
1249 printk(KERN_DEBUG "%s, %s, D(%02X), M(%1d)\n", 1249 printk(KERN_DEBUG "%s, %s, D(%02X), M(%1d)\n",
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index b3af457ed667..88c214e75a6b 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -166,7 +166,7 @@ static int __assign_irq_vector(int irq, struct apic_chip_data *d,
166 offset = current_offset; 166 offset = current_offset;
167next: 167next:
168 vector += 16; 168 vector += 16;
169 if (vector >= first_system_vector) { 169 if (vector >= FIRST_SYSTEM_VECTOR) {
170 offset = (offset + 1) % 16; 170 offset = (offset + 1) % 16;
171 vector = FIRST_EXTERNAL_VECTOR + offset; 171 vector = FIRST_EXTERNAL_VECTOR + offset;
172 } 172 }
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
index 99332f550c48..cf42206926af 100644
--- a/arch/x86/kernel/asm-offsets_64.c
+++ b/arch/x86/kernel/asm-offsets_64.c
@@ -20,7 +20,6 @@ static char syscalls_ia32[] = {
20int main(void) 20int main(void)
21{ 21{
22#ifdef CONFIG_PARAVIRT 22#ifdef CONFIG_PARAVIRT
23 OFFSET(PV_IRQ_adjust_exception_frame, pv_irq_ops, adjust_exception_frame);
24 OFFSET(PV_CPU_usergs_sysret64, pv_cpu_ops, usergs_sysret64); 23 OFFSET(PV_CPU_usergs_sysret64, pv_cpu_ops, usergs_sysret64);
25 OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs); 24 OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs);
26 BLANK(); 25 BLANK();
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index b95cd94ca97b..efba8e3da3e2 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1329,15 +1329,6 @@ static __init int setup_disablecpuid(char *arg)
1329__setup("clearcpuid=", setup_disablecpuid); 1329__setup("clearcpuid=", setup_disablecpuid);
1330 1330
1331#ifdef CONFIG_X86_64 1331#ifdef CONFIG_X86_64
1332struct desc_ptr idt_descr __ro_after_init = {
1333 .size = NR_VECTORS * 16 - 1,
1334 .address = (unsigned long) idt_table,
1335};
1336const struct desc_ptr debug_idt_descr = {
1337 .size = NR_VECTORS * 16 - 1,
1338 .address = (unsigned long) debug_idt_table,
1339};
1340
1341DEFINE_PER_CPU_FIRST(union irq_stack_union, 1332DEFINE_PER_CPU_FIRST(union irq_stack_union,
1342 irq_stack_union) __aligned(PAGE_SIZE) __visible; 1333 irq_stack_union) __aligned(PAGE_SIZE) __visible;
1343 1334
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index 5ce1a5689162..40e28ed77fbf 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -771,24 +771,12 @@ static void __log_error(unsigned int bank, u64 status, u64 addr, u64 misc)
771 mce_log(&m); 771 mce_log(&m);
772} 772}
773 773
774static inline void __smp_deferred_error_interrupt(void)
775{
776 inc_irq_stat(irq_deferred_error_count);
777 deferred_error_int_vector();
778}
779
780asmlinkage __visible void __irq_entry smp_deferred_error_interrupt(void) 774asmlinkage __visible void __irq_entry smp_deferred_error_interrupt(void)
781{ 775{
782 entering_irq(); 776 entering_irq();
783 __smp_deferred_error_interrupt();
784 exiting_ack_irq();
785}
786
787asmlinkage __visible void __irq_entry smp_trace_deferred_error_interrupt(void)
788{
789 entering_irq();
790 trace_deferred_error_apic_entry(DEFERRED_ERROR_VECTOR); 777 trace_deferred_error_apic_entry(DEFERRED_ERROR_VECTOR);
791 __smp_deferred_error_interrupt(); 778 inc_irq_stat(irq_deferred_error_count);
779 deferred_error_int_vector();
792 trace_deferred_error_apic_exit(DEFERRED_ERROR_VECTOR); 780 trace_deferred_error_apic_exit(DEFERRED_ERROR_VECTOR);
793 exiting_ack_irq(); 781 exiting_ack_irq();
794} 782}
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c
index f7370abd33c6..2da67b70ba98 100644
--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
+++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
@@ -390,26 +390,12 @@ static void unexpected_thermal_interrupt(void)
390 390
391static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt; 391static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt;
392 392
393static inline void __smp_thermal_interrupt(void) 393asmlinkage __visible void __irq_entry smp_thermal_interrupt(struct pt_regs *r)
394{
395 inc_irq_stat(irq_thermal_count);
396 smp_thermal_vector();
397}
398
399asmlinkage __visible void __irq_entry
400smp_thermal_interrupt(struct pt_regs *regs)
401{
402 entering_irq();
403 __smp_thermal_interrupt();
404 exiting_ack_irq();
405}
406
407asmlinkage __visible void __irq_entry
408smp_trace_thermal_interrupt(struct pt_regs *regs)
409{ 394{
410 entering_irq(); 395 entering_irq();
411 trace_thermal_apic_entry(THERMAL_APIC_VECTOR); 396 trace_thermal_apic_entry(THERMAL_APIC_VECTOR);
412 __smp_thermal_interrupt(); 397 inc_irq_stat(irq_thermal_count);
398 smp_thermal_vector();
413 trace_thermal_apic_exit(THERMAL_APIC_VECTOR); 399 trace_thermal_apic_exit(THERMAL_APIC_VECTOR);
414 exiting_ack_irq(); 400 exiting_ack_irq();
415} 401}
diff --git a/arch/x86/kernel/cpu/mcheck/threshold.c b/arch/x86/kernel/cpu/mcheck/threshold.c
index bb0e75eed10a..5e7249e42f8f 100644
--- a/arch/x86/kernel/cpu/mcheck/threshold.c
+++ b/arch/x86/kernel/cpu/mcheck/threshold.c
@@ -17,24 +17,12 @@ static void default_threshold_interrupt(void)
17 17
18void (*mce_threshold_vector)(void) = default_threshold_interrupt; 18void (*mce_threshold_vector)(void) = default_threshold_interrupt;
19 19
20static inline void __smp_threshold_interrupt(void)
21{
22 inc_irq_stat(irq_threshold_count);
23 mce_threshold_vector();
24}
25
26asmlinkage __visible void __irq_entry smp_threshold_interrupt(void) 20asmlinkage __visible void __irq_entry smp_threshold_interrupt(void)
27{ 21{
28 entering_irq(); 22 entering_irq();
29 __smp_threshold_interrupt();
30 exiting_ack_irq();
31}
32
33asmlinkage __visible void __irq_entry smp_trace_threshold_interrupt(void)
34{
35 entering_irq();
36 trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR); 23 trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR);
37 __smp_threshold_interrupt(); 24 inc_irq_stat(irq_threshold_count);
25 mce_threshold_vector();
38 trace_threshold_apic_exit(THRESHOLD_APIC_VECTOR); 26 trace_threshold_apic_exit(THRESHOLD_APIC_VECTOR);
39 exiting_ack_irq(); 27 exiting_ack_irq();
40} 28}
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 70e717fccdd6..9fc32651c911 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -59,13 +59,8 @@ void hyperv_vector_handler(struct pt_regs *regs)
59void hv_setup_vmbus_irq(void (*handler)(void)) 59void hv_setup_vmbus_irq(void (*handler)(void))
60{ 60{
61 vmbus_handler = handler; 61 vmbus_handler = handler;
62 /* 62 /* Setup the IDT for hypervisor callback */
63 * Setup the IDT for hypervisor callback. Prevent reallocation 63 alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
64 * at module reload.
65 */
66 if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors))
67 alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
68 hyperv_callback_vector);
69} 64}
70 65
71void hv_remove_vmbus_irq(void) 66void hv_remove_vmbus_irq(void)
diff --git a/arch/x86/kernel/eisa.c b/arch/x86/kernel/eisa.c
new file mode 100644
index 000000000000..f260e452e4f8
--- /dev/null
+++ b/arch/x86/kernel/eisa.c
@@ -0,0 +1,19 @@
1/*
2 * EISA specific code
3 *
4 * This file is licensed under the GPL V2
5 */
6#include <linux/ioport.h>
7#include <linux/eisa.h>
8#include <linux/io.h>
9
10static __init int eisa_bus_probe(void)
11{
12 void __iomem *p = ioremap(0x0FFFD9, 4);
13
14 if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24))
15 EISA_bus = 1;
16 iounmap(p);
17 return 0;
18}
19subsys_initcall(eisa_bus_probe);
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index 538ec012b371..cf2ce063f65a 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -10,6 +10,7 @@
10#include <linux/mm.h> 10#include <linux/mm.h>
11#include <linux/memblock.h> 11#include <linux/memblock.h>
12 12
13#include <asm/desc.h>
13#include <asm/setup.h> 14#include <asm/setup.h>
14#include <asm/sections.h> 15#include <asm/sections.h>
15#include <asm/e820/api.h> 16#include <asm/e820/api.h>
@@ -30,6 +31,9 @@ static void __init i386_default_early_setup(void)
30asmlinkage __visible void __init i386_start_kernel(void) 31asmlinkage __visible void __init i386_start_kernel(void)
31{ 32{
32 cr4_init_shadow(); 33 cr4_init_shadow();
34
35 idt_setup_early_handler();
36
33 sanitize_boot_params(&boot_params); 37 sanitize_boot_params(&boot_params);
34 38
35 x86_early_init_platform_quirks(); 39 x86_early_init_platform_quirks();
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 6a193b93fd95..bab4fa579450 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -311,8 +311,6 @@ static void __init copy_bootdata(char *real_mode_data)
311 311
312asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) 312asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
313{ 313{
314 int i;
315
316 /* 314 /*
317 * Build-time sanity checks on the kernel image and module 315 * Build-time sanity checks on the kernel image and module
318 * area mappings. (these are purely build-time and produce no code) 316 * area mappings. (these are purely build-time and produce no code)
@@ -345,9 +343,7 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
345 343
346 kasan_early_init(); 344 kasan_early_init();
347 345
348 for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) 346 idt_setup_early_handler();
349 set_intr_gate(i, early_idt_handler_array[i]);
350 load_idt((const struct desc_ptr *)&idt_descr);
351 347
352 copy_bootdata(__va(real_mode_data)); 348 copy_bootdata(__va(real_mode_data));
353 349
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 29da9599fec0..9ed3074d0d27 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -345,7 +345,6 @@ ENTRY(startup_32_smp)
345 movl %eax,%cr0 345 movl %eax,%cr0
346 346
347 lgdt early_gdt_descr 347 lgdt early_gdt_descr
348 lidt idt_descr
349 ljmp $(__KERNEL_CS),$1f 348 ljmp $(__KERNEL_CS),$1f
3501: movl $(__KERNEL_DS),%eax # reload all the segment registers 3491: movl $(__KERNEL_DS),%eax # reload all the segment registers
351 movl %eax,%ss # after changing gdt. 350 movl %eax,%ss # after changing gdt.
@@ -378,37 +377,6 @@ ENDPROC(startup_32_smp)
378 */ 377 */
379__INIT 378__INIT
380setup_once: 379setup_once:
381 /*
382 * Set up a idt with 256 interrupt gates that push zero if there
383 * is no error code and then jump to early_idt_handler_common.
384 * It doesn't actually load the idt - that needs to be done on
385 * each CPU. Interrupts are enabled elsewhere, when we can be
386 * relatively sure everything is ok.
387 */
388
389 movl $idt_table,%edi
390 movl $early_idt_handler_array,%eax
391 movl $NUM_EXCEPTION_VECTORS,%ecx
3921:
393 movl %eax,(%edi)
394 movl %eax,4(%edi)
395 /* interrupt gate, dpl=0, present */
396 movl $(0x8E000000 + __KERNEL_CS),2(%edi)
397 addl $EARLY_IDT_HANDLER_SIZE,%eax
398 addl $8,%edi
399 loop 1b
400
401 movl $256 - NUM_EXCEPTION_VECTORS,%ecx
402 movl $ignore_int,%edx
403 movl $(__KERNEL_CS << 16),%eax
404 movw %dx,%ax /* selector = 0x0010 = cs */
405 movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
4062:
407 movl %eax,(%edi)
408 movl %edx,4(%edi)
409 addl $8,%edi
410 loop 2b
411
412#ifdef CONFIG_CC_STACKPROTECTOR 380#ifdef CONFIG_CC_STACKPROTECTOR
413 /* 381 /*
414 * Configure the stack canary. The linker can't handle this by 382 * Configure the stack canary. The linker can't handle this by
@@ -497,8 +465,7 @@ early_idt_handler_common:
497ENDPROC(early_idt_handler_common) 465ENDPROC(early_idt_handler_common)
498 466
499/* This is the default interrupt "handler" :-) */ 467/* This is the default interrupt "handler" :-) */
500 ALIGN 468ENTRY(early_ignore_irq)
501ignore_int:
502 cld 469 cld
503#ifdef CONFIG_PRINTK 470#ifdef CONFIG_PRINTK
504 pushl %eax 471 pushl %eax
@@ -533,7 +500,8 @@ ignore_int:
533hlt_loop: 500hlt_loop:
534 hlt 501 hlt
535 jmp hlt_loop 502 jmp hlt_loop
536ENDPROC(ignore_int) 503ENDPROC(early_ignore_irq)
504
537__INITDATA 505__INITDATA
538 .align 4 506 .align 4
539GLOBAL(early_recursion_flag) 507GLOBAL(early_recursion_flag)
@@ -622,7 +590,6 @@ int_msg:
622 590
623 .data 591 .data
624.globl boot_gdt_descr 592.globl boot_gdt_descr
625.globl idt_descr
626 593
627 ALIGN 594 ALIGN
628# early boot GDT descriptor (must use 1:1 address mapping) 595# early boot GDT descriptor (must use 1:1 address mapping)
@@ -631,11 +598,6 @@ boot_gdt_descr:
631 .word __BOOT_DS+7 598 .word __BOOT_DS+7
632 .long boot_gdt - __PAGE_OFFSET 599 .long boot_gdt - __PAGE_OFFSET
633 600
634 .word 0 # 32-bit align idt_desc.address
635idt_descr:
636 .word IDT_ENTRIES*8-1 # idt contains 256 entries
637 .long idt_table
638
639# boot GDT descriptor (later on used by CPU#0): 601# boot GDT descriptor (later on used by CPU#0):
640 .word 0 # 32 bit align gdt_desc.address 602 .word 0 # 32 bit align gdt_desc.address
641ENTRY(early_gdt_descr) 603ENTRY(early_gdt_descr)
diff --git a/arch/x86/kernel/idt.c b/arch/x86/kernel/idt.c
new file mode 100644
index 000000000000..6107ee1cb8d5
--- /dev/null
+++ b/arch/x86/kernel/idt.c
@@ -0,0 +1,371 @@
1/*
2 * Interrupt descriptor table related code
3 *
4 * This file is licensed under the GPL V2
5 */
6#include <linux/interrupt.h>
7
8#include <asm/traps.h>
9#include <asm/proto.h>
10#include <asm/desc.h>
11
12struct idt_data {
13 unsigned int vector;
14 unsigned int segment;
15 struct idt_bits bits;
16 const void *addr;
17};
18
19#define DPL0 0x0
20#define DPL3 0x3
21
22#define DEFAULT_STACK 0
23
24#define G(_vector, _addr, _ist, _type, _dpl, _segment) \
25 { \
26 .vector = _vector, \
27 .bits.ist = _ist, \
28 .bits.type = _type, \
29 .bits.dpl = _dpl, \
30 .bits.p = 1, \
31 .addr = _addr, \
32 .segment = _segment, \
33 }
34
35/* Interrupt gate */
36#define INTG(_vector, _addr) \
37 G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL0, __KERNEL_CS)
38
39/* System interrupt gate */
40#define SYSG(_vector, _addr) \
41 G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL3, __KERNEL_CS)
42
43/* Interrupt gate with interrupt stack */
44#define ISTG(_vector, _addr, _ist) \
45 G(_vector, _addr, _ist, GATE_INTERRUPT, DPL0, __KERNEL_CS)
46
47/* System interrupt gate with interrupt stack */
48#define SISTG(_vector, _addr, _ist) \
49 G(_vector, _addr, _ist, GATE_INTERRUPT, DPL3, __KERNEL_CS)
50
51/* Task gate */
52#define TSKG(_vector, _gdt) \
53 G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3)
54
55/*
56 * Early traps running on the DEFAULT_STACK because the other interrupt
57 * stacks work only after cpu_init().
58 */
59static const __initdata struct idt_data early_idts[] = {
60 INTG(X86_TRAP_DB, debug),
61 SYSG(X86_TRAP_BP, int3),
62#ifdef CONFIG_X86_32
63 INTG(X86_TRAP_PF, page_fault),
64#endif
65};
66
67/*
68 * The default IDT entries which are set up in trap_init() before
69 * cpu_init() is invoked. Interrupt stacks cannot be used at that point and
70 * the traps which use them are reinitialized with IST after cpu_init() has
71 * set up TSS.
72 */
73static const __initdata struct idt_data def_idts[] = {
74 INTG(X86_TRAP_DE, divide_error),
75 INTG(X86_TRAP_NMI, nmi),
76 INTG(X86_TRAP_BR, bounds),
77 INTG(X86_TRAP_UD, invalid_op),
78 INTG(X86_TRAP_NM, device_not_available),
79 INTG(X86_TRAP_OLD_MF, coprocessor_segment_overrun),
80 INTG(X86_TRAP_TS, invalid_TSS),
81 INTG(X86_TRAP_NP, segment_not_present),
82 INTG(X86_TRAP_SS, stack_segment),
83 INTG(X86_TRAP_GP, general_protection),
84 INTG(X86_TRAP_SPURIOUS, spurious_interrupt_bug),
85 INTG(X86_TRAP_MF, coprocessor_error),
86 INTG(X86_TRAP_AC, alignment_check),
87 INTG(X86_TRAP_XF, simd_coprocessor_error),
88
89#ifdef CONFIG_X86_32
90 TSKG(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS),
91#else
92 INTG(X86_TRAP_DF, double_fault),
93#endif
94 INTG(X86_TRAP_DB, debug),
95 INTG(X86_TRAP_NMI, nmi),
96 INTG(X86_TRAP_BP, int3),
97
98#ifdef CONFIG_X86_MCE
99 INTG(X86_TRAP_MC, &machine_check),
100#endif
101
102 SYSG(X86_TRAP_OF, overflow),
103#if defined(CONFIG_IA32_EMULATION)
104 SYSG(IA32_SYSCALL_VECTOR, entry_INT80_compat),
105#elif defined(CONFIG_X86_32)
106 SYSG(IA32_SYSCALL_VECTOR, entry_INT80_32),
107#endif
108};
109
110/*
111 * The APIC and SMP idt entries
112 */
113static const __initdata struct idt_data apic_idts[] = {
114#ifdef CONFIG_SMP
115 INTG(RESCHEDULE_VECTOR, reschedule_interrupt),
116 INTG(CALL_FUNCTION_VECTOR, call_function_interrupt),
117 INTG(CALL_FUNCTION_SINGLE_VECTOR, call_function_single_interrupt),
118 INTG(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt),
119 INTG(REBOOT_VECTOR, reboot_interrupt),
120#endif
121
122#ifdef CONFIG_X86_THERMAL_VECTOR
123 INTG(THERMAL_APIC_VECTOR, thermal_interrupt),
124#endif
125
126#ifdef CONFIG_X86_MCE_THRESHOLD
127 INTG(THRESHOLD_APIC_VECTOR, threshold_interrupt),
128#endif
129
130#ifdef CONFIG_X86_MCE_AMD
131 INTG(DEFERRED_ERROR_VECTOR, deferred_error_interrupt),
132#endif
133
134#ifdef CONFIG_X86_LOCAL_APIC
135 INTG(LOCAL_TIMER_VECTOR, apic_timer_interrupt),
136 INTG(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi),
137# ifdef CONFIG_HAVE_KVM
138 INTG(POSTED_INTR_VECTOR, kvm_posted_intr_ipi),
139 INTG(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi),
140 INTG(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi),
141# endif
142# ifdef CONFIG_IRQ_WORK
143 INTG(IRQ_WORK_VECTOR, irq_work_interrupt),
144# endif
145 INTG(SPURIOUS_APIC_VECTOR, spurious_interrupt),
146 INTG(ERROR_APIC_VECTOR, error_interrupt),
147#endif
148};
149
150#ifdef CONFIG_X86_64
151/*
152 * Early traps running on the DEFAULT_STACK because the other interrupt
153 * stacks work only after cpu_init().
154 */
155static const __initdata struct idt_data early_pf_idts[] = {
156 INTG(X86_TRAP_PF, page_fault),
157};
158
159/*
160 * Override for the debug_idt. Same as the default, but with interrupt
161 * stack set to DEFAULT_STACK (0). Required for NMI trap handling.
162 */
163static const __initdata struct idt_data dbg_idts[] = {
164 INTG(X86_TRAP_DB, debug),
165 INTG(X86_TRAP_BP, int3),
166};
167#endif
168
169/* Must be page-aligned because the real IDT is used in a fixmap. */
170gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss;
171
172struct desc_ptr idt_descr __ro_after_init = {
173 .size = (IDT_ENTRIES * 2 * sizeof(unsigned long)) - 1,
174 .address = (unsigned long) idt_table,
175};
176
177#ifdef CONFIG_X86_64
178/* No need to be aligned, but done to keep all IDTs defined the same way. */
179gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss;
180
181/*
182 * The exceptions which use Interrupt stacks. They are setup after
183 * cpu_init() when the TSS has been initialized.
184 */
185static const __initdata struct idt_data ist_idts[] = {
186 ISTG(X86_TRAP_DB, debug, DEBUG_STACK),
187 ISTG(X86_TRAP_NMI, nmi, NMI_STACK),
188 SISTG(X86_TRAP_BP, int3, DEBUG_STACK),
189 ISTG(X86_TRAP_DF, double_fault, DOUBLEFAULT_STACK),
190#ifdef CONFIG_X86_MCE
191 ISTG(X86_TRAP_MC, &machine_check, MCE_STACK),
192#endif
193};
194
195/*
196 * Override for the debug_idt. Same as the default, but with interrupt
197 * stack set to DEFAULT_STACK (0). Required for NMI trap handling.
198 */
199const struct desc_ptr debug_idt_descr = {
200 .size = IDT_ENTRIES * 16 - 1,
201 .address = (unsigned long) debug_idt_table,
202};
203#endif
204
205static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d)
206{
207 unsigned long addr = (unsigned long) d->addr;
208
209 gate->offset_low = (u16) addr;
210 gate->segment = (u16) d->segment;
211 gate->bits = d->bits;
212 gate->offset_middle = (u16) (addr >> 16);
213#ifdef CONFIG_X86_64
214 gate->offset_high = (u32) (addr >> 32);
215 gate->reserved = 0;
216#endif
217}
218
219static void
220idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size, bool sys)
221{
222 gate_desc desc;
223
224 for (; size > 0; t++, size--) {
225 idt_init_desc(&desc, t);
226 write_idt_entry(idt, t->vector, &desc);
227 if (sys)
228 set_bit(t->vector, used_vectors);
229 }
230}
231
232static void set_intr_gate(unsigned int n, const void *addr)
233{
234 struct idt_data data;
235
236 BUG_ON(n > 0xFF);
237
238 memset(&data, 0, sizeof(data));
239 data.vector = n;
240 data.addr = addr;
241 data.segment = __KERNEL_CS;
242 data.bits.type = GATE_INTERRUPT;
243 data.bits.p = 1;
244
245 idt_setup_from_table(idt_table, &data, 1, false);
246}
247
248/**
249 * idt_setup_early_traps - Initialize the idt table with early traps
250 *
251 * On X8664 these traps do not use interrupt stacks as they can't work
252 * before cpu_init() is invoked and sets up TSS. The IST variants are
253 * installed after that.
254 */
255void __init idt_setup_early_traps(void)
256{
257 idt_setup_from_table(idt_table, early_idts, ARRAY_SIZE(early_idts),
258 true);
259 load_idt(&idt_descr);
260}
261
262/**
263 * idt_setup_traps - Initialize the idt table with default traps
264 */
265void __init idt_setup_traps(void)
266{
267 idt_setup_from_table(idt_table, def_idts, ARRAY_SIZE(def_idts), true);
268}
269
270#ifdef CONFIG_X86_64
271/**
272 * idt_setup_early_pf - Initialize the idt table with early pagefault handler
273 *
274 * On X8664 this does not use interrupt stacks as they can't work before
275 * cpu_init() is invoked and sets up TSS. The IST variant is installed
276 * after that.
277 *
278 * FIXME: Why is 32bit and 64bit installing the PF handler at different
279 * places in the early setup code?
280 */
281void __init idt_setup_early_pf(void)
282{
283 idt_setup_from_table(idt_table, early_pf_idts,
284 ARRAY_SIZE(early_pf_idts), true);
285}
286
287/**
288 * idt_setup_ist_traps - Initialize the idt table with traps using IST
289 */
290void __init idt_setup_ist_traps(void)
291{
292 idt_setup_from_table(idt_table, ist_idts, ARRAY_SIZE(ist_idts), true);
293}
294
295/**
296 * idt_setup_debugidt_traps - Initialize the debug idt table with debug traps
297 */
298void __init idt_setup_debugidt_traps(void)
299{
300 memcpy(&debug_idt_table, &idt_table, IDT_ENTRIES * 16);
301
302 idt_setup_from_table(debug_idt_table, dbg_idts, ARRAY_SIZE(dbg_idts), false);
303}
304#endif
305
306/**
307 * idt_setup_apic_and_irq_gates - Setup APIC/SMP and normal interrupt gates
308 */
309void __init idt_setup_apic_and_irq_gates(void)
310{
311 int i = FIRST_EXTERNAL_VECTOR;
312 void *entry;
313
314 idt_setup_from_table(idt_table, apic_idts, ARRAY_SIZE(apic_idts), true);
315
316 for_each_clear_bit_from(i, used_vectors, FIRST_SYSTEM_VECTOR) {
317 entry = irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR);
318 set_intr_gate(i, entry);
319 }
320
321 for_each_clear_bit_from(i, used_vectors, NR_VECTORS) {
322#ifdef CONFIG_X86_LOCAL_APIC
323 set_bit(i, used_vectors);
324 set_intr_gate(i, spurious_interrupt);
325#else
326 entry = irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR);
327 set_intr_gate(i, entry);
328#endif
329 }
330}
331
332/**
333 * idt_setup_early_handler - Initializes the idt table with early handlers
334 */
335void __init idt_setup_early_handler(void)
336{
337 int i;
338
339 for (i = 0; i < NUM_EXCEPTION_VECTORS; i++)
340 set_intr_gate(i, early_idt_handler_array[i]);
341#ifdef CONFIG_X86_32
342 for ( ; i < NR_VECTORS; i++)
343 set_intr_gate(i, early_ignore_irq);
344#endif
345 load_idt(&idt_descr);
346}
347
348/**
349 * idt_invalidate - Invalidate interrupt descriptor table
350 * @addr: The virtual address of the 'invalid' IDT
351 */
352void idt_invalidate(void *addr)
353{
354 struct desc_ptr idt = { .address = (unsigned long) addr, .size = 0 };
355
356 load_idt(&idt);
357}
358
359void __init update_intr_gate(unsigned int n, const void *addr)
360{
361 if (WARN_ON_ONCE(!test_bit(n, used_vectors)))
362 return;
363 set_intr_gate(n, addr);
364}
365
366void alloc_intr_gate(unsigned int n, const void *addr)
367{
368 BUG_ON(n < FIRST_SYSTEM_VECTOR);
369 if (!test_and_set_bit(n, used_vectors))
370 set_intr_gate(n, addr);
371}
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 4ed0aba8dbc8..52089c043160 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -29,9 +29,6 @@ EXPORT_PER_CPU_SYMBOL(irq_regs);
29 29
30atomic_t irq_err_count; 30atomic_t irq_err_count;
31 31
32/* Function pointer for generic interrupt vector handling */
33void (*x86_platform_ipi_callback)(void) = NULL;
34
35/* 32/*
36 * 'what should we do if we get a hw irq event on an illegal vector'. 33 * 'what should we do if we get a hw irq event on an illegal vector'.
37 * each architecture has to answer this themselves. 34 * each architecture has to answer this themselves.
@@ -87,13 +84,13 @@ int arch_show_interrupts(struct seq_file *p, int prec)
87 for_each_online_cpu(j) 84 for_each_online_cpu(j)
88 seq_printf(p, "%10u ", irq_stats(j)->icr_read_retry_count); 85 seq_printf(p, "%10u ", irq_stats(j)->icr_read_retry_count);
89 seq_puts(p, " APIC ICR read retries\n"); 86 seq_puts(p, " APIC ICR read retries\n");
90#endif
91 if (x86_platform_ipi_callback) { 87 if (x86_platform_ipi_callback) {
92 seq_printf(p, "%*s: ", prec, "PLT"); 88 seq_printf(p, "%*s: ", prec, "PLT");
93 for_each_online_cpu(j) 89 for_each_online_cpu(j)
94 seq_printf(p, "%10u ", irq_stats(j)->x86_platform_ipis); 90 seq_printf(p, "%10u ", irq_stats(j)->x86_platform_ipis);
95 seq_puts(p, " Platform interrupts\n"); 91 seq_puts(p, " Platform interrupts\n");
96 } 92 }
93#endif
97#ifdef CONFIG_SMP 94#ifdef CONFIG_SMP
98 seq_printf(p, "%*s: ", prec, "RES"); 95 seq_printf(p, "%*s: ", prec, "RES");
99 for_each_online_cpu(j) 96 for_each_online_cpu(j)
@@ -183,9 +180,9 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
183 sum += irq_stats(cpu)->apic_perf_irqs; 180 sum += irq_stats(cpu)->apic_perf_irqs;
184 sum += irq_stats(cpu)->apic_irq_work_irqs; 181 sum += irq_stats(cpu)->apic_irq_work_irqs;
185 sum += irq_stats(cpu)->icr_read_retry_count; 182 sum += irq_stats(cpu)->icr_read_retry_count;
186#endif
187 if (x86_platform_ipi_callback) 183 if (x86_platform_ipi_callback)
188 sum += irq_stats(cpu)->x86_platform_ipis; 184 sum += irq_stats(cpu)->x86_platform_ipis;
185#endif
189#ifdef CONFIG_SMP 186#ifdef CONFIG_SMP
190 sum += irq_stats(cpu)->irq_resched_count; 187 sum += irq_stats(cpu)->irq_resched_count;
191 sum += irq_stats(cpu)->irq_call_count; 188 sum += irq_stats(cpu)->irq_call_count;
@@ -259,26 +256,26 @@ __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
259 return 1; 256 return 1;
260} 257}
261 258
259#ifdef CONFIG_X86_LOCAL_APIC
260/* Function pointer for generic interrupt vector handling */
261void (*x86_platform_ipi_callback)(void) = NULL;
262/* 262/*
263 * Handler for X86_PLATFORM_IPI_VECTOR. 263 * Handler for X86_PLATFORM_IPI_VECTOR.
264 */ 264 */
265void __smp_x86_platform_ipi(void)
266{
267 inc_irq_stat(x86_platform_ipis);
268
269 if (x86_platform_ipi_callback)
270 x86_platform_ipi_callback();
271}
272
273__visible void __irq_entry smp_x86_platform_ipi(struct pt_regs *regs) 265__visible void __irq_entry smp_x86_platform_ipi(struct pt_regs *regs)
274{ 266{
275 struct pt_regs *old_regs = set_irq_regs(regs); 267 struct pt_regs *old_regs = set_irq_regs(regs);
276 268
277 entering_ack_irq(); 269 entering_ack_irq();
278 __smp_x86_platform_ipi(); 270 trace_x86_platform_ipi_entry(X86_PLATFORM_IPI_VECTOR);
271 inc_irq_stat(x86_platform_ipis);
272 if (x86_platform_ipi_callback)
273 x86_platform_ipi_callback();
274 trace_x86_platform_ipi_exit(X86_PLATFORM_IPI_VECTOR);
279 exiting_irq(); 275 exiting_irq();
280 set_irq_regs(old_regs); 276 set_irq_regs(old_regs);
281} 277}
278#endif
282 279
283#ifdef CONFIG_HAVE_KVM 280#ifdef CONFIG_HAVE_KVM
284static void dummy_handler(void) {} 281static void dummy_handler(void) {}
@@ -334,19 +331,6 @@ __visible void smp_kvm_posted_intr_nested_ipi(struct pt_regs *regs)
334} 331}
335#endif 332#endif
336 333
337__visible void __irq_entry smp_trace_x86_platform_ipi(struct pt_regs *regs)
338{
339 struct pt_regs *old_regs = set_irq_regs(regs);
340
341 entering_ack_irq();
342 trace_x86_platform_ipi_entry(X86_PLATFORM_IPI_VECTOR);
343 __smp_x86_platform_ipi();
344 trace_x86_platform_ipi_exit(X86_PLATFORM_IPI_VECTOR);
345 exiting_irq();
346 set_irq_regs(old_regs);
347}
348
349EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq);
350 334
351#ifdef CONFIG_HOTPLUG_CPU 335#ifdef CONFIG_HOTPLUG_CPU
352 336
@@ -431,7 +415,7 @@ int check_irq_vectors_for_cpu_disable(void)
431 * this w/o holding vector_lock. 415 * this w/o holding vector_lock.
432 */ 416 */
433 for (vector = FIRST_EXTERNAL_VECTOR; 417 for (vector = FIRST_EXTERNAL_VECTOR;
434 vector < first_system_vector; vector++) { 418 vector < FIRST_SYSTEM_VECTOR; vector++) {
435 if (!test_bit(vector, used_vectors) && 419 if (!test_bit(vector, used_vectors) &&
436 IS_ERR_OR_NULL(per_cpu(vector_irq, cpu)[vector])) { 420 IS_ERR_OR_NULL(per_cpu(vector_irq, cpu)[vector])) {
437 if (++count == this_count) 421 if (++count == this_count)
diff --git a/arch/x86/kernel/irq_work.c b/arch/x86/kernel/irq_work.c
index 275487872be2..70dee056f92b 100644
--- a/arch/x86/kernel/irq_work.c
+++ b/arch/x86/kernel/irq_work.c
@@ -11,35 +11,23 @@
11#include <asm/trace/irq_vectors.h> 11#include <asm/trace/irq_vectors.h>
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13 13
14static inline void __smp_irq_work_interrupt(void) 14#ifdef CONFIG_X86_LOCAL_APIC
15{
16 inc_irq_stat(apic_irq_work_irqs);
17 irq_work_run();
18}
19
20__visible void __irq_entry smp_irq_work_interrupt(struct pt_regs *regs) 15__visible void __irq_entry smp_irq_work_interrupt(struct pt_regs *regs)
21{ 16{
22 ipi_entering_ack_irq(); 17 ipi_entering_ack_irq();
23 __smp_irq_work_interrupt();
24 exiting_irq();
25}
26
27__visible void __irq_entry smp_trace_irq_work_interrupt(struct pt_regs *regs)
28{
29 ipi_entering_ack_irq();
30 trace_irq_work_entry(IRQ_WORK_VECTOR); 18 trace_irq_work_entry(IRQ_WORK_VECTOR);
31 __smp_irq_work_interrupt(); 19 inc_irq_stat(apic_irq_work_irqs);
20 irq_work_run();
32 trace_irq_work_exit(IRQ_WORK_VECTOR); 21 trace_irq_work_exit(IRQ_WORK_VECTOR);
33 exiting_irq(); 22 exiting_irq();
34} 23}
35 24
36void arch_irq_work_raise(void) 25void arch_irq_work_raise(void)
37{ 26{
38#ifdef CONFIG_X86_LOCAL_APIC
39 if (!arch_irq_work_has_interrupt()) 27 if (!arch_irq_work_has_interrupt())
40 return; 28 return;
41 29
42 apic->send_IPI_self(IRQ_WORK_VECTOR); 30 apic->send_IPI_self(IRQ_WORK_VECTOR);
43 apic_wait_icr_idle(); 31 apic_wait_icr_idle();
44#endif
45} 32}
33#endif
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index c7fd18526c3e..1add9e08e83e 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -55,18 +55,6 @@ DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
55 [0 ... NR_VECTORS - 1] = VECTOR_UNUSED, 55 [0 ... NR_VECTORS - 1] = VECTOR_UNUSED,
56}; 56};
57 57
58int vector_used_by_percpu_irq(unsigned int vector)
59{
60 int cpu;
61
62 for_each_online_cpu(cpu) {
63 if (!IS_ERR_OR_NULL(per_cpu(vector_irq, cpu)[vector]))
64 return 1;
65 }
66
67 return 0;
68}
69
70void __init init_ISA_irqs(void) 58void __init init_ISA_irqs(void)
71{ 59{
72 struct irq_chip *chip = legacy_pic->chip; 60 struct irq_chip *chip = legacy_pic->chip;
@@ -99,100 +87,12 @@ void __init init_IRQ(void)
99 x86_init.irqs.intr_init(); 87 x86_init.irqs.intr_init();
100} 88}
101 89
102static void __init smp_intr_init(void)
103{
104#ifdef CONFIG_SMP
105 /*
106 * The reschedule interrupt is a CPU-to-CPU reschedule-helper
107 * IPI, driven by wakeup.
108 */
109 alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
110
111 /* IPI for generic function call */
112 alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
113
114 /* IPI for generic single function call */
115 alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR,
116 call_function_single_interrupt);
117
118 /* Low priority IPI to cleanup after moving an irq */
119 set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
120 set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
121
122 /* IPI used for rebooting/stopping */
123 alloc_intr_gate(REBOOT_VECTOR, reboot_interrupt);
124#endif /* CONFIG_SMP */
125}
126
127static void __init apic_intr_init(void)
128{
129 smp_intr_init();
130
131#ifdef CONFIG_X86_THERMAL_VECTOR
132 alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
133#endif
134#ifdef CONFIG_X86_MCE_THRESHOLD
135 alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
136#endif
137
138#ifdef CONFIG_X86_MCE_AMD
139 alloc_intr_gate(DEFERRED_ERROR_VECTOR, deferred_error_interrupt);
140#endif
141
142#ifdef CONFIG_X86_LOCAL_APIC
143 /* self generated IPI for local APIC timer */
144 alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
145
146 /* IPI for X86 platform specific use */
147 alloc_intr_gate(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi);
148#ifdef CONFIG_HAVE_KVM
149 /* IPI for KVM to deliver posted interrupt */
150 alloc_intr_gate(POSTED_INTR_VECTOR, kvm_posted_intr_ipi);
151 /* IPI for KVM to deliver interrupt to wake up tasks */
152 alloc_intr_gate(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi);
153 /* IPI for KVM to deliver nested posted interrupt */
154 alloc_intr_gate(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi);
155#endif
156
157 /* IPI vectors for APIC spurious and error interrupts */
158 alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
159 alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
160
161 /* IRQ work interrupts: */
162# ifdef CONFIG_IRQ_WORK
163 alloc_intr_gate(IRQ_WORK_VECTOR, irq_work_interrupt);
164# endif
165
166#endif
167}
168
169void __init native_init_IRQ(void) 90void __init native_init_IRQ(void)
170{ 91{
171 int i;
172
173 /* Execute any quirks before the call gates are initialised: */ 92 /* Execute any quirks before the call gates are initialised: */
174 x86_init.irqs.pre_vector_init(); 93 x86_init.irqs.pre_vector_init();
175 94
176 apic_intr_init(); 95 idt_setup_apic_and_irq_gates();
177
178 /*
179 * Cover the whole vector space, no vector can escape
180 * us. (some of these will be overridden and become
181 * 'special' SMP interrupts)
182 */
183 i = FIRST_EXTERNAL_VECTOR;
184#ifndef CONFIG_X86_LOCAL_APIC
185#define first_system_vector NR_VECTORS
186#endif
187 for_each_clear_bit_from(i, used_vectors, first_system_vector) {
188 /* IA32_SYSCALL_VECTOR could be used in trap_init already. */
189 set_intr_gate(i, irq_entries_start +
190 8 * (i - FIRST_EXTERNAL_VECTOR));
191 }
192#ifdef CONFIG_X86_LOCAL_APIC
193 for_each_clear_bit_from(i, used_vectors, NR_VECTORS)
194 set_intr_gate(i, spurious_interrupt);
195#endif
196 96
197 if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs()) 97 if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs())
198 setup_irq(2, &irq2); 98 setup_irq(2, &irq2);
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index d04e30e3c0ff..874827b0d7ca 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -263,7 +263,7 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code)
263 263
264 switch (kvm_read_and_reset_pf_reason()) { 264 switch (kvm_read_and_reset_pf_reason()) {
265 default: 265 default:
266 trace_do_page_fault(regs, error_code); 266 do_page_fault(regs, error_code);
267 break; 267 break;
268 case KVM_PV_REASON_PAGE_NOT_PRESENT: 268 case KVM_PV_REASON_PAGE_NOT_PRESENT:
269 /* page is swapped out by the host. */ 269 /* page is swapped out by the host. */
@@ -455,7 +455,7 @@ static int kvm_cpu_down_prepare(unsigned int cpu)
455 455
456static void __init kvm_apf_trap_init(void) 456static void __init kvm_apf_trap_init(void)
457{ 457{
458 set_intr_gate(14, async_page_fault); 458 update_intr_gate(X86_TRAP_PF, async_page_fault);
459} 459}
460 460
461void __init kvm_guest_init(void) 461void __init kvm_guest_init(void)
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index 8c53c5d7a1bc..00bc751c861c 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -26,18 +26,6 @@
26#include <asm/set_memory.h> 26#include <asm/set_memory.h>
27#include <asm/debugreg.h> 27#include <asm/debugreg.h>
28 28
29static void set_idt(void *newidt, __u16 limit)
30{
31 struct desc_ptr curidt;
32
33 /* ia32 supports unaliged loads & stores */
34 curidt.size = limit;
35 curidt.address = (unsigned long)newidt;
36
37 load_idt(&curidt);
38}
39
40
41static void set_gdt(void *newgdt, __u16 limit) 29static void set_gdt(void *newgdt, __u16 limit)
42{ 30{
43 struct desc_ptr curgdt; 31 struct desc_ptr curgdt;
@@ -245,7 +233,7 @@ void machine_kexec(struct kimage *image)
245 * If you want to load them you must set up your own idt & gdt. 233 * If you want to load them you must set up your own idt & gdt.
246 */ 234 */
247 set_gdt(phys_to_virt(0), 0); 235 set_gdt(phys_to_virt(0), 0);
248 set_idt(phys_to_virt(0), 0); 236 idt_invalidate(phys_to_virt(0));
249 237
250 /* now call it */ 238 /* now call it */
251 image->start = relocate_kernel_ptr((unsigned long)image->head, 239 image->start = relocate_kernel_ptr((unsigned long)image->head,
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index bc0a849589bb..a14df9eecfed 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -319,9 +319,6 @@ __visible struct pv_irq_ops pv_irq_ops = {
319 .irq_enable = __PV_IS_CALLEE_SAVE(native_irq_enable), 319 .irq_enable = __PV_IS_CALLEE_SAVE(native_irq_enable),
320 .safe_halt = native_safe_halt, 320 .safe_halt = native_safe_halt,
321 .halt = native_halt, 321 .halt = native_halt,
322#ifdef CONFIG_X86_64
323 .adjust_exception_frame = paravirt_nop,
324#endif
325}; 322};
326 323
327__visible struct pv_cpu_ops pv_cpu_ops = { 324__visible struct pv_cpu_ops pv_cpu_ops = {
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index a56bf6051f4e..54984b142641 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -38,8 +38,6 @@
38void (*pm_power_off)(void); 38void (*pm_power_off)(void);
39EXPORT_SYMBOL(pm_power_off); 39EXPORT_SYMBOL(pm_power_off);
40 40
41static const struct desc_ptr no_idt = {};
42
43/* 41/*
44 * This is set if we need to go through the 'emergency' path. 42 * This is set if we need to go through the 'emergency' path.
45 * When machine_emergency_restart() is called, we may be on 43 * When machine_emergency_restart() is called, we may be on
@@ -638,7 +636,7 @@ static void native_machine_emergency_restart(void)
638 break; 636 break;
639 637
640 case BOOT_TRIPLE: 638 case BOOT_TRIPLE:
641 load_idt(&no_idt); 639 idt_invalidate(NULL);
642 __asm__ __volatile__("int3"); 640 __asm__ __volatile__("int3");
643 641
644 /* We're probably dead after this, but... */ 642 /* We're probably dead after this, but... */
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 022ebddb3734..9cc16a841745 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -900,7 +900,7 @@ void __init setup_arch(char **cmdline_p)
900 */ 900 */
901 olpc_ofw_detect(); 901 olpc_ofw_detect();
902 902
903 early_trap_init(); 903 idt_setup_early_traps();
904 early_cpu_init(); 904 early_cpu_init();
905 early_ioremap_init(); 905 early_ioremap_init();
906 906
@@ -1171,7 +1171,7 @@ void __init setup_arch(char **cmdline_p)
1171 1171
1172 init_mem_mapping(); 1172 init_mem_mapping();
1173 1173
1174 early_trap_pf_init(); 1174 idt_setup_early_pf();
1175 1175
1176 /* 1176 /*
1177 * Update mmu_cr4_features (and, indirectly, trampoline_cr4_features) 1177 * Update mmu_cr4_features (and, indirectly, trampoline_cr4_features)
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 10edd1e69a68..6e8fcb6f7e1e 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -155,13 +155,10 @@ static void __init pcpup_populate_pte(unsigned long addr)
155static inline void setup_percpu_segment(int cpu) 155static inline void setup_percpu_segment(int cpu)
156{ 156{
157#ifdef CONFIG_X86_32 157#ifdef CONFIG_X86_32
158 struct desc_struct gdt; 158 struct desc_struct d = GDT_ENTRY_INIT(0x8092, per_cpu_offset(cpu),
159 0xFFFFF);
159 160
160 pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF, 161 write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
161 0x2 | DESCTYPE_S, 0x8);
162 gdt.s = 1;
163 write_gdt_entry(get_cpu_gdt_rw(cpu),
164 GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
165#endif 162#endif
166} 163}
167 164
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index d798c0da451c..5c574dff4c1a 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -254,84 +254,45 @@ finish:
254} 254}
255 255
256/* 256/*
257 * Reschedule call back. 257 * Reschedule call back. KVM uses this interrupt to force a cpu out of
258 * guest mode
258 */ 259 */
259static inline void __smp_reschedule_interrupt(void)
260{
261 inc_irq_stat(irq_resched_count);
262 scheduler_ipi();
263}
264
265__visible void __irq_entry smp_reschedule_interrupt(struct pt_regs *regs) 260__visible void __irq_entry smp_reschedule_interrupt(struct pt_regs *regs)
266{ 261{
267 ack_APIC_irq(); 262 ack_APIC_irq();
268 __smp_reschedule_interrupt(); 263 inc_irq_stat(irq_resched_count);
269 /*
270 * KVM uses this interrupt to force a cpu out of guest mode
271 */
272}
273
274__visible void __irq_entry smp_trace_reschedule_interrupt(struct pt_regs *regs)
275{
276 /*
277 * Need to call irq_enter() before calling the trace point.
278 * __smp_reschedule_interrupt() calls irq_enter/exit() too (in
279 * scheduler_ipi(). This is OK, since those functions are allowed
280 * to nest.
281 */
282 ipi_entering_ack_irq();
283 trace_reschedule_entry(RESCHEDULE_VECTOR);
284 __smp_reschedule_interrupt();
285 trace_reschedule_exit(RESCHEDULE_VECTOR);
286 exiting_irq();
287 /*
288 * KVM uses this interrupt to force a cpu out of guest mode
289 */
290}
291 264
292static inline void __smp_call_function_interrupt(void) 265 if (trace_resched_ipi_enabled()) {
293{ 266 /*
294 generic_smp_call_function_interrupt(); 267 * scheduler_ipi() might call irq_enter() as well, but
295 inc_irq_stat(irq_call_count); 268 * nested calls are fine.
269 */
270 irq_enter();
271 trace_reschedule_entry(RESCHEDULE_VECTOR);
272 scheduler_ipi();
273 trace_reschedule_exit(RESCHEDULE_VECTOR);
274 irq_exit();
275 return;
276 }
277 scheduler_ipi();
296} 278}
297 279
298__visible void __irq_entry smp_call_function_interrupt(struct pt_regs *regs) 280__visible void __irq_entry smp_call_function_interrupt(struct pt_regs *regs)
299{ 281{
300 ipi_entering_ack_irq(); 282 ipi_entering_ack_irq();
301 __smp_call_function_interrupt();
302 exiting_irq();
303}
304
305__visible void __irq_entry
306smp_trace_call_function_interrupt(struct pt_regs *regs)
307{
308 ipi_entering_ack_irq();
309 trace_call_function_entry(CALL_FUNCTION_VECTOR); 283 trace_call_function_entry(CALL_FUNCTION_VECTOR);
310 __smp_call_function_interrupt();
311 trace_call_function_exit(CALL_FUNCTION_VECTOR);
312 exiting_irq();
313}
314
315static inline void __smp_call_function_single_interrupt(void)
316{
317 generic_smp_call_function_single_interrupt();
318 inc_irq_stat(irq_call_count); 284 inc_irq_stat(irq_call_count);
319} 285 generic_smp_call_function_interrupt();
320 286 trace_call_function_exit(CALL_FUNCTION_VECTOR);
321__visible void __irq_entry
322smp_call_function_single_interrupt(struct pt_regs *regs)
323{
324 ipi_entering_ack_irq();
325 __smp_call_function_single_interrupt();
326 exiting_irq(); 287 exiting_irq();
327} 288}
328 289
329__visible void __irq_entry 290__visible void __irq_entry smp_call_function_single_interrupt(struct pt_regs *r)
330smp_trace_call_function_single_interrupt(struct pt_regs *regs)
331{ 291{
332 ipi_entering_ack_irq(); 292 ipi_entering_ack_irq();
333 trace_call_function_single_entry(CALL_FUNCTION_SINGLE_VECTOR); 293 trace_call_function_single_entry(CALL_FUNCTION_SINGLE_VECTOR);
334 __smp_call_function_single_interrupt(); 294 inc_irq_stat(irq_call_count);
295 generic_smp_call_function_single_interrupt();
335 trace_call_function_single_exit(CALL_FUNCTION_SINGLE_VECTOR); 296 trace_call_function_single_exit(CALL_FUNCTION_SINGLE_VECTOR);
336 exiting_irq(); 297 exiting_irq();
337} 298}
diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c
index dcd699baea1b..a106b9719c58 100644
--- a/arch/x86/kernel/tls.c
+++ b/arch/x86/kernel/tls.c
@@ -93,7 +93,7 @@ static void set_tls_desc(struct task_struct *p, int idx,
93 93
94 while (n-- > 0) { 94 while (n-- > 0) {
95 if (LDT_empty(info) || LDT_zero(info)) { 95 if (LDT_empty(info) || LDT_zero(info)) {
96 desc->a = desc->b = 0; 96 memset(desc, 0, sizeof(*desc));
97 } else { 97 } else {
98 fill_ldt(desc, info); 98 fill_ldt(desc, info);
99 99
diff --git a/arch/x86/kernel/tracepoint.c b/arch/x86/kernel/tracepoint.c
index 15515132bf0d..c6636d1f60b9 100644
--- a/arch/x86/kernel/tracepoint.c
+++ b/arch/x86/kernel/tracepoint.c
@@ -4,57 +4,38 @@
4 * Copyright (C) 2013 Seiji Aguchi <seiji.aguchi@hds.com> 4 * Copyright (C) 2013 Seiji Aguchi <seiji.aguchi@hds.com>
5 * 5 *
6 */ 6 */
7#include <asm/hw_irq.h> 7#include <linux/jump_label.h>
8#include <asm/desc.h>
9#include <linux/atomic.h> 8#include <linux/atomic.h>
10 9
11atomic_t trace_idt_ctr = ATOMIC_INIT(0); 10#include <asm/hw_irq.h>
12struct desc_ptr trace_idt_descr = { NR_VECTORS * 16 - 1, 11#include <asm/desc.h>
13 (unsigned long) trace_idt_table };
14
15/* No need to be aligned, but done to keep all IDTs defined the same way. */
16gate_desc trace_idt_table[NR_VECTORS] __page_aligned_bss;
17 12
18static int trace_irq_vector_refcount; 13DEFINE_STATIC_KEY_FALSE(trace_pagefault_key);
19static DEFINE_MUTEX(irq_vector_mutex);
20 14
21static void set_trace_idt_ctr(int val) 15int trace_pagefault_reg(void)
22{ 16{
23 atomic_set(&trace_idt_ctr, val); 17 static_branch_inc(&trace_pagefault_key);
24 /* Ensure the trace_idt_ctr is set before sending IPI */ 18 return 0;
25 wmb();
26} 19}
27 20
28static void switch_idt(void *arg) 21void trace_pagefault_unreg(void)
29{ 22{
30 unsigned long flags; 23 static_branch_dec(&trace_pagefault_key);
31
32 local_irq_save(flags);
33 load_current_idt();
34 local_irq_restore(flags);
35} 24}
36 25
37int trace_irq_vector_regfunc(void) 26#ifdef CONFIG_SMP
27
28DEFINE_STATIC_KEY_FALSE(trace_resched_ipi_key);
29
30int trace_resched_ipi_reg(void)
38{ 31{
39 mutex_lock(&irq_vector_mutex); 32 static_branch_inc(&trace_resched_ipi_key);
40 if (!trace_irq_vector_refcount) {
41 set_trace_idt_ctr(1);
42 smp_call_function(switch_idt, NULL, 0);
43 switch_idt(NULL);
44 }
45 trace_irq_vector_refcount++;
46 mutex_unlock(&irq_vector_mutex);
47 return 0; 33 return 0;
48} 34}
49 35
50void trace_irq_vector_unregfunc(void) 36void trace_resched_ipi_unreg(void)
51{ 37{
52 mutex_lock(&irq_vector_mutex); 38 static_branch_dec(&trace_resched_ipi_key);
53 trace_irq_vector_refcount--;
54 if (!trace_irq_vector_refcount) {
55 set_trace_idt_ctr(0);
56 smp_call_function(switch_idt, NULL, 0);
57 switch_idt(NULL);
58 }
59 mutex_unlock(&irq_vector_mutex);
60} 39}
40
41#endif
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index bf54309b85da..34ea3651362e 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -38,11 +38,6 @@
38#include <linux/smp.h> 38#include <linux/smp.h>
39#include <linux/io.h> 39#include <linux/io.h>
40 40
41#ifdef CONFIG_EISA
42#include <linux/ioport.h>
43#include <linux/eisa.h>
44#endif
45
46#if defined(CONFIG_EDAC) 41#if defined(CONFIG_EDAC)
47#include <linux/edac.h> 42#include <linux/edac.h>
48#endif 43#endif
@@ -70,20 +65,13 @@
70#include <asm/x86_init.h> 65#include <asm/x86_init.h>
71#include <asm/pgalloc.h> 66#include <asm/pgalloc.h>
72#include <asm/proto.h> 67#include <asm/proto.h>
73
74/* No need to be aligned, but done to keep all IDTs defined the same way. */
75gate_desc debug_idt_table[NR_VECTORS] __page_aligned_bss;
76#else 68#else
77#include <asm/processor-flags.h> 69#include <asm/processor-flags.h>
78#include <asm/setup.h> 70#include <asm/setup.h>
79#include <asm/proto.h> 71#include <asm/proto.h>
80#endif 72#endif
81 73
82/* Must be page-aligned because the real IDT is used in a fixmap. */
83gate_desc idt_table[NR_VECTORS] __page_aligned_bss;
84
85DECLARE_BITMAP(used_vectors, NR_VECTORS); 74DECLARE_BITMAP(used_vectors, NR_VECTORS);
86EXPORT_SYMBOL_GPL(used_vectors);
87 75
88static inline void cond_local_irq_enable(struct pt_regs *regs) 76static inline void cond_local_irq_enable(struct pt_regs *regs)
89{ 77{
@@ -935,87 +923,9 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
935} 923}
936#endif 924#endif
937 925
938/* Set of traps needed for early debugging. */
939void __init early_trap_init(void)
940{
941 /*
942 * Don't use IST to set DEBUG_STACK as it doesn't work until TSS
943 * is ready in cpu_init() <-- trap_init(). Before trap_init(),
944 * CPU runs at ring 0 so it is impossible to hit an invalid
945 * stack. Using the original stack works well enough at this
946 * early stage. DEBUG_STACK will be equipped after cpu_init() in
947 * trap_init().
948 *
949 * We don't need to set trace_idt_table like set_intr_gate(),
950 * since we don't have trace_debug and it will be reset to
951 * 'debug' in trap_init() by set_intr_gate_ist().
952 */
953 set_intr_gate_notrace(X86_TRAP_DB, debug);
954 /* int3 can be called from all */
955 set_system_intr_gate(X86_TRAP_BP, &int3);
956#ifdef CONFIG_X86_32
957 set_intr_gate(X86_TRAP_PF, page_fault);
958#endif
959 load_idt(&idt_descr);
960}
961
962void __init early_trap_pf_init(void)
963{
964#ifdef CONFIG_X86_64
965 set_intr_gate(X86_TRAP_PF, page_fault);
966#endif
967}
968
969void __init trap_init(void) 926void __init trap_init(void)
970{ 927{
971 int i; 928 idt_setup_traps();
972
973#ifdef CONFIG_EISA
974 void __iomem *p = early_ioremap(0x0FFFD9, 4);
975
976 if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24))
977 EISA_bus = 1;
978 early_iounmap(p, 4);
979#endif
980
981 set_intr_gate(X86_TRAP_DE, divide_error);
982 set_intr_gate_ist(X86_TRAP_NMI, &nmi, NMI_STACK);
983 /* int4 can be called from all */
984 set_system_intr_gate(X86_TRAP_OF, &overflow);
985 set_intr_gate(X86_TRAP_BR, bounds);
986 set_intr_gate(X86_TRAP_UD, invalid_op);
987 set_intr_gate(X86_TRAP_NM, device_not_available);
988#ifdef CONFIG_X86_32
989 set_task_gate(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS);
990#else
991 set_intr_gate_ist(X86_TRAP_DF, &double_fault, DOUBLEFAULT_STACK);
992#endif
993 set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun);
994 set_intr_gate(X86_TRAP_TS, invalid_TSS);
995 set_intr_gate(X86_TRAP_NP, segment_not_present);
996 set_intr_gate(X86_TRAP_SS, stack_segment);
997 set_intr_gate(X86_TRAP_GP, general_protection);
998 set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug);
999 set_intr_gate(X86_TRAP_MF, coprocessor_error);
1000 set_intr_gate(X86_TRAP_AC, alignment_check);
1001#ifdef CONFIG_X86_MCE
1002 set_intr_gate_ist(X86_TRAP_MC, &machine_check, MCE_STACK);
1003#endif
1004 set_intr_gate(X86_TRAP_XF, simd_coprocessor_error);
1005
1006 /* Reserve all the builtin and the syscall vector: */
1007 for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
1008 set_bit(i, used_vectors);
1009
1010#ifdef CONFIG_IA32_EMULATION
1011 set_system_intr_gate(IA32_SYSCALL_VECTOR, entry_INT80_compat);
1012 set_bit(IA32_SYSCALL_VECTOR, used_vectors);
1013#endif
1014
1015#ifdef CONFIG_X86_32
1016 set_system_intr_gate(IA32_SYSCALL_VECTOR, entry_INT80_32);
1017 set_bit(IA32_SYSCALL_VECTOR, used_vectors);
1018#endif
1019 929
1020 /* 930 /*
1021 * Set the IDT descriptor to a fixed read-only location, so that the 931 * Set the IDT descriptor to a fixed read-only location, so that the
@@ -1030,20 +940,9 @@ void __init trap_init(void)
1030 */ 940 */
1031 cpu_init(); 941 cpu_init();
1032 942
1033 /* 943 idt_setup_ist_traps();
1034 * X86_TRAP_DB and X86_TRAP_BP have been set
1035 * in early_trap_init(). However, ITS works only after
1036 * cpu_init() loads TSS. See comments in early_trap_init().
1037 */
1038 set_intr_gate_ist(X86_TRAP_DB, &debug, DEBUG_STACK);
1039 /* int3 can be called from all */
1040 set_system_intr_gate_ist(X86_TRAP_BP, &int3, DEBUG_STACK);
1041 944
1042 x86_init.irqs.trap_init(); 945 x86_init.irqs.trap_init();
1043 946
1044#ifdef CONFIG_X86_64 947 idt_setup_debugidt_traps();
1045 memcpy(&debug_idt_table, &idt_table, IDT_ENTRIES * 16);
1046 set_nmi_gate(X86_TRAP_DB, &debug);
1047 set_nmi_gate(X86_TRAP_BP, &int3);
1048#endif
1049} 948}
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index d40900914a72..70b90c0810d0 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -8779,7 +8779,7 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu)
8779 8779
8780 vector = exit_intr_info & INTR_INFO_VECTOR_MASK; 8780 vector = exit_intr_info & INTR_INFO_VECTOR_MASK;
8781 desc = (gate_desc *)vmx->host_idt_base + vector; 8781 desc = (gate_desc *)vmx->host_idt_base + vector;
8782 entry = gate_offset(*desc); 8782 entry = gate_offset(desc);
8783 asm volatile( 8783 asm volatile(
8784#ifdef CONFIG_X86_64 8784#ifdef CONFIG_X86_64
8785 "mov %%" _ASM_SP ", %[sp]\n\t" 8785 "mov %%" _ASM_SP ", %[sp]\n\t"
diff --git a/arch/x86/math-emu/fpu_entry.c b/arch/x86/math-emu/fpu_entry.c
index 0203baefb5c0..d4a7df2205b8 100644
--- a/arch/x86/math-emu/fpu_entry.c
+++ b/arch/x86/math-emu/fpu_entry.c
@@ -147,7 +147,7 @@ void math_emulate(struct math_emu_info *info)
147 } 147 }
148 148
149 code_descriptor = FPU_get_ldt_descriptor(FPU_CS); 149 code_descriptor = FPU_get_ldt_descriptor(FPU_CS);
150 if (SEG_D_SIZE(code_descriptor)) { 150 if (code_descriptor.d) {
151 /* The above test may be wrong, the book is not clear */ 151 /* The above test may be wrong, the book is not clear */
152 /* Segmented 32 bit protected mode */ 152 /* Segmented 32 bit protected mode */
153 addr_modes.default_mode = SEG32; 153 addr_modes.default_mode = SEG32;
@@ -155,11 +155,10 @@ void math_emulate(struct math_emu_info *info)
155 /* 16 bit protected mode */ 155 /* 16 bit protected mode */
156 addr_modes.default_mode = PM16; 156 addr_modes.default_mode = PM16;
157 } 157 }
158 FPU_EIP += code_base = SEG_BASE_ADDR(code_descriptor); 158 FPU_EIP += code_base = seg_get_base(&code_descriptor);
159 code_limit = code_base 159 code_limit = seg_get_limit(&code_descriptor) + 1;
160 + (SEG_LIMIT(code_descriptor) + 160 code_limit *= seg_get_granularity(&code_descriptor);
161 1) * SEG_GRANULARITY(code_descriptor) 161 code_limit += code_base - 1;
162 - 1;
163 if (code_limit < code_base) 162 if (code_limit < code_base)
164 code_limit = 0xffffffff; 163 code_limit = 0xffffffff;
165 } 164 }
diff --git a/arch/x86/math-emu/fpu_system.h b/arch/x86/math-emu/fpu_system.h
index a179254a5122..699f329f1d40 100644
--- a/arch/x86/math-emu/fpu_system.h
+++ b/arch/x86/math-emu/fpu_system.h
@@ -34,17 +34,43 @@ static inline struct desc_struct FPU_get_ldt_descriptor(unsigned seg)
34 return ret; 34 return ret;
35} 35}
36 36
37#define SEG_D_SIZE(x) ((x).b & (3 << 21)) 37#define SEG_TYPE_WRITABLE (1U << 1)
38#define SEG_G_BIT(x) ((x).b & (1 << 23)) 38#define SEG_TYPE_EXPANDS_DOWN (1U << 2)
39#define SEG_GRANULARITY(x) (((x).b & (1 << 23)) ? 4096 : 1) 39#define SEG_TYPE_EXECUTE (1U << 3)
40#define SEG_286_MODE(x) ((x).b & ( 0xff000000 | 0xf0000 | (1 << 23))) 40#define SEG_TYPE_EXPAND_MASK (SEG_TYPE_EXPANDS_DOWN | SEG_TYPE_EXECUTE)
41#define SEG_BASE_ADDR(s) (((s).b & 0xff000000) \ 41#define SEG_TYPE_EXECUTE_MASK (SEG_TYPE_WRITABLE | SEG_TYPE_EXECUTE)
42 | (((s).b & 0xff) << 16) | ((s).a >> 16)) 42
43#define SEG_LIMIT(s) (((s).b & 0xff0000) | ((s).a & 0xffff)) 43static inline unsigned long seg_get_base(struct desc_struct *d)
44#define SEG_EXECUTE_ONLY(s) (((s).b & ((1 << 11) | (1 << 9))) == (1 << 11)) 44{
45#define SEG_WRITE_PERM(s) (((s).b & ((1 << 11) | (1 << 9))) == (1 << 9)) 45 unsigned long base = (unsigned long)d->base2 << 24;
46#define SEG_EXPAND_DOWN(s) (((s).b & ((1 << 11) | (1 << 10))) \ 46
47 == (1 << 10)) 47 return base | ((unsigned long)d->base1 << 16) | d->base0;
48}
49
50static inline unsigned long seg_get_limit(struct desc_struct *d)
51{
52 return ((unsigned long)d->limit1 << 16) | d->limit0;
53}
54
55static inline unsigned long seg_get_granularity(struct desc_struct *d)
56{
57 return d->g ? 4096 : 1;
58}
59
60static inline bool seg_expands_down(struct desc_struct *d)
61{
62 return (d->type & SEG_TYPE_EXPAND_MASK) == SEG_TYPE_EXPANDS_DOWN;
63}
64
65static inline bool seg_execute_only(struct desc_struct *d)
66{
67 return (d->type & SEG_TYPE_EXECUTE_MASK) == SEG_TYPE_EXECUTE;
68}
69
70static inline bool seg_writable(struct desc_struct *d)
71{
72 return (d->type & SEG_TYPE_EXECUTE_MASK) == SEG_TYPE_WRITABLE;
73}
48 74
49#define I387 (&current->thread.fpu.state) 75#define I387 (&current->thread.fpu.state)
50#define FPU_info (I387->soft.info) 76#define FPU_info (I387->soft.info)
diff --git a/arch/x86/math-emu/get_address.c b/arch/x86/math-emu/get_address.c
index b8ef9f9d2ffc..c48967c6a0e2 100644
--- a/arch/x86/math-emu/get_address.c
+++ b/arch/x86/math-emu/get_address.c
@@ -159,17 +159,18 @@ static long pm_address(u_char FPU_modrm, u_char segment,
159 } 159 }
160 160
161 descriptor = FPU_get_ldt_descriptor(addr->selector); 161 descriptor = FPU_get_ldt_descriptor(addr->selector);
162 base_address = SEG_BASE_ADDR(descriptor); 162 base_address = seg_get_base(&descriptor);
163 address = base_address + offset; 163 address = base_address + offset;
164 limit = base_address 164 limit = seg_get_limit(&descriptor) + 1;
165 + (SEG_LIMIT(descriptor) + 1) * SEG_GRANULARITY(descriptor) - 1; 165 limit *= seg_get_granularity(&descriptor);
166 limit += base_address - 1;
166 if (limit < base_address) 167 if (limit < base_address)
167 limit = 0xffffffff; 168 limit = 0xffffffff;
168 169
169 if (SEG_EXPAND_DOWN(descriptor)) { 170 if (seg_expands_down(&descriptor)) {
170 if (SEG_G_BIT(descriptor)) 171 if (descriptor.g) {
171 seg_top = 0xffffffff; 172 seg_top = 0xffffffff;
172 else { 173 } else {
173 seg_top = base_address + (1 << 20); 174 seg_top = base_address + (1 << 20);
174 if (seg_top < base_address) 175 if (seg_top < base_address)
175 seg_top = 0xffffffff; 176 seg_top = 0xffffffff;
@@ -182,8 +183,8 @@ static long pm_address(u_char FPU_modrm, u_char segment,
182 (address > limit) || (address < base_address) ? 0 : 183 (address > limit) || (address < base_address) ? 0 :
183 ((limit - address) >= 254 ? 255 : limit - address + 1); 184 ((limit - address) >= 254 ? 255 : limit - address + 1);
184 } 185 }
185 if (SEG_EXECUTE_ONLY(descriptor) || 186 if (seg_execute_only(&descriptor) ||
186 (!SEG_WRITE_PERM(descriptor) && (FPU_modrm & FPU_WRITE_BIT))) { 187 (!seg_writable(&descriptor) && (FPU_modrm & FPU_WRITE_BIT))) {
187 access_limit = 0; 188 access_limit = 0;
188 } 189 }
189 return address; 190 return address;
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 0cdf14cf3270..b836a7274e12 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -1258,10 +1258,6 @@ static inline bool smap_violation(int error_code, struct pt_regs *regs)
1258 * This routine handles page faults. It determines the address, 1258 * This routine handles page faults. It determines the address,
1259 * and the problem, and then passes it off to one of the appropriate 1259 * and the problem, and then passes it off to one of the appropriate
1260 * routines. 1260 * routines.
1261 *
1262 * This function must have noinline because both callers
1263 * {,trace_}do_page_fault() have notrace on. Having this an actual function
1264 * guarantees there's a function trace entry.
1265 */ 1261 */
1266static noinline void 1262static noinline void
1267__do_page_fault(struct pt_regs *regs, unsigned long error_code, 1263__do_page_fault(struct pt_regs *regs, unsigned long error_code,
@@ -1494,27 +1490,6 @@ good_area:
1494} 1490}
1495NOKPROBE_SYMBOL(__do_page_fault); 1491NOKPROBE_SYMBOL(__do_page_fault);
1496 1492
1497dotraplinkage void notrace
1498do_page_fault(struct pt_regs *regs, unsigned long error_code)
1499{
1500 unsigned long address = read_cr2(); /* Get the faulting address */
1501 enum ctx_state prev_state;
1502
1503 /*
1504 * We must have this function tagged with __kprobes, notrace and call
1505 * read_cr2() before calling anything else. To avoid calling any kind
1506 * of tracing machinery before we've observed the CR2 value.
1507 *
1508 * exception_{enter,exit}() contain all sorts of tracepoints.
1509 */
1510
1511 prev_state = exception_enter();
1512 __do_page_fault(regs, error_code, address);
1513 exception_exit(prev_state);
1514}
1515NOKPROBE_SYMBOL(do_page_fault);
1516
1517#ifdef CONFIG_TRACING
1518static nokprobe_inline void 1493static nokprobe_inline void
1519trace_page_fault_entries(unsigned long address, struct pt_regs *regs, 1494trace_page_fault_entries(unsigned long address, struct pt_regs *regs,
1520 unsigned long error_code) 1495 unsigned long error_code)
@@ -1525,22 +1500,24 @@ trace_page_fault_entries(unsigned long address, struct pt_regs *regs,
1525 trace_page_fault_kernel(address, regs, error_code); 1500 trace_page_fault_kernel(address, regs, error_code);
1526} 1501}
1527 1502
1503/*
1504 * We must have this function blacklisted from kprobes, tagged with notrace
1505 * and call read_cr2() before calling anything else. To avoid calling any
1506 * kind of tracing machinery before we've observed the CR2 value.
1507 *
1508 * exception_{enter,exit}() contains all sorts of tracepoints.
1509 */
1528dotraplinkage void notrace 1510dotraplinkage void notrace
1529trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) 1511do_page_fault(struct pt_regs *regs, unsigned long error_code)
1530{ 1512{
1531 /* 1513 unsigned long address = read_cr2(); /* Get the faulting address */
1532 * The exception_enter and tracepoint processing could
1533 * trigger another page faults (user space callchain
1534 * reading) and destroy the original cr2 value, so read
1535 * the faulting address now.
1536 */
1537 unsigned long address = read_cr2();
1538 enum ctx_state prev_state; 1514 enum ctx_state prev_state;
1539 1515
1540 prev_state = exception_enter(); 1516 prev_state = exception_enter();
1541 trace_page_fault_entries(address, regs, error_code); 1517 if (trace_pagefault_enabled())
1518 trace_page_fault_entries(address, regs, error_code);
1519
1542 __do_page_fault(regs, error_code, address); 1520 __do_page_fault(regs, error_code, address);
1543 exception_exit(prev_state); 1521 exception_exit(prev_state);
1544} 1522}
1545NOKPROBE_SYMBOL(trace_do_page_fault); 1523NOKPROBE_SYMBOL(do_page_fault);
1546#endif /* CONFIG_TRACING */
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index 6c279c8f0a0e..ae2a2e2d6362 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -501,7 +501,7 @@ static void __init xen_load_gdt_boot(const struct desc_ptr *dtr)
501static inline bool desc_equal(const struct desc_struct *d1, 501static inline bool desc_equal(const struct desc_struct *d1,
502 const struct desc_struct *d2) 502 const struct desc_struct *d2)
503{ 503{
504 return d1->a == d2->a && d1->b == d2->b; 504 return !memcmp(d1, d2, sizeof(*d1));
505} 505}
506 506
507static void load_TLS_descriptor(struct thread_struct *t, 507static void load_TLS_descriptor(struct thread_struct *t,
@@ -586,59 +586,91 @@ static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum,
586 preempt_enable(); 586 preempt_enable();
587} 587}
588 588
589#ifdef CONFIG_X86_64
590struct trap_array_entry {
591 void (*orig)(void);
592 void (*xen)(void);
593 bool ist_okay;
594};
595
596static struct trap_array_entry trap_array[] = {
597 { debug, xen_xendebug, true },
598 { int3, xen_xenint3, true },
599 { double_fault, xen_double_fault, true },
600#ifdef CONFIG_X86_MCE
601 { machine_check, xen_machine_check, true },
602#endif
603 { nmi, xen_nmi, true },
604 { overflow, xen_overflow, false },
605#ifdef CONFIG_IA32_EMULATION
606 { entry_INT80_compat, xen_entry_INT80_compat, false },
607#endif
608 { page_fault, xen_page_fault, false },
609 { divide_error, xen_divide_error, false },
610 { bounds, xen_bounds, false },
611 { invalid_op, xen_invalid_op, false },
612 { device_not_available, xen_device_not_available, false },
613 { coprocessor_segment_overrun, xen_coprocessor_segment_overrun, false },
614 { invalid_TSS, xen_invalid_TSS, false },
615 { segment_not_present, xen_segment_not_present, false },
616 { stack_segment, xen_stack_segment, false },
617 { general_protection, xen_general_protection, false },
618 { spurious_interrupt_bug, xen_spurious_interrupt_bug, false },
619 { coprocessor_error, xen_coprocessor_error, false },
620 { alignment_check, xen_alignment_check, false },
621 { simd_coprocessor_error, xen_simd_coprocessor_error, false },
622};
623
624static bool get_trap_addr(void **addr, unsigned int ist)
625{
626 unsigned int nr;
627 bool ist_okay = false;
628
629 /*
630 * Replace trap handler addresses by Xen specific ones.
631 * Check for known traps using IST and whitelist them.
632 * The debugger ones are the only ones we care about.
633 * Xen will handle faults like double_fault, * so we should never see
634 * them. Warn if there's an unexpected IST-using fault handler.
635 */
636 for (nr = 0; nr < ARRAY_SIZE(trap_array); nr++) {
637 struct trap_array_entry *entry = trap_array + nr;
638
639 if (*addr == entry->orig) {
640 *addr = entry->xen;
641 ist_okay = entry->ist_okay;
642 break;
643 }
644 }
645
646 if (WARN_ON(ist != 0 && !ist_okay))
647 return false;
648
649 return true;
650}
651#endif
652
589static int cvt_gate_to_trap(int vector, const gate_desc *val, 653static int cvt_gate_to_trap(int vector, const gate_desc *val,
590 struct trap_info *info) 654 struct trap_info *info)
591{ 655{
592 unsigned long addr; 656 unsigned long addr;
593 657
594 if (val->type != GATE_TRAP && val->type != GATE_INTERRUPT) 658 if (val->bits.type != GATE_TRAP && val->bits.type != GATE_INTERRUPT)
595 return 0; 659 return 0;
596 660
597 info->vector = vector; 661 info->vector = vector;
598 662
599 addr = gate_offset(*val); 663 addr = gate_offset(val);
600#ifdef CONFIG_X86_64 664#ifdef CONFIG_X86_64
601 /* 665 if (!get_trap_addr((void **)&addr, val->bits.ist))
602 * Look for known traps using IST, and substitute them
603 * appropriately. The debugger ones are the only ones we care
604 * about. Xen will handle faults like double_fault,
605 * so we should never see them. Warn if
606 * there's an unexpected IST-using fault handler.
607 */
608 if (addr == (unsigned long)debug)
609 addr = (unsigned long)xen_debug;
610 else if (addr == (unsigned long)int3)
611 addr = (unsigned long)xen_int3;
612 else if (addr == (unsigned long)stack_segment)
613 addr = (unsigned long)xen_stack_segment;
614 else if (addr == (unsigned long)double_fault) {
615 /* Don't need to handle these */
616 return 0; 666 return 0;
617#ifdef CONFIG_X86_MCE
618 } else if (addr == (unsigned long)machine_check) {
619 /*
620 * when xen hypervisor inject vMCE to guest,
621 * use native mce handler to handle it
622 */
623 ;
624#endif
625 } else if (addr == (unsigned long)nmi)
626 /*
627 * Use the native version as well.
628 */
629 ;
630 else {
631 /* Some other trap using IST? */
632 if (WARN_ON(val->ist != 0))
633 return 0;
634 }
635#endif /* CONFIG_X86_64 */ 667#endif /* CONFIG_X86_64 */
636 info->address = addr; 668 info->address = addr;
637 669
638 info->cs = gate_segment(*val); 670 info->cs = gate_segment(val);
639 info->flags = val->dpl; 671 info->flags = val->bits.dpl;
640 /* interrupt gates clear IF */ 672 /* interrupt gates clear IF */
641 if (val->type == GATE_INTERRUPT) 673 if (val->bits.type == GATE_INTERRUPT)
642 info->flags |= 1 << 2; 674 info->flags |= 1 << 2;
643 675
644 return 1; 676 return 1;
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 33e92955e09d..d4eff5676cfa 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -123,9 +123,6 @@ static const struct pv_irq_ops xen_irq_ops __initconst = {
123 123
124 .safe_halt = xen_safe_halt, 124 .safe_halt = xen_safe_halt,
125 .halt = xen_halt, 125 .halt = xen_halt,
126#ifdef CONFIG_X86_64
127 .adjust_exception_frame = xen_adjust_exception_frame,
128#endif
129}; 126};
130 127
131void __init xen_init_irq_ops(void) 128void __init xen_init_irq_ops(void)
diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S
index 3a3b6a211584..dae2cc33afb5 100644
--- a/arch/x86/xen/xen-asm_64.S
+++ b/arch/x86/xen/xen-asm_64.S
@@ -16,11 +16,42 @@
16 16
17#include <linux/linkage.h> 17#include <linux/linkage.h>
18 18
19ENTRY(xen_adjust_exception_frame) 19.macro xen_pv_trap name
20 mov 8+0(%rsp), %rcx 20ENTRY(xen_\name)
21 mov 8+8(%rsp), %r11 21 pop %rcx
22 ret $16 22 pop %r11
23ENDPROC(xen_adjust_exception_frame) 23 jmp \name
24END(xen_\name)
25.endm
26
27xen_pv_trap divide_error
28xen_pv_trap debug
29xen_pv_trap xendebug
30xen_pv_trap int3
31xen_pv_trap xenint3
32xen_pv_trap nmi
33xen_pv_trap overflow
34xen_pv_trap bounds
35xen_pv_trap invalid_op
36xen_pv_trap device_not_available
37xen_pv_trap double_fault
38xen_pv_trap coprocessor_segment_overrun
39xen_pv_trap invalid_TSS
40xen_pv_trap segment_not_present
41xen_pv_trap stack_segment
42xen_pv_trap general_protection
43xen_pv_trap page_fault
44xen_pv_trap spurious_interrupt_bug
45xen_pv_trap coprocessor_error
46xen_pv_trap alignment_check
47#ifdef CONFIG_X86_MCE
48xen_pv_trap machine_check
49#endif /* CONFIG_X86_MCE */
50xen_pv_trap simd_coprocessor_error
51#ifdef CONFIG_IA32_EMULATION
52xen_pv_trap entry_INT80_compat
53#endif
54xen_pv_trap hypervisor_callback
24 55
25hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32 56hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32
26/* 57/*
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 70301ac0d414..c8a6d224f7ed 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -138,7 +138,6 @@ __visible void xen_restore_fl_direct(unsigned long);
138__visible void xen_iret(void); 138__visible void xen_iret(void);
139__visible void xen_sysret32(void); 139__visible void xen_sysret32(void);
140__visible void xen_sysret64(void); 140__visible void xen_sysret64(void);
141__visible void xen_adjust_exception_frame(void);
142 141
143extern int xen_panic_handler_init(void); 142extern int xen_panic_handler_init(void);
144 143
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 2d43118077e4..1ab4bd11f5f3 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -1653,10 +1653,8 @@ void xen_callback_vector(void)
1653 return; 1653 return;
1654 } 1654 }
1655 pr_info("Xen HVM callback vector for event delivery is enabled\n"); 1655 pr_info("Xen HVM callback vector for event delivery is enabled\n");
1656 /* in the restore case the vector has already been allocated */ 1656 alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
1657 if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) 1657 xen_hvm_callback_vector);
1658 alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
1659 xen_hvm_callback_vector);
1660 } 1658 }
1661} 1659}
1662#else 1660#else