x86: Cleanup IDT code
Subsystems (9)
v3 cover x86: Cleanup IDT code
This is the 3rd iteration of the series. The previous version can be found here:
http://lkml.kernel.org/r/[email protected]
The series applies on top of
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/apic
and is available as a git branch from
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git WIP.x86/apic
Changes since V2:
- Addressed the review comments
- Addressed the fallout reported by kbuild robot
- Picked up acks and reviewed by tags
Thanks,
tglx
----
arch/x86/boot/compressed/eboot.c | 8 arch/x86/entry/entry_32.S | 20 - arch/x86/entry/entry_64.S | 26 -- arch/x86/entry/vdso/vma.c | 2 arch/x86/include/asm/desc.h | 248 +++----------------- arch/x86/include/asm/desc_defs.h | 122 +++++----- arch/x86/include/asm/entry_arch.h | 17 - arch/x86/include/asm/hw_irq.h | 20 - arch/x86/include/asm/irq.h | 4 arch/x86/include/asm/irq_work.h | 8 arch/x86/include/asm/segment.h | 4 arch/x86/include/asm/trace/common.h | 16 + arch/x86/include/asm/trace/exceptions.h | 8 arch/x86/include/asm/trace/irq_vectors.h | 51 +++- arch/x86/include/asm/traps.h | 10 arch/x86/include/asm/xen/hypercall.h | 6 arch/x86/kernel/Makefile | 3 arch/x86/kernel/apic/apic.c | 70 +---- arch/x86/kernel/apic/vector.c | 2 arch/x86/kernel/cpu/common.c | 9 arch/x86/kernel/cpu/mcheck/mce_amd.c | 16 - arch/x86/kernel/cpu/mcheck/therm_throt.c | 20 - arch/x86/kernel/cpu/mcheck/threshold.c | 16 - arch/x86/kernel/cpu/mshyperv.c | 9 arch/x86/kernel/eisa.c | 18 + arch/x86/kernel/head32.c | 4 arch/x86/kernel/head64.c | 6 arch/x86/kernel/head_32.S | 42 --- arch/x86/kernel/idt.c | 367 +++++++++++++++++++++++++++++++ arch/x86/kernel/irq.c | 40 +-- arch/x86/kernel/irq_work.c | 20 - arch/x86/kernel/irqinit.c | 102 -------- arch/x86/kernel/kvm.c | 4 arch/x86/kernel/machine_kexec_32.c | 14 - arch/x86/kernel/reboot.c | 4 arch/x86/kernel/setup.c | 4 arch/x86/kernel/setup_percpu.c | 9 arch/x86/kernel/smp.c | 81 +----- arch/x86/kernel/tls.c | 2 arch/x86/kernel/tracepoint.c | 57 +--- arch/x86/kernel/traps.c | 107 --------- arch/x86/kvm/vmx.c | 2 arch/x86/math-emu/fpu_entry.c | 11 arch/x86/math-emu/fpu_system.h | 48 +++- arch/x86/math-emu/get_address.c | 17 - arch/x86/mm/fault.c | 49 +--- arch/x86/xen/enlighten_pv.c | 14 - drivers/xen/events/events_base.c | 6 48 files changed, 760 insertions(+), 983 deletions(-)
PATCH v3 1/44 x86/irq: Remove vector_used_by_percpu_irq()
Last user (lguest) is gone. Remove it.
--- arch/x86/include/asm/irq.h | 1 - arch/x86/kernel/irq.c | 2 -- arch/x86/kernel/irqinit.c | 12 ------------ 3 files changed, 15 deletions(-)
arch/x86/include/asm/irq.h +0 -1
@@ -44,7 +44,6 @@ extern __visible unsigned int do_IRQ(str/* Interrupt vector management */ extern DECLARE_BITMAP(used_vectors, NR_VECTORS); -extern int vector_used_by_percpu_irq (unsigned int vector);extern void init_ISA_irqs (void );
arch/x86/kernel/irq.c +0 -2
@@ -346,8 +346,6 @@ EXPORT_SYMBOL_GPL(kvm_set_posted_intr_waset_irq_regs (old_regs); } -EXPORT_SYMBOL_GPL (vector_used_by_percpu_irq); -#ifdef CONFIG_HOTPLUG_CPU /* These two declarations are only used in check_irq_vectors_for_cpu_disable()
arch/x86/kernel/irqinit.c +0 -12
@@ -55,18 +55,6 @@ DEFINE_PER_CPU(vector_irq_t, vector_irq) [0 ... NR_VECTORS - 1] = VECTOR_UNUSED, }; -int vector_used_by_percpu_irq (unsigned int vector) -{ -int cpu; - -for_each_online_cpu (cpu) { -if (!IS_ERR_OR_NULL (per_cpu (vector_irq, cpu)[vector])) -return 1 ; - } - -return 0 ; -} -void __init init_ISA_irqs (void ) {struct irq_chip *chip = legacy_pic->chip;
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/irq: Remove vector_used_by_percpu_irq()
x86/irq: Remove vector_used_by_percpu_irq()
Commit-ID: 69de72ec6db950c436e36b94cf05eeb9e11ee144 Gitweb: http://git.kernel.org/tip/69de72ec6db950c436e36b94cf05eeb9e11ee144 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:16 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:20 +0200
x86/irq: Remove vector_used_by_percpu_irq()
Last user (lguest) is gone. Remove it.
--- arch/x86/include/asm/irq.h | 1 - arch/x86/kernel/irq.c | 2 -- arch/x86/kernel/irqinit.c | 12 ------------ 3 files changed, 15 deletions(-)
arch/x86/include/asm/irq.h +0 -1
@@ -44,7 +44,6 @@ extern __visible unsigned int do_IRQ(struct pt_regs *regs);/* Interrupt vector management */ extern DECLARE_BITMAP(used_vectors, NR_VECTORS); -extern int vector_used_by_percpu_irq (unsigned int vector);extern void init_ISA_irqs (void );
arch/x86/kernel/irq.c +0 -2
@@ -346,8 +346,6 @@ __visible void __irq_entry smp_trace_x86_platform_ipi(struct pt_regs *regs)set_irq_regs (old_regs); } -EXPORT_SYMBOL_GPL (vector_used_by_percpu_irq); -#ifdef CONFIG_HOTPLUG_CPU /* These two declarations are only used in check_irq_vectors_for_cpu_disable()
arch/x86/kernel/irqinit.c +0 -12
@@ -55,18 +55,6 @@ DEFINE_PER_CPU(vector_irq_t, vector_irq) = { [0 ... NR_VECTORS - 1] = VECTOR_UNUSED, }; -int vector_used_by_percpu_irq (unsigned int vector) -{ -int cpu; - -for_each_online_cpu (cpu) { -if (!IS_ERR_OR_NULL (per_cpu (vector_irq, cpu)[vector])) -return 1 ; - } - -return 0 ; -} -void __init init_ISA_irqs (void ) {struct irq_chip *chip = legacy_pic->chip;
PATCH v3 2/44 x86/irq: Unexport used_vectors
In reply to Thomas GleixnerNo modular users.
--- arch/x86/kernel/traps.c | 1 - 1 file changed, 1 deletion(-)
arch/x86/kernel/traps.c +0 -1
@@ -83,7 +83,6 @@ gate_desc debug_idt_table[NR_VECTORS] __ gate_desc idt_table[NR_VECTORS] __page_aligned_bss;DECLARE_BITMAP (used_vectors,NR_VECTORS ); -EXPORT_SYMBOL_GPL (used_vectors);static inline void cond_local_irq_enable (struct pt_regs *regs) {
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/irq: Unexport used_vectors[]
x86/irq: Unexport used_vectors[]
Commit-ID: fa4ab5774dfe58fd5e99462f625253659d41df09 Gitweb: http://git.kernel.org/tip/fa4ab5774dfe58fd5e99462f625253659d41df09 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:17 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:20 +0200
x86/irq: Unexport used_vectors[]
No modular users.
--- arch/x86/kernel/traps.c | 1 - 1 file changed, 1 deletion(-)
arch/x86/kernel/traps.c +0 -1
@@ -83,7 +83,6 @@ gate_desc debug_idt_table[NR_VECTORS] __page_aligned_bss; gate_desc idt_table[NR_VECTORS] __page_aligned_bss;DECLARE_BITMAP (used_vectors,NR_VECTORS ); -EXPORT_SYMBOL_GPL (used_vectors);static inline void cond_local_irq_enable (struct pt_regs *regs) {
PATCH v3 3/44 x86/irq: Get rid of the first_system_vector bogisity
In reply to Thomas GleixnerThis variable is beyond pointless. Nothing allocates a vector via alloc_gate() below FIRST_SYSTEM_VECTOR. So nothing can change first_system_vector.
If there is a need for a gate below FIRST_SYSTEM_VECTOR then it can be added to the vector defines and FIRST_SYSTEM_VECTOR adjusted accordingly.
--- arch/x86/include/asm/desc.h | 5 ++--- arch/x86/kernel/apic/apic.c | 2 -- arch/x86/kernel/apic/vector.c | 2 +- arch/x86/kernel/irq.c | 2 +- arch/x86/kernel/irqinit.c | 5 +---- 5 files changed, 5 insertions(+), 11 deletions(-)
arch/x86/include/asm/desc.h +2 -3
@@ -5,6 +5,7 @@#include <asm/ldt.h> #include <asm/mmu.h> #include <asm/fixmap.h> +#include <asm/irq_vectors.h> #include <linux/smp.h> #include <linux/percpu.h>
@@ -482,16 +483,14 @@ static inline void _set_gate(int gate, u 0, 0, __KERNEL_CS); \ }while (0 ) -extern int first_system_vector;/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */ extern unsigned long used_vectors[];static inline void alloc_system_vector (int vector) { +BUG_ON (vector <FIRST_SYSTEM_VECTOR );if (!test_bit (vector, used_vectors)) {set_bit (vector, used_vectors); -if (first_system_vector > vector) - first_system_vector = vector; }else {BUG (); }
arch/x86/kernel/apic/apic.c +0 -2
@@ -177,8 +177,6 @@ static int disable_apic_timer __initdataint local_apic_timer_c2_ok;EXPORT_SYMBOL_GPL (local_apic_timer_c2_ok); -int first_system_vector =FIRST_SYSTEM_VECTOR ; -/* * Debug level, exported for io_apic.c */
arch/x86/kernel/apic/vector.c +1 -1
@@ -166,7 +166,7 @@ static int __assign_irq_vector(int irq, offset = current_offset; next: vector +=16 ; -if (vector >= first_system_vector) { +if (vector >=FIRST_SYSTEM_VECTOR ) { offset = (offset +1 ) %16 ; vector =FIRST_EXTERNAL_VECTOR + offset; }
arch/x86/kernel/irq.c +1 -1
@@ -429,7 +429,7 @@ int check_irq_vectors_for_cpu_disable(vo* this w/o holding vector_lock. */ for (vector =FIRST_EXTERNAL_VECTOR ; - vector < first_system_vector; vector++) { + vector <FIRST_SYSTEM_VECTOR ; vector++) {if (!test_bit (vector, used_vectors) &&IS_ERR_OR_NULL (per_cpu (vector_irq, cpu)[vector])) {if (++count == this_count)
arch/x86/kernel/irqinit.c +1 -4
@@ -169,10 +169,7 @@ void __init native_init_IRQ(void)* 'special' SMP interrupts) */ i =FIRST_EXTERNAL_VECTOR ; -#ifndef CONFIG_X86_LOCAL_APIC -#define first_system_vector NR_VECTORS -#endif -for_each_clear_bit_from (i, used_vectors, first_system_vector) { +for_each_clear_bit_from (i, used_vectors,FIRST_SYSTEM_VECTOR ) {/* IA32_SYSCALL_VECTOR could be used in trap_init already. */ set_intr_gate (i, irq_entries_start +8 * (i -FIRST_EXTERNAL_VECTOR ));
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/irq: Get rid of the 'first_system_vector' indirection bogosity
x86/irq: Get rid of the 'first_system_vector' indirection bogosity
Commit-ID: 05161b9cbe553c41cf775ac41bb5120d94347e5c Gitweb: http://git.kernel.org/tip/05161b9cbe553c41cf775ac41bb5120d94347e5c Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:18 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:21 +0200
x86/irq: Get rid of the 'first_system_vector' indirection bogosity
This variable is beyond pointless. Nothing allocates a vector via alloc_gate() below FIRST_SYSTEM_VECTOR. So nothing can change first_system_vector.
If there is a need for a gate below FIRST_SYSTEM_VECTOR then it can be added to the vector defines and FIRST_SYSTEM_VECTOR can be adjusted accordingly.
--- arch/x86/include/asm/desc.h | 5 ++--- arch/x86/kernel/apic/apic.c | 2 -- arch/x86/kernel/apic/vector.c | 2 +- arch/x86/kernel/irq.c | 2 +- arch/x86/kernel/irqinit.c | 5 +---- 5 files changed, 5 insertions(+), 11 deletions(-)
arch/x86/include/asm/desc.h +2 -3
@@ -5,6 +5,7 @@#include <asm/ldt.h> #include <asm/mmu.h> #include <asm/fixmap.h> +#include <asm/irq_vectors.h> #include <linux/smp.h> #include <linux/percpu.h>
@@ -482,16 +483,14 @@ static inline void _set_gate(int gate, unsigned type, void *addr, 0, 0, __KERNEL_CS); \ }while (0 ) -extern int first_system_vector;/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */ extern unsigned long used_vectors[];static inline void alloc_system_vector (int vector) { +BUG_ON (vector <FIRST_SYSTEM_VECTOR );if (!test_bit (vector, used_vectors)) {set_bit (vector, used_vectors); -if (first_system_vector > vector) - first_system_vector = vector; }else {BUG (); }
arch/x86/kernel/apic/apic.c +0 -2
@@ -177,8 +177,6 @@ static int disable_apic_timer __initdata;int local_apic_timer_c2_ok;EXPORT_SYMBOL_GPL (local_apic_timer_c2_ok); -int first_system_vector =FIRST_SYSTEM_VECTOR ; -/* * Debug level, exported for io_apic.c */
arch/x86/kernel/apic/vector.c +1 -1
@@ -166,7 +166,7 @@ static int __assign_irq_vector(int irq, struct apic_chip_data *d, offset = current_offset; next: vector +=16 ; -if (vector >= first_system_vector) { +if (vector >=FIRST_SYSTEM_VECTOR ) { offset = (offset +1 ) %16 ; vector =FIRST_EXTERNAL_VECTOR + offset; }
arch/x86/kernel/irq.c +1 -1
@@ -429,7 +429,7 @@ int check_irq_vectors_for_cpu_disable(void)* this w/o holding vector_lock. */ for (vector =FIRST_EXTERNAL_VECTOR ; - vector < first_system_vector; vector++) { + vector <FIRST_SYSTEM_VECTOR ; vector++) {if (!test_bit (vector, used_vectors) &&IS_ERR_OR_NULL (per_cpu (vector_irq, cpu)[vector])) {if (++count == this_count)
arch/x86/kernel/irqinit.c +1 -4
@@ -169,10 +169,7 @@ void __init native_init_IRQ(void)* 'special' SMP interrupts) */ i =FIRST_EXTERNAL_VECTOR ; -#ifndef CONFIG_X86_LOCAL_APIC -#define first_system_vector NR_VECTORS -#endif -for_each_clear_bit_from (i, used_vectors, first_system_vector) { +for_each_clear_bit_from (i, used_vectors,FIRST_SYSTEM_VECTOR ) {/* IA32_SYSCALL_VECTOR could be used in trap_init already. */ set_intr_gate (i, irq_entries_start +8 * (i -FIRST_EXTERNAL_VECTOR ));
PATCH v3 4/44 x86/irq: Remove duplicated used_vectors definition
In reply to Thomas GleixnerRemove the unparseable comment in the other place while at it.
--- arch/x86/include/asm/desc.h | 1 - arch/x86/include/asm/irq.h | 3 --- 2 files changed, 4 deletions(-)
arch/x86/include/asm/desc.h +0 -1
@@ -483,7 +483,6 @@ static inline void _set_gate(int gate, u 0, 0, __KERNEL_CS); \ }while (0 ) -/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */ extern unsigned long used_vectors[];static inline void alloc_system_vector (int vector)
arch/x86/include/asm/irq.h +0 -3
@@ -42,9 +42,6 @@ extern bool handle_irq(struct irq_desc * extern __visible unsigned int do_IRQ(struct pt_regs *regs); -/* Interrupt vector management */ -extern DECLARE_BITMAP(used_vectors, NR_VECTORS); -extern void init_ISA_irqs (void );#ifdef CONFIG_X86_LOCAL_APIC
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/irq: Remove duplicated used_vectors definition
x86/irq: Remove duplicated used_vectors definition
Commit-ID: 9aec458ff07323f6593fd718cc33b1bca2f64597 Gitweb: http://git.kernel.org/tip/9aec458ff07323f6593fd718cc33b1bca2f64597 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:19 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:21 +0200
x86/irq: Remove duplicated used_vectors definition
Also remove the unparseable comment in the other place while at it.
--- arch/x86/include/asm/desc.h | 1 - arch/x86/include/asm/irq.h | 3 --- 2 files changed, 4 deletions(-)
arch/x86/include/asm/desc.h +0 -1
@@ -483,7 +483,6 @@ static inline void _set_gate(int gate, unsigned type, void *addr, 0, 0, __KERNEL_CS); \ }while (0 ) -/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */ extern unsigned long used_vectors[];static inline void alloc_system_vector (int vector)
arch/x86/include/asm/irq.h +0 -3
@@ -42,9 +42,6 @@ extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs); extern __visible unsigned int do_IRQ(struct pt_regs *regs); -/* Interrupt vector management */ -extern DECLARE_BITMAP(used_vectors, NR_VECTORS); -extern void init_ISA_irqs (void );#ifdef CONFIG_X86_LOCAL_APIC
PATCH v3 5/44 x86/boot: Move EISA setup to a proper place
In reply to Thomas GleixnerEISA has absolutely nothing to do with traps. The EISA bus detection does not need to run in the very early boot. It's good enough to run it before the EISA bus and drivers are initialized.
--- arch/x86/kernel/Makefile | 1 + arch/x86/kernel/eisa.c | 18 ++++++++++++++++++ arch/x86/kernel/traps.c | 13 ------------- 3 files changed, 19 insertions(+), 13 deletions(-)
arch/x86/kernel/Makefile +1 -0
@@ -111,6 +111,7 @@ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= parav obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o obj-$(CONFIG_X86_PMEM_LEGACY_DEVICE) += pmem.o +obj-$(CONFIG_EISA) += eisa.o obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
arch/x86/kernel/eisa.c new file +18 -0
@@ -0,0 +1,18 @@ +/* +* EISA specific code +* +* This file is licensed under the GPL V2 +*/ +#include <linux/ioport.h> +#include <linux/eisa.h> + +static __init int eisa_bus_probe (void ) +{ +void __iomem *p =ioremap (0x0FFFD9 ,4 ); + +if (readl (p) =='E' + ('I' <<8 ) + ('S' <<16 ) + ('A' <<24 )) + EISA_bus =1 ; +iounmap (p); +return 0 ; +} +subsys_initcall (eisa_bus_probe);
arch/x86/kernel/traps.c +0 -13
@@ -38,11 +38,6 @@#include <linux/smp.h> #include <linux/io.h> -#ifdef CONFIG_EISA -#include <linux/ioport.h> -#include <linux/eisa.h> -#endif -#if defined(CONFIG_EDAC )#include <linux/edac.h> #endif
@@ -969,14 +964,6 @@ void __init trap_init(void) {int i; -#ifdef CONFIG_EISA -void __iomem *p =early_ioremap (0x0FFFD9 ,4 ); - -if (readl (p) =='E' + ('I' <<8 ) + ('S' <<16 ) + ('A' <<24 )) - EISA_bus =1 ; -early_iounmap (p,4 ); -#endif -set_intr_gate (X86_TRAP_DE , divide_error);set_intr_gate_ist (X86_TRAP_NMI , &nmi,NMI_STACK );/* int4 can be called from all */
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/boot: Move EISA setup to a separate file
x86/boot: Move EISA setup to a separate file
Commit-ID: f7eaf6e00fd581043bb540dfe865f1d81769b189 Gitweb: http://git.kernel.org/tip/f7eaf6e00fd581043bb540dfe865f1d81769b189 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:20 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:22 +0200
x86/boot: Move EISA setup to a separate file
EISA has absolutely nothing to do with traps, so move it out of traps.c into its own eisa.c file.
Furthermore, the EISA bus detection does not need to run during very early boot, it's good enough to run it before the EISA bus and drivers are initialized.
I.e. instead of calling it from the very early trap_init() code, make it a subsys_initcall().
--- arch/x86/kernel/Makefile | 1 + arch/x86/kernel/eisa.c | 18 ++++++++++++++++++ arch/x86/kernel/traps.c | 13 ------------- 3 files changed, 19 insertions(+), 13 deletions(-)
arch/x86/kernel/Makefile +1 -0
@@ -111,6 +111,7 @@ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o obj-$(CONFIG_X86_PMEM_LEGACY_DEVICE) += pmem.o +obj-$(CONFIG_EISA) += eisa.o obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
arch/x86/kernel/eisa.c new file +18 -0
@@ -0,0 +1,18 @@ +/* +* EISA specific code +* +* This file is licensed under the GPL V2 +*/ +#include <linux/ioport.h> +#include <linux/eisa.h> + +static __init int eisa_bus_probe (void ) +{ +void __iomem *p =ioremap (0x0FFFD9 ,4 ); + +if (readl (p) =='E' + ('I' <<8 ) + ('S' <<16 ) + ('A' <<24 )) + EISA_bus =1 ; +iounmap (p); +return 0 ; +} +subsys_initcall (eisa_bus_probe);
arch/x86/kernel/traps.c +0 -13
@@ -38,11 +38,6 @@#include <linux/smp.h> #include <linux/io.h> -#ifdef CONFIG_EISA -#include <linux/ioport.h> -#include <linux/eisa.h> -#endif -#if defined(CONFIG_EDAC )#include <linux/edac.h> #endif
@@ -969,14 +964,6 @@ void __init trap_init(void) {int i; -#ifdef CONFIG_EISA -void __iomem *p =early_ioremap (0x0FFFD9 ,4 ); - -if (readl (p) =='E' + ('I' <<8 ) + ('S' <<16 ) + ('A' <<24 )) - EISA_bus =1 ; -early_iounmap (p,4 ); -#endif -set_intr_gate (X86_TRAP_DE , divide_error);set_intr_gate_ist (X86_TRAP_NMI , &nmi,NMI_STACK );/* int4 can be called from all */
PATCH v3 6/44 x86/tracing: Introduce a static key for exception tracing
In reply to Thomas GleixnerSwitching the IDT just for avoiding tracepoints creates a complete impenetrable macro/inline/ifdef mess.
There is no point in avoiding tracepoints for most of the traps/exceptions. For the more expensive tracepoints, like pagefaults, this can be handled with an explicit static key.
Preparatory patch to remove the tracing idt.
--- arch/x86/include/asm/trace/common.h | 15 +++++++++++++++ arch/x86/include/asm/trace/exceptions.h | 4 +--- arch/x86/include/asm/trace/irq_vectors.h | 4 +--- arch/x86/kernel/tracepoint.c | 9 ++++++++- 4 files changed, 25 insertions(+), 7 deletions(-)
arch/x86/include/asm/trace/common.h new file +15 -0
@@ -0,0 +1,15 @@ +#ifndef _ASM_TRACE_COMMON_H +#define _ASM_TRACE_COMMON_H + +extern int trace_irq_vector_regfunc (void ); +extern void trace_irq_vector_unregfunc (void ); + +#ifdef CONFIG_TRACING +DECLARE_STATIC_KEY_FALSE (trace_irqvectors_key); +#define trace_irqvectors_enabled () \ + static_branch_unlikely(&trace_irqvectors_key) +#else +static inline bool trace_irqvectors_enabled (void ) {return false; } +#endif + +#endif
arch/x86/include/asm/trace/exceptions.h +1 -3
@@ -5,9 +5,7 @@#define _TRACE_PAGE_FAULT_H#include <linux/tracepoint.h> - -extern int trace_irq_vector_regfunc (void ); -extern void trace_irq_vector_unregfunc (void ); +#include <asm/trace/common.h> DECLARE_EVENT_CLASS(x86_exceptions,
arch/x86/include/asm/trace/irq_vectors.h +1 -3
@@ -5,9 +5,7 @@#define _TRACE_IRQ_VECTORS_H#include <linux/tracepoint.h> - -extern int trace_irq_vector_regfunc (void ); -extern void trace_irq_vector_unregfunc (void ); +#include <asm/trace/common.h> DECLARE_EVENT_CLASS(x86_irq_vector,
arch/x86/kernel/tracepoint.c +8 -1
@@ -4,9 +4,11 @@* Copyright (C) 2013 Seiji Aguchi <[email protected]> * */ +#include <linux/jump_label.h> +#include <linux/atomic.h> +#include <asm/hw_irq.h> #include <asm/desc.h> -#include <linux/atomic.h> atomic_t trace_idt_ctr =ATOMIC_INIT (0 );struct desc_ptr trace_idt_descr = {NR_VECTORS *16 -1 ,
@@ -15,6 +17,7 @@ struct desc_ptr trace_idt_descr = { NR_V/* No need to be aligned, but done to keep all IDTs defined the same way. */ gate_desc trace_idt_table[NR_VECTORS] __page_aligned_bss; +DEFINE_STATIC_KEY_FALSE (trace_irqvectors_key);static int trace_irq_vector_refcount;static DEFINE_MUTEX (irq_vector_mutex);
@@ -36,6 +39,8 @@ static void switch_idt(void *arg)int trace_irq_vector_regfunc (void ) { +static_branch_inc (&trace_irqvectors_key); +mutex_lock (&irq_vector_mutex);if (!trace_irq_vector_refcount) {set_trace_idt_ctr (1 );
@@ -49,6 +54,8 @@ int trace_irq_vector_regfunc(void)void trace_irq_vector_unregfunc (void ) { +static_branch_dec (&trace_irqvectors_key); +mutex_lock (&irq_vector_mutex); trace_irq_vector_refcount--;if (!trace_irq_vector_refcount) {
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/tracing: Introduce a static key for exception tracing
x86/tracing: Introduce a static key for exception tracing
Commit-ID: 2feb1b316d48004d905278c02a55902cab0be8be Gitweb: http://git.kernel.org/tip/2feb1b316d48004d905278c02a55902cab0be8be Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:21 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:23 +0200
x86/tracing: Introduce a static key for exception tracing
Switching the IDT just for avoiding tracepoints creates a completely impenetrable macro/inline/ifdef mess.
There is no point in avoiding tracepoints for most of the traps/exceptions. For the more expensive tracepoints, like pagefaults, this can be handled with an explicit static key.
Preparatory patch to remove the tracing IDT.
--- arch/x86/include/asm/trace/common.h | 15 +++++++++++++++ arch/x86/include/asm/trace/exceptions.h | 4 +--- arch/x86/include/asm/trace/irq_vectors.h | 4 +--- arch/x86/kernel/tracepoint.c | 9 ++++++++- 4 files changed, 25 insertions(+), 7 deletions(-)
arch/x86/include/asm/trace/common.h new file +15 -0
@@ -0,0 +1,15 @@ +#ifndef _ASM_TRACE_COMMON_H +#define _ASM_TRACE_COMMON_H + +extern int trace_irq_vector_regfunc (void ); +extern void trace_irq_vector_unregfunc (void ); + +#ifdef CONFIG_TRACING +DECLARE_STATIC_KEY_FALSE (trace_irqvectors_key); +#define trace_irqvectors_enabled () \ + static_branch_unlikely(&trace_irqvectors_key) +#else +static inline bool trace_irqvectors_enabled (void ) {return false; } +#endif + +#endif
arch/x86/include/asm/trace/exceptions.h +1 -3
@@ -5,9 +5,7 @@#define _TRACE_PAGE_FAULT_H#include <linux/tracepoint.h> - -extern int trace_irq_vector_regfunc (void ); -extern void trace_irq_vector_unregfunc (void ); +#include <asm/trace/common.h> DECLARE_EVENT_CLASS(x86_exceptions,
arch/x86/include/asm/trace/irq_vectors.h +1 -3
@@ -5,9 +5,7 @@#define _TRACE_IRQ_VECTORS_H#include <linux/tracepoint.h> - -extern int trace_irq_vector_regfunc (void ); -extern void trace_irq_vector_unregfunc (void ); +#include <asm/trace/common.h> DECLARE_EVENT_CLASS(x86_irq_vector,
arch/x86/kernel/tracepoint.c +8 -1
@@ -4,9 +4,11 @@* Copyright (C) 2013 Seiji Aguchi <[email protected]> * */ +#include <linux/jump_label.h> +#include <linux/atomic.h> +#include <asm/hw_irq.h> #include <asm/desc.h> -#include <linux/atomic.h> atomic_t trace_idt_ctr =ATOMIC_INIT (0 );struct desc_ptr trace_idt_descr = {NR_VECTORS *16 -1 ,
@@ -15,6 +17,7 @@ struct desc_ptr trace_idt_descr = { NR_VECTORS * 16 - 1,/* No need to be aligned, but done to keep all IDTs defined the same way. */ gate_desc trace_idt_table[NR_VECTORS] __page_aligned_bss; +DEFINE_STATIC_KEY_FALSE (trace_irqvectors_key);static int trace_irq_vector_refcount;static DEFINE_MUTEX (irq_vector_mutex);
@@ -36,6 +39,8 @@ static void switch_idt(void *arg)int trace_irq_vector_regfunc (void ) { +static_branch_inc (&trace_irqvectors_key); +mutex_lock (&irq_vector_mutex);if (!trace_irq_vector_refcount) {set_trace_idt_ctr (1 );
@@ -49,6 +54,8 @@ int trace_irq_vector_regfunc(void)void trace_irq_vector_unregfunc (void ) { +static_branch_dec (&trace_irqvectors_key); +mutex_lock (&irq_vector_mutex); trace_irq_vector_refcount--;if (!trace_irq_vector_refcount) {
PATCH v3 7/44 x86/traps: Simplify pagefault tracing logic
In reply to Thomas GleixnerMake use of the new irqvector tracing static key and remove the duplicated trace_do_pagefault() implementation.
If irq vector tracing is disabled, then the overhead of this is a single NOP5, which is a reasonable tradeoff to avoid duplicated code and the unholy macro mess.
--- arch/x86/entry/entry_32.S | 8 ------- arch/x86/entry/entry_64.S | 13 ----------- arch/x86/include/asm/traps.h | 10 -------- arch/x86/kernel/kvm.c | 2 - arch/x86/mm/fault.c | 49 +++++++++++-------------------------------- 5 files changed, 16 insertions(+), 66 deletions(-)
arch/x86/entry/entry_32.S +0 -8
@@ -891,14 +891,6 @@ BUILD_INTERRUPT3(hyperv_callback_vector, #endif /* CONFIG_HYPERV */ -#ifdef CONFIG_TRACING -ENTRY(trace_page_fault) - ASM_CLAC - pushl $trace_do_page_fault - jmp common_exception -END(trace_page_fault) -#endif - ENTRY(page_fault) ASM_CLAC pushl $do_page_fault
arch/x86/entry/entry_64.S +1 -12
@@ -918,17 +918,6 @@ ENTRY(\sym) END(\sym) .endm -#ifdef CONFIG_TRACING -.macro trace_idtentry sym do_sym has_error_code:req -idtentry trace(\sym) trace(\do_sym) has_error_code=\has_error_code -idtentry \sym \do_sym has_error_code=\has_error_code -.endm -#else -.macro trace_idtentry sym do_sym has_error_code:req -idtentry \sym \do_sym has_error_code=\has_error_code -.endm -#endif - idtentry divide_error do_divide_error has_error_code=0 idtentry overflow do_overflow has_error_code=0 idtentry bounds do_bounds has_error_code=0
@@ -1096,7 +1085,7 @@ idtentry xen_stack_segment do_stack_segm #endif idtentry general_protection do_general_protection has_error_code=1 -trace_idtentry page_fault do_page_fault has_error_code=1 +idtentry page_fault do_page_fault has_error_code=1 #ifdef CONFIG_KVM_GUEST idtentry async_page_fault do_async_page_fault has_error_code=1
arch/x86/include/asm/traps.h +1 -9
@@ -39,7 +39,6 @@ asmlinkage void machine_check(void); asmlinkage void simd_coprocessor_error(void);#ifdef CONFIG_TRACING -asmlinkage void trace_page_fault(void);#define trace_stack_segment stack_segment#define trace_divide_error divide_error#define trace_bounds bounds
@@ -54,6 +53,7 @@ asmlinkage void trace_page_fault(void);#define trace_alignment_check alignment_check#define trace_simd_coprocessor_error simd_coprocessor_error#define trace_async_page_fault async_page_fault +#define trace_page_fault page_fault#endif dotraplinkage void do_divide_error(struct pt_regs *, long);
@@ -74,14 +74,6 @@ asmlinkage struct pt_regs *sync_regs(str#endif dotraplinkage void do_general_protection(struct pt_regs *, long); dotraplinkage void do_page_fault(struct pt_regs *, unsigned long); -#ifdef CONFIG_TRACING -dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long); -#else -static inline void trace_do_page_fault (struct pt_regs *regs,unsigned long error) -{ -do_page_fault (regs, error); -} -#endif dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long); dotraplinkage void do_coprocessor_error(struct pt_regs *, long); dotraplinkage void do_alignment_check(struct pt_regs *, long);
arch/x86/kernel/kvm.c +1 -1
@@ -263,7 +263,7 @@ do_async_page_fault(struct pt_regs *regsswitch (kvm_read_and_reset_pf_reason ()) {default : -trace_do_page_fault (regs, error_code); +do_page_fault (regs, error_code);break ;case KVM_PV_REASON_PAGE_NOT_PRESENT :/* page is swapped out by the host. */
arch/x86/mm/fault.c +13 -36
72 lines not on this page · raw message
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/traps: Simplify pagefault tracing logic
x86/traps: Simplify pagefault tracing logic
Commit-ID: 11a7ffb01703c3bbb1e9b968893f4487a1b0b5a8 Gitweb: http://git.kernel.org/tip/11a7ffb01703c3bbb1e9b968893f4487a1b0b5a8 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:22 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:23 +0200
x86/traps: Simplify pagefault tracing logic
Make use of the new irqvector tracing static key and remove the duplicated trace_do_pagefault() implementation.
If irq vector tracing is disabled, then the overhead of this is a single NOP5, which is a reasonable tradeoff to avoid duplicated code and the unholy macro mess.
--- arch/x86/entry/entry_32.S | 8 -------- arch/x86/entry/entry_64.S | 13 +----------- arch/x86/include/asm/traps.h | 10 +-------- arch/x86/kernel/kvm.c | 2 +- arch/x86/mm/fault.c | 49 ++++++++++++-------------------------------- 5 files changed, 16 insertions(+), 66 deletions(-)
arch/x86/entry/entry_32.S +0 -8
@@ -891,14 +891,6 @@ BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR, #endif /* CONFIG_HYPERV */ -#ifdef CONFIG_TRACING -ENTRY(trace_page_fault) - ASM_CLAC - pushl $trace_do_page_fault - jmp common_exception -END(trace_page_fault) -#endif - ENTRY(page_fault) ASM_CLAC pushl $do_page_fault
arch/x86/entry/entry_64.S +1 -12
@@ -918,17 +918,6 @@ ENTRY(\sym) END(\sym) .endm -#ifdef CONFIG_TRACING -.macro trace_idtentry sym do_sym has_error_code:req -idtentry trace(\sym) trace(\do_sym) has_error_code=\has_error_code -idtentry \sym \do_sym has_error_code=\has_error_code -.endm -#else -.macro trace_idtentry sym do_sym has_error_code:req -idtentry \sym \do_sym has_error_code=\has_error_code -.endm -#endif - idtentry divide_error do_divide_error has_error_code=0 idtentry overflow do_overflow has_error_code=0 idtentry bounds do_bounds has_error_code=0
@@ -1096,7 +1085,7 @@ idtentry xen_stack_segment do_stack_segment has_error_code=1 #endif idtentry general_protection do_general_protection has_error_code=1 -trace_idtentry page_fault do_page_fault has_error_code=1 +idtentry page_fault do_page_fault has_error_code=1 #ifdef CONFIG_KVM_GUEST idtentry async_page_fault do_async_page_fault has_error_code=1
arch/x86/include/asm/traps.h +1 -9
@@ -39,7 +39,6 @@ asmlinkage void machine_check(void); asmlinkage void simd_coprocessor_error(void);#ifdef CONFIG_TRACING -asmlinkage void trace_page_fault(void);#define trace_stack_segment stack_segment#define trace_divide_error divide_error#define trace_bounds bounds
@@ -54,6 +53,7 @@ asmlinkage void trace_page_fault(void);#define trace_alignment_check alignment_check#define trace_simd_coprocessor_error simd_coprocessor_error#define trace_async_page_fault async_page_fault +#define trace_page_fault page_fault#endif dotraplinkage void do_divide_error(struct pt_regs *, long);
@@ -74,14 +74,6 @@ asmlinkage struct pt_regs *sync_regs(struct pt_regs *);#endif dotraplinkage void do_general_protection(struct pt_regs *, long); dotraplinkage void do_page_fault(struct pt_regs *, unsigned long); -#ifdef CONFIG_TRACING -dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long); -#else -static inline void trace_do_page_fault (struct pt_regs *regs,unsigned long error) -{ -do_page_fault (regs, error); -} -#endif dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long); dotraplinkage void do_coprocessor_error(struct pt_regs *, long); dotraplinkage void do_alignment_check(struct pt_regs *, long);
arch/x86/kernel/kvm.c +1 -1
@@ -263,7 +263,7 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code)switch (kvm_read_and_reset_pf_reason ()) {default : -trace_do_page_fault (regs, error_code); +do_page_fault (regs, error_code);break ;case KVM_PV_REASON_PAGE_NOT_PRESENT :/* page is swapped out by the host. */
arch/x86/mm/fault.c +13 -36
72 lines not on this page · raw message
PATCH v3 8/44 x86/apic: Remove the duplicated tracing version of local_timer_interrupt
In reply to Thomas GleixnerThe two NOP5 are noise in the rest of the work which is done by the timer interrupt and modern CPUs are pretty good in optimizing nops.
Get rid of the interrupt handler duplication and move the tracepoints into the regular handler.
--- arch/x86/include/asm/hw_irq.h | 2 +- arch/x86/kernel/apic/apic.c | 19 ------------------- 2 files changed, 1 insertion(+), 20 deletions(-)
arch/x86/include/asm/hw_irq.h +1 -1
@@ -48,7 +48,6 @@ extern asmlinkage void call_function_sin#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ -extern void trace_apic_timer_interrupt (void );extern void trace_x86_platform_ipi (void );extern void trace_error_interrupt (void );extern void trace_irq_work_interrupt (void );
@@ -59,6 +58,7 @@ extern void trace_threshold_interrupt(voextern void trace_deferred_error_interrupt (void );extern void trace_call_function_interrupt (void );extern void trace_call_function_single_interrupt (void ); +#define trace_apic_timer_interrupt apic_timer_interrupt#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt#define trace_reboot_interrupt reboot_interrupt#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi
arch/x86/kernel/apic/apic.c +0 -19
@@ -1038,25 +1038,6 @@ static void local_apic_timer_interrupt(v* interrupt lock, which is the WrongThing (tm) to do. */ entering_ack_irq (); -local_apic_timer_interrupt (); -exiting_irq (); - -set_irq_regs (old_regs); -} - -__visible void __irq_entry smp_trace_apic_timer_interrupt(struct pt_regs *regs) -{ -struct pt_regs *old_regs =set_irq_regs (regs); - -/* -* NOTE! We'd better ACK the irq immediately, -* because timer handling can be slow. -* -* update_process_times() expects us to have done irq_enter(). -* Besides, if we don't timer interrupts ignore the global -* interrupt lock, which is the WrongThing (tm) to do. -*/ -entering_ack_irq ();trace_local_timer_entry (LOCAL_TIMER_VECTOR );local_apic_timer_interrupt ();trace_local_timer_exit (LOCAL_TIMER_VECTOR );
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/apic: Remove the duplicated tracing version of local_timer_interrupt()
x86/apic: Remove the duplicated tracing version of local_timer_interrupt()
Commit-ID: 302a98f896bbd2feb1393d98e8b9febeb101db6e Gitweb: http://git.kernel.org/tip/302a98f896bbd2feb1393d98e8b9febeb101db6e Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:23 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:24 +0200
x86/apic: Remove the duplicated tracing version of local_timer_interrupt()
The two NOP5s are noise in the rest of the work which is done by the timer interrupt and modern CPUs are pretty good in optimizing NOPs anyway.
Get rid of the interrupt handler duplication and move the tracepoints into the regular handler.
--- arch/x86/include/asm/hw_irq.h | 2 +- arch/x86/kernel/apic/apic.c | 19 ------------------- 2 files changed, 1 insertion(+), 20 deletions(-)
arch/x86/include/asm/hw_irq.h +1 -1
@@ -48,7 +48,6 @@ extern asmlinkage void call_function_single_interrupt(void);#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ -extern void trace_apic_timer_interrupt (void );extern void trace_x86_platform_ipi (void );extern void trace_error_interrupt (void );extern void trace_irq_work_interrupt (void );
@@ -59,6 +58,7 @@ extern void trace_threshold_interrupt(void);extern void trace_deferred_error_interrupt (void );extern void trace_call_function_interrupt (void );extern void trace_call_function_single_interrupt (void ); +#define trace_apic_timer_interrupt apic_timer_interrupt#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt#define trace_reboot_interrupt reboot_interrupt#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi
arch/x86/kernel/apic/apic.c +0 -19
@@ -1038,25 +1038,6 @@ __visible void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs)* interrupt lock, which is the WrongThing (tm) to do. */ entering_ack_irq (); -local_apic_timer_interrupt (); -exiting_irq (); - -set_irq_regs (old_regs); -} - -__visible void __irq_entry smp_trace_apic_timer_interrupt(struct pt_regs *regs) -{ -struct pt_regs *old_regs =set_irq_regs (regs); - -/* -* NOTE! We'd better ACK the irq immediately, -* because timer handling can be slow. -* -* update_process_times() expects us to have done irq_enter(). -* Besides, if we don't timer interrupts ignore the global -* interrupt lock, which is the WrongThing (tm) to do. -*/ -entering_ack_irq ();trace_local_timer_entry (LOCAL_TIMER_VECTOR );local_apic_timer_interrupt ();trace_local_timer_exit (LOCAL_TIMER_VECTOR );
PATCH v3 9/44 x86/apic: Use this_cpu_ptr in local_timer_interrupt
In reply to Thomas GleixnerAccessing the per cpu data via per_cpu(, smp_processor_id()) is pointless. Use this_cpu_ptr() instead.
--- arch/x86/kernel/apic/apic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/kernel/apic/apic.c +3 -3
@@ -988,8 +988,7 @@ void setup_secondary_APIC_clock(void)*/ static void local_apic_timer_interrupt (void ) { -int cpu =smp_processor_id (); -struct clock_event_device *evt = &per_cpu (lapic_events, cpu); +struct clock_event_device *evt =this_cpu_ptr (&lapic_events);/* * Normally we should not be here till LAPIC has been initialized but
@@ -1003,7 +1002,8 @@ static void local_apic_timer_interrupt(v* spurious. */ if (!evt->event_handler) { -pr_warning ("Spurious LAPIC timer interrupt on cpu %d\n" , cpu); +pr_warning ("Spurious LAPIC timer interrupt on cpu %d\n" , +smp_processor_id ());/* Switch it off */ lapic_timer_shutdown (evt);return ;
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/apic: Use this_cpu_ptr() in local_timer_interrupt()
x86/apic: Use this_cpu_ptr() in local_timer_interrupt()
Commit-ID: 3bec6def39e32609e01a68b43476ee1f1c512eaa Gitweb: http://git.kernel.org/tip/3bec6def39e32609e01a68b43476ee1f1c512eaa Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:24 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:24 +0200
x86/apic: Use this_cpu_ptr() in local_timer_interrupt()
Accessing the per cpu data via per_cpu(, smp_processor_id()) is pointless. Use this_cpu_ptr() instead.
--- arch/x86/kernel/apic/apic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/kernel/apic/apic.c +3 -3
@@ -988,8 +988,7 @@ void setup_secondary_APIC_clock(void)*/ static void local_apic_timer_interrupt (void ) { -int cpu =smp_processor_id (); -struct clock_event_device *evt = &per_cpu (lapic_events, cpu); +struct clock_event_device *evt =this_cpu_ptr (&lapic_events);/* * Normally we should not be here till LAPIC has been initialized but
@@ -1003,7 +1002,8 @@ static void local_apic_timer_interrupt(void)* spurious. */ if (!evt->event_handler) { -pr_warning ("Spurious LAPIC timer interrupt on cpu %d\n" , cpu); +pr_warning ("Spurious LAPIC timer interrupt on cpu %d\n" , +smp_processor_id ());/* Switch it off */ lapic_timer_shutdown (evt);return ;
PATCH v3 10/44 x86/irq: Get rid of duplicated trace_x86_platform_ipi() code
In reply to Thomas GleixnerTwo NOP5 are really a good tradeoff vs. the unholy IDT switching mess, which duplicates code all over the place.
--- arch/x86/include/asm/hw_irq.h | 2 +- arch/x86/kernel/irq.c | 25 +++++-------------------- 2 files changed, 6 insertions(+), 21 deletions(-)
arch/x86/include/asm/hw_irq.h +1 -1
@@ -48,7 +48,6 @@ extern asmlinkage void call_function_sin#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ -extern void trace_x86_platform_ipi (void );extern void trace_error_interrupt (void );extern void trace_irq_work_interrupt (void );extern void trace_spurious_interrupt (void );
@@ -58,6 +57,7 @@ extern void trace_threshold_interrupt(voextern void trace_deferred_error_interrupt (void );extern void trace_call_function_interrupt (void );extern void trace_call_function_single_interrupt (void ); +#define trace_x86_platform_ipi x86_platform_ipi#define trace_apic_timer_interrupt apic_timer_interrupt#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt#define trace_reboot_interrupt reboot_interrupt
arch/x86/kernel/irq.c +5 -20
@@ -262,20 +262,16 @@ u64 arch_irq_stat(void)/* * Handler for X86_PLATFORM_IPI_VECTOR. */ -void __smp_x86_platform_ipi (void ) -{ -inc_irq_stat (x86_platform_ipis); - -if (x86_platform_ipi_callback) -x86_platform_ipi_callback (); -} - __visible void __irq_entry smp_x86_platform_ipi(struct pt_regs *regs) {struct pt_regs *old_regs =set_irq_regs (regs);entering_ack_irq (); -__smp_x86_platform_ipi (); +trace_x86_platform_ipi_entry (X86_PLATFORM_IPI_VECTOR ); +inc_irq_stat (x86_platform_ipis); +if (x86_platform_ipi_callback) +x86_platform_ipi_callback (); +trace_x86_platform_ipi_exit (X86_PLATFORM_IPI_VECTOR );exiting_irq ();set_irq_regs (old_regs); }
@@ -334,17 +330,6 @@ EXPORT_SYMBOL_GPL(kvm_set_posted_intr_wa }#endif -__visible void __irq_entry smp_trace_x86_platform_ipi(struct pt_regs *regs) -{ -struct pt_regs *old_regs =set_irq_regs (regs); - -entering_ack_irq (); -trace_x86_platform_ipi_entry (X86_PLATFORM_IPI_VECTOR ); -__smp_x86_platform_ipi (); -trace_x86_platform_ipi_exit (X86_PLATFORM_IPI_VECTOR ); -exiting_irq (); -set_irq_regs (old_regs); -}#ifdef CONFIG_HOTPLUG_CPU
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/irq: Get rid of duplicated trace_x86_platform_ipi() code
x86/irq: Get rid of duplicated trace_x86_platform_ipi() code
Commit-ID: 8a17116b1fddc1f414cd4dd5e86fa239fcdb5208 Gitweb: http://git.kernel.org/tip/8a17116b1fddc1f414cd4dd5e86fa239fcdb5208 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:25 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:25 +0200
x86/irq: Get rid of duplicated trace_x86_platform_ipi() code
Two NOP5s are really a good tradeoff vs. the unholy IDT switching mess, which duplicates code all over the place.
--- arch/x86/include/asm/hw_irq.h | 2 +- arch/x86/kernel/irq.c | 25 +++++-------------------- 2 files changed, 6 insertions(+), 21 deletions(-)
arch/x86/include/asm/hw_irq.h +1 -1
@@ -48,7 +48,6 @@ extern asmlinkage void call_function_single_interrupt(void);#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ -extern void trace_x86_platform_ipi (void );extern void trace_error_interrupt (void );extern void trace_irq_work_interrupt (void );extern void trace_spurious_interrupt (void );
@@ -58,6 +57,7 @@ extern void trace_threshold_interrupt(void);extern void trace_deferred_error_interrupt (void );extern void trace_call_function_interrupt (void );extern void trace_call_function_single_interrupt (void ); +#define trace_x86_platform_ipi x86_platform_ipi#define trace_apic_timer_interrupt apic_timer_interrupt#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt#define trace_reboot_interrupt reboot_interrupt
arch/x86/kernel/irq.c +5 -20
@@ -262,20 +262,16 @@ __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs)/* * Handler for X86_PLATFORM_IPI_VECTOR. */ -void __smp_x86_platform_ipi (void ) -{ -inc_irq_stat (x86_platform_ipis); - -if (x86_platform_ipi_callback) -x86_platform_ipi_callback (); -} - __visible void __irq_entry smp_x86_platform_ipi(struct pt_regs *regs) {struct pt_regs *old_regs =set_irq_regs (regs);entering_ack_irq (); -__smp_x86_platform_ipi (); +trace_x86_platform_ipi_entry (X86_PLATFORM_IPI_VECTOR ); +inc_irq_stat (x86_platform_ipis); +if (x86_platform_ipi_callback) +x86_platform_ipi_callback (); +trace_x86_platform_ipi_exit (X86_PLATFORM_IPI_VECTOR );exiting_irq ();set_irq_regs (old_regs); }
@@ -334,17 +330,6 @@ __visible void smp_kvm_posted_intr_nested_ipi(struct pt_regs *regs) }#endif -__visible void __irq_entry smp_trace_x86_platform_ipi(struct pt_regs *regs) -{ -struct pt_regs *old_regs =set_irq_regs (regs); - -entering_ack_irq (); -trace_x86_platform_ipi_entry (X86_PLATFORM_IPI_VECTOR ); -__smp_x86_platform_ipi (); -trace_x86_platform_ipi_exit (X86_PLATFORM_IPI_VECTOR ); -exiting_irq (); -set_irq_regs (old_regs); -}#ifdef CONFIG_HOTPLUG_CPU
PATCH v3 11/44 x86/apic: Remove the duplicated tracing versions of interrupts
In reply to Thomas GleixnerThe error and the spurious interrupt are really rare events and not at all so performance sensitive that two NOP5s can not be tolerated when tracing is disabled.
Remove the nonsense.
--- arch/x86/include/asm/hw_irq.h | 4 +-- arch/x86/kernel/apic/apic.c | 43 +++++++++--------------------------------- 2 files changed, 12 insertions(+), 35 deletions(-)
arch/x86/include/asm/hw_irq.h +2 -2
@@ -48,15 +48,15 @@ extern asmlinkage void call_function_sin#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ -extern void trace_error_interrupt (void );extern void trace_irq_work_interrupt (void ); -extern void trace_spurious_interrupt (void );extern void trace_thermal_interrupt (void );extern void trace_reschedule_interrupt (void );extern void trace_threshold_interrupt (void );extern void trace_deferred_error_interrupt (void );extern void trace_call_function_interrupt (void );extern void trace_call_function_single_interrupt (void ); +#define trace_error_interrupt error_interrupt +#define trace_spurious_interrupt spurious_interrupt#define trace_x86_platform_ipi x86_platform_ipi#define trace_apic_timer_interrupt apic_timer_interrupt#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt
arch/x86/kernel/apic/apic.c +10 -33
78 lines not on this page · raw message
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/apic: Remove the duplicated tracing versions of interrupts
x86/apic: Remove the duplicated tracing versions of interrupts
Commit-ID: 61069de7a3252be0b1f567fe9e0b4723f1d2814f Gitweb: http://git.kernel.org/tip/61069de7a3252be0b1f567fe9e0b4723f1d2814f Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:26 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:25 +0200
x86/apic: Remove the duplicated tracing versions of interrupts
The error and the spurious interrupt are really rare events and not at all performance sensitive: two NOP5s can be tolerated when tracing is disabled.
Remove the complication.
--- arch/x86/include/asm/hw_irq.h | 4 ++-- arch/x86/kernel/apic/apic.c | 43 ++++++++++--------------------------------- 2 files changed, 12 insertions(+), 35 deletions(-)
arch/x86/include/asm/hw_irq.h +2 -2
@@ -48,15 +48,15 @@ extern asmlinkage void call_function_single_interrupt(void);#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ -extern void trace_error_interrupt (void );extern void trace_irq_work_interrupt (void ); -extern void trace_spurious_interrupt (void );extern void trace_thermal_interrupt (void );extern void trace_reschedule_interrupt (void );extern void trace_threshold_interrupt (void );extern void trace_deferred_error_interrupt (void );extern void trace_call_function_interrupt (void );extern void trace_call_function_single_interrupt (void ); +#define trace_error_interrupt error_interrupt +#define trace_spurious_interrupt spurious_interrupt#define trace_x86_platform_ipi x86_platform_ipi#define trace_apic_timer_interrupt apic_timer_interrupt#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt
arch/x86/kernel/apic/apic.c +10 -33
78 lines not on this page · raw message
PATCH v3 12/44 x86/irqwork: Get rid of duplicated tracing interrupt code
In reply to Thomas GleixnerTwo NOP5 are a reasonable tradeoff to avoid duplicated code and the requirement to switch the IDT.
--- arch/x86/include/asm/hw_irq.h | 2 +- arch/x86/kernel/irq_work.c | 16 ++-------------- 2 files changed, 3 insertions(+), 15 deletions(-)
arch/x86/include/asm/hw_irq.h +1 -1
@@ -48,13 +48,13 @@ extern asmlinkage void call_function_sin#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ -extern void trace_irq_work_interrupt (void );extern void trace_thermal_interrupt (void );extern void trace_reschedule_interrupt (void );extern void trace_threshold_interrupt (void );extern void trace_deferred_error_interrupt (void );extern void trace_call_function_interrupt (void );extern void trace_call_function_single_interrupt (void ); +#define trace_irq_work_interrupt irq_work_interrupt#define trace_error_interrupt error_interrupt#define trace_spurious_interrupt spurious_interrupt#define trace_x86_platform_ipi x86_platform_ipi
arch/x86/kernel/irq_work.c +2 -14
@@ -11,24 +11,12 @@#include <asm/trace/irq_vectors.h> #include <linux/interrupt.h> -static inline void __smp_irq_work_interrupt (void ) -{ -inc_irq_stat (apic_irq_work_irqs); -irq_work_run (); -} - __visible void __irq_entry smp_irq_work_interrupt(struct pt_regs *regs) {ipi_entering_ack_irq (); -__smp_irq_work_interrupt (); -exiting_irq (); -} - -__visible void __irq_entry smp_trace_irq_work_interrupt(struct pt_regs *regs) -{ -ipi_entering_ack_irq ();trace_irq_work_entry (IRQ_WORK_VECTOR ); -__smp_irq_work_interrupt (); +inc_irq_stat (apic_irq_work_irqs); +irq_work_run ();trace_irq_work_exit (IRQ_WORK_VECTOR );exiting_irq (); }
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/irqwork: Get rid of duplicated tracing interrupt code
x86/irqwork: Get rid of duplicated tracing interrupt code
Commit-ID: daabb8eb9a55af90d0a55d93547a51cc6921389f Gitweb: http://git.kernel.org/tip/daabb8eb9a55af90d0a55d93547a51cc6921389f Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:27 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:26 +0200
x86/irqwork: Get rid of duplicated tracing interrupt code
Two NOP5s are a reasonable tradeoff to avoid duplicated code and the requirement to switch the IDT.
--- arch/x86/include/asm/hw_irq.h | 2 +- arch/x86/kernel/irq_work.c | 16 ++-------------- 2 files changed, 3 insertions(+), 15 deletions(-)
arch/x86/include/asm/hw_irq.h +1 -1
@@ -48,13 +48,13 @@ extern asmlinkage void call_function_single_interrupt(void);#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ -extern void trace_irq_work_interrupt (void );extern void trace_thermal_interrupt (void );extern void trace_reschedule_interrupt (void );extern void trace_threshold_interrupt (void );extern void trace_deferred_error_interrupt (void );extern void trace_call_function_interrupt (void );extern void trace_call_function_single_interrupt (void ); +#define trace_irq_work_interrupt irq_work_interrupt#define trace_error_interrupt error_interrupt#define trace_spurious_interrupt spurious_interrupt#define trace_x86_platform_ipi x86_platform_ipi
arch/x86/kernel/irq_work.c +2 -14
@@ -11,24 +11,12 @@#include <asm/trace/irq_vectors.h> #include <linux/interrupt.h> -static inline void __smp_irq_work_interrupt (void ) -{ -inc_irq_stat (apic_irq_work_irqs); -irq_work_run (); -} - __visible void __irq_entry smp_irq_work_interrupt(struct pt_regs *regs) {ipi_entering_ack_irq (); -__smp_irq_work_interrupt (); -exiting_irq (); -} - -__visible void __irq_entry smp_trace_irq_work_interrupt(struct pt_regs *regs) -{ -ipi_entering_ack_irq ();trace_irq_work_entry (IRQ_WORK_VECTOR ); -__smp_irq_work_interrupt (); +inc_irq_stat (apic_irq_work_irqs); +irq_work_run ();trace_irq_work_exit (IRQ_WORK_VECTOR );exiting_irq (); }
PATCH v3 13/44 x86/mce: Remove duplicated tracing interrupt code
In reply to Thomas GleixnerMachine checks are not really high frequency events. The extra two NOP5 for the disabled tracepoints are noise vs. the heavy lifting which needs to be done in the MCE handler.
--- arch/x86/include/asm/hw_irq.h | 6 +++--- arch/x86/kernel/cpu/mcheck/mce_amd.c | 16 ++-------------- arch/x86/kernel/cpu/mcheck/therm_throt.c | 20 +++----------------- arch/x86/kernel/cpu/mcheck/threshold.c | 16 ++-------------- 4 files changed, 10 insertions(+), 48 deletions(-)
arch/x86/include/asm/hw_irq.h +3 -3
@@ -48,12 +48,12 @@ extern asmlinkage void call_function_sin#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ -extern void trace_thermal_interrupt (void );extern void trace_reschedule_interrupt (void ); -extern void trace_threshold_interrupt (void ); -extern void trace_deferred_error_interrupt (void );extern void trace_call_function_interrupt (void );extern void trace_call_function_single_interrupt (void ); +#define trace_thermal_interrupt thermal_interrupt +#define trace_threshold_interrupt threshold_interrupt +#define trace_deferred_error_interrupt deferred_error_interrupt#define trace_irq_work_interrupt irq_work_interrupt#define trace_error_interrupt error_interrupt#define trace_spurious_interrupt spurious_interrupt
arch/x86/kernel/cpu/mcheck/mce_amd.c +2 -14
@@ -776,24 +776,12 @@ static void __log_error(unsigned int banmce_log (&m); } -static inline void __smp_deferred_error_interrupt (void ) -{ -inc_irq_stat (irq_deferred_error_count); -deferred_error_int_vector (); -} - asmlinkage __visible void __irq_entry smp_deferred_error_interrupt(void) {entering_irq (); -__smp_deferred_error_interrupt (); -exiting_ack_irq (); -} - -asmlinkage __visible void __irq_entry smp_trace_deferred_error_interrupt(void) -{ -entering_irq ();trace_deferred_error_apic_entry (DEFERRED_ERROR_VECTOR ); -__smp_deferred_error_interrupt (); +inc_irq_stat (irq_deferred_error_count); +deferred_error_int_vector ();trace_deferred_error_apic_exit (DEFERRED_ERROR_VECTOR );exiting_ack_irq (); }
arch/x86/kernel/cpu/mcheck/therm_throt.c +3 -17
@@ -390,26 +390,12 @@ static void unexpected_thermal_interruptstatic void (*smp_thermal_vector)(void ) = unexpected_thermal_interrupt; -static inline void __smp_thermal_interrupt (void ) -{ -inc_irq_stat (irq_thermal_count); -smp_thermal_vector (); -} - -asmlinkage __visible void __irq_entry -smp_thermal_interrupt (struct pt_regs *regs) -{ -entering_irq (); -__smp_thermal_interrupt (); -exiting_ack_irq (); -} - -asmlinkage __visible void __irq_entry -smp_trace_thermal_interrupt (struct pt_regs *regs) +asmlinkage __visible void __irq_entry smp_thermal_interrupt(struct pt_regs *r) {entering_irq ();trace_thermal_apic_entry (THERMAL_APIC_VECTOR ); -__smp_thermal_interrupt (); +inc_irq_stat (irq_thermal_count); +smp_thermal_vector ();trace_thermal_apic_exit (THERMAL_APIC_VECTOR );exiting_ack_irq (); }
arch/x86/kernel/cpu/mcheck/threshold.c +2 -14
@@ -17,24 +17,12 @@ static void default_threshold_interrupt(void (*mce_threshold_vector)(void ) = default_threshold_interrupt; -static inline void __smp_threshold_interrupt (void ) -{ -inc_irq_stat (irq_threshold_count); -mce_threshold_vector (); -} - asmlinkage __visible void __irq_entry smp_threshold_interrupt(void) {entering_irq (); -__smp_threshold_interrupt (); -exiting_ack_irq (); -} - -asmlinkage __visible void __irq_entry smp_trace_threshold_interrupt(void) -{ -entering_irq ();trace_threshold_apic_entry (THRESHOLD_APIC_VECTOR ); -__smp_threshold_interrupt (); +inc_irq_stat (irq_threshold_count); +mce_threshold_vector ();trace_threshold_apic_exit (THRESHOLD_APIC_VECTOR );exiting_ack_irq (); }
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/mce: Remove duplicated tracing interrupt code
x86/mce: Remove duplicated tracing interrupt code
Commit-ID: 0f42ae283c9b3ebfa34cac6d86c335aa1ebe8ac1 Gitweb: http://git.kernel.org/tip/0f42ae283c9b3ebfa34cac6d86c335aa1ebe8ac1 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:28 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:26 +0200
x86/mce: Remove duplicated tracing interrupt code
Machine checks are not really high frequency events. The extra two NOP5s for the disabled tracepoints are noise vs. the heavy lifting which needs to be done in the MCE handler.
--- arch/x86/include/asm/hw_irq.h | 6 +++--- arch/x86/kernel/cpu/mcheck/mce_amd.c | 16 ++-------------- arch/x86/kernel/cpu/mcheck/therm_throt.c | 20 +++----------------- arch/x86/kernel/cpu/mcheck/threshold.c | 16 ++-------------- 4 files changed, 10 insertions(+), 48 deletions(-)
arch/x86/include/asm/hw_irq.h +3 -3
@@ -48,12 +48,12 @@ extern asmlinkage void call_function_single_interrupt(void);#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ -extern void trace_thermal_interrupt (void );extern void trace_reschedule_interrupt (void ); -extern void trace_threshold_interrupt (void ); -extern void trace_deferred_error_interrupt (void );extern void trace_call_function_interrupt (void );extern void trace_call_function_single_interrupt (void ); +#define trace_thermal_interrupt thermal_interrupt +#define trace_threshold_interrupt threshold_interrupt +#define trace_deferred_error_interrupt deferred_error_interrupt#define trace_irq_work_interrupt irq_work_interrupt#define trace_error_interrupt error_interrupt#define trace_spurious_interrupt spurious_interrupt
arch/x86/kernel/cpu/mcheck/mce_amd.c +2 -14
@@ -776,24 +776,12 @@ static void __log_error(unsigned int bank, u64 status, u64 addr, u64 misc)mce_log (&m); } -static inline void __smp_deferred_error_interrupt (void ) -{ -inc_irq_stat (irq_deferred_error_count); -deferred_error_int_vector (); -} - asmlinkage __visible void __irq_entry smp_deferred_error_interrupt(void) {entering_irq (); -__smp_deferred_error_interrupt (); -exiting_ack_irq (); -} - -asmlinkage __visible void __irq_entry smp_trace_deferred_error_interrupt(void) -{ -entering_irq ();trace_deferred_error_apic_entry (DEFERRED_ERROR_VECTOR ); -__smp_deferred_error_interrupt (); +inc_irq_stat (irq_deferred_error_count); +deferred_error_int_vector ();trace_deferred_error_apic_exit (DEFERRED_ERROR_VECTOR );exiting_ack_irq (); }
arch/x86/kernel/cpu/mcheck/therm_throt.c +3 -17
@@ -390,26 +390,12 @@ static void unexpected_thermal_interrupt(void)static void (*smp_thermal_vector)(void ) = unexpected_thermal_interrupt; -static inline void __smp_thermal_interrupt (void ) -{ -inc_irq_stat (irq_thermal_count); -smp_thermal_vector (); -} - -asmlinkage __visible void __irq_entry -smp_thermal_interrupt (struct pt_regs *regs) -{ -entering_irq (); -__smp_thermal_interrupt (); -exiting_ack_irq (); -} - -asmlinkage __visible void __irq_entry -smp_trace_thermal_interrupt (struct pt_regs *regs) +asmlinkage __visible void __irq_entry smp_thermal_interrupt(struct pt_regs *r) {entering_irq ();trace_thermal_apic_entry (THERMAL_APIC_VECTOR ); -__smp_thermal_interrupt (); +inc_irq_stat (irq_thermal_count); +smp_thermal_vector ();trace_thermal_apic_exit (THERMAL_APIC_VECTOR );exiting_ack_irq (); }
arch/x86/kernel/cpu/mcheck/threshold.c +2 -14
@@ -17,24 +17,12 @@ static void default_threshold_interrupt(void)void (*mce_threshold_vector)(void ) = default_threshold_interrupt; -static inline void __smp_threshold_interrupt (void ) -{ -inc_irq_stat (irq_threshold_count); -mce_threshold_vector (); -} - asmlinkage __visible void __irq_entry smp_threshold_interrupt(void) {entering_irq (); -__smp_threshold_interrupt (); -exiting_ack_irq (); -} - -asmlinkage __visible void __irq_entry smp_trace_threshold_interrupt(void) -{ -entering_irq ();trace_threshold_apic_entry (THRESHOLD_APIC_VECTOR ); -__smp_threshold_interrupt (); +inc_irq_stat (irq_threshold_count); +mce_threshold_vector ();trace_threshold_apic_exit (THRESHOLD_APIC_VECTOR );exiting_ack_irq (); }
PATCH v3 14/44 x86/smp: Remove pointless duplicated interrupt code
In reply to Thomas GleixnerTwo NOP5 are really a good tradeoff vs. the unholy IDT switching mess, which duplicates code all over the place. The rescheduling interrupt gets optimized in a later step.
Make the ordering of function call and statistics increment the same as in other places. stats first, then function call.
--- arch/x86/include/asm/hw_irq.h | 4 +-- arch/x86/kernel/smp.c | 43 ++++++------------------------------------ 2 files changed, 9 insertions(+), 38 deletions(-)
arch/x86/include/asm/hw_irq.h +2 -2
@@ -49,8 +49,8 @@ extern asmlinkage void call_function_sin#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ extern void trace_reschedule_interrupt (void ); -extern void trace_call_function_interrupt (void ); -extern void trace_call_function_single_interrupt (void ); +#define trace_call_function_interrupt call_function_interrupt +#define trace_call_function_single_interrupt call_function_single_interrupt#define trace_thermal_interrupt thermal_interrupt#define trace_threshold_interrupt threshold_interrupt#define trace_deferred_error_interrupt deferred_error_interrupt
arch/x86/kernel/smp.c +7 -36
64 lines not on this page · raw message
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/smp: Remove pointless duplicated interrupt code
x86/smp: Remove pointless duplicated interrupt code
Commit-ID: 85b77cdd8fbd163d65f340e3f6578c50031af960 Gitweb: http://git.kernel.org/tip/85b77cdd8fbd163d65f340e3f6578c50031af960 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:29 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:27 +0200
x86/smp: Remove pointless duplicated interrupt code
Two NOP5s are really a good tradeoff vs. the unholy IDT switching mess, which duplicates code all over the place. The rescheduling interrupt gets optimized in a later step.
Make the ordering of function call and statistics increment the same as in other places. Calculate stats first, then do the function call.
--- arch/x86/include/asm/hw_irq.h | 4 ++-- arch/x86/kernel/smp.c | 43 +++++++------------------------------------ 2 files changed, 9 insertions(+), 38 deletions(-)
arch/x86/include/asm/hw_irq.h +2 -2
@@ -49,8 +49,8 @@ extern asmlinkage void call_function_single_interrupt(void);#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ extern void trace_reschedule_interrupt (void ); -extern void trace_call_function_interrupt (void ); -extern void trace_call_function_single_interrupt (void ); +#define trace_call_function_interrupt call_function_interrupt +#define trace_call_function_single_interrupt call_function_single_interrupt#define trace_thermal_interrupt thermal_interrupt#define trace_threshold_interrupt threshold_interrupt#define trace_deferred_error_interrupt deferred_error_interrupt
arch/x86/kernel/smp.c +7 -36
64 lines not on this page · raw message
PATCH v3 15/44 x86/smp: Use static key for reschedule interrupt tracing
In reply to Thomas GleixnerIt's worth to avoid the extra irq_enter()/irq_exit() pair in the case that the reschedule interrupt tracepoints are disabled.
Use the static key which indicates that exception tracing is enabled. For now this key is global. It will be optimized in a later step.
--- arch/x86/include/asm/hw_irq.h | 2 +- arch/x86/kernel/smp.c | 40 +++++++++++++++------------------------- 2 files changed, 16 insertions(+), 26 deletions(-)
arch/x86/include/asm/hw_irq.h +1 -1
@@ -48,7 +48,7 @@ extern asmlinkage void call_function_sin#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ -extern void trace_reschedule_interrupt (void ); +#define trace_reschedule_interrupt reschedule_interrupt#define trace_call_function_interrupt call_function_interrupt#define trace_call_function_single_interrupt call_function_single_interrupt#define trace_thermal_interrupt thermal_interrupt
arch/x86/kernel/smp.c +15 -25
@@ -254,37 +254,27 @@ static void native_stop_other_cpus(int w }/* -* Reschedule call back. +* Reschedule call back. KVM uses this interrupt to force a cpu out of +* guest mode */ -static inline void __smp_reschedule_interrupt (void ) -{ -inc_irq_stat (irq_resched_count); -scheduler_ipi (); -} - __visible void __irq_entry smp_reschedule_interrupt(struct pt_regs *regs) {ack_APIC_irq (); -__smp_reschedule_interrupt (); -/* -* KVM uses this interrupt to force a cpu out of guest mode -*/ -} - -__visible void __irq_entry smp_trace_reschedule_interrupt(struct pt_regs *regs) -{ -/* -* Need to call irq_enter() before calling the trace point. -* __smp_reschedule_interrupt() calls irq_enter/exit() too (in -* scheduler_ipi(). This is OK, since those functions are allowed -* to nest. -*/ -ipi_entering_ack_irq (); -trace_reschedule_entry (RESCHEDULE_VECTOR );inc_irq_stat (irq_resched_count); + +if (trace_irqvectors_enabled ()) { +/* +* scheduler_ipi() might call irq_enter() as well, but +* nested calls are fine. +*/ +irq_enter (); +trace_reschedule_entry (RESCHEDULE_VECTOR ); +scheduler_ipi (); +trace_reschedule_exit (RESCHEDULE_VECTOR ); +irq_exit (); +return ; + }scheduler_ipi (); -trace_reschedule_exit (RESCHEDULE_VECTOR ); -exiting_irq (); } __visible void __irq_entry smp_call_function_interrupt(struct pt_regs *regs)
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/smp: Use static key for reschedule interrupt tracing
x86/smp: Use static key for reschedule interrupt tracing
Commit-ID: 3cd788c1eec4b3659671aa13d335a15102ac4d06 Gitweb: http://git.kernel.org/tip/3cd788c1eec4b3659671aa13d335a15102ac4d06 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:30 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:27 +0200
x86/smp: Use static key for reschedule interrupt tracing
It's worth to avoid the extra irq_enter()/irq_exit() pair in the case that the reschedule interrupt tracepoints are disabled.
Use the static key which indicates that exception tracing is enabled. For now this key is global. It will be optimized in a later step.
--- arch/x86/include/asm/hw_irq.h | 2 +- arch/x86/kernel/smp.c | 40 +++++++++++++++------------------------- 2 files changed, 16 insertions(+), 26 deletions(-)
arch/x86/include/asm/hw_irq.h +1 -1
@@ -48,7 +48,7 @@ extern asmlinkage void call_function_single_interrupt(void);#ifdef CONFIG_TRACING /* Interrupt handlers registered during init_IRQ */ -extern void trace_reschedule_interrupt (void ); +#define trace_reschedule_interrupt reschedule_interrupt#define trace_call_function_interrupt call_function_interrupt#define trace_call_function_single_interrupt call_function_single_interrupt#define trace_thermal_interrupt thermal_interrupt
arch/x86/kernel/smp.c +15 -25
@@ -254,37 +254,27 @@ finish: }/* -* Reschedule call back. +* Reschedule call back. KVM uses this interrupt to force a cpu out of +* guest mode */ -static inline void __smp_reschedule_interrupt (void ) -{ -inc_irq_stat (irq_resched_count); -scheduler_ipi (); -} - __visible void __irq_entry smp_reschedule_interrupt(struct pt_regs *regs) {ack_APIC_irq (); -__smp_reschedule_interrupt (); -/* -* KVM uses this interrupt to force a cpu out of guest mode -*/ -} - -__visible void __irq_entry smp_trace_reschedule_interrupt(struct pt_regs *regs) -{ -/* -* Need to call irq_enter() before calling the trace point. -* __smp_reschedule_interrupt() calls irq_enter/exit() too (in -* scheduler_ipi(). This is OK, since those functions are allowed -* to nest. -*/ -ipi_entering_ack_irq (); -trace_reschedule_entry (RESCHEDULE_VECTOR );inc_irq_stat (irq_resched_count); + +if (trace_irqvectors_enabled ()) { +/* +* scheduler_ipi() might call irq_enter() as well, but +* nested calls are fine. +*/ +irq_enter (); +trace_reschedule_entry (RESCHEDULE_VECTOR ); +scheduler_ipi (); +trace_reschedule_exit (RESCHEDULE_VECTOR ); +irq_exit (); +return ; + }scheduler_ipi (); -trace_reschedule_exit (RESCHEDULE_VECTOR ); -exiting_irq (); } __visible void __irq_entry smp_call_function_interrupt(struct pt_regs *regs)
PATCH v3 16/44 x86/idt: Remove tracing idt completely
In reply to Thomas GleixnerNo more users of the tracing idt. All exception tracepoints have been moved into the regular handlers. Get rid of the mess which shouldn't have been created in the first place.
--- arch/x86/entry/entry_32.S | 12 +----- arch/x86/entry/entry_64.S | 13 ------ arch/x86/include/asm/desc.h | 82 +++-------------------------------------- arch/x86/include/asm/hw_irq.h | 20 ---------- arch/x86/include/asm/segment.h | 3 - arch/x86/kernel/tracepoint.c | 43 --------------------- arch/x86/kernel/traps.c | 6 --- 7 files changed, 9 insertions(+), 170 deletions(-)
arch/x86/entry/entry_32.S +2 -10
@@ -673,16 +673,8 @@ ENTRY(name) \ jmp ret_from_intr; \ ENDPROC(name) - -#ifdef CONFIG_TRACING -# define TRACE_BUILD_INTERRUPT(name, nr) BUILD_INTERRUPT3(trace_##name, nr, smp_trace_##name) -#else -# define TRACE_BUILD_INTERRUPT(name, nr) -#endif - #define BUILD_INTERRUPT(name, nr) \ BUILD_INTERRUPT3(name, nr, smp_##name); \ - TRACE_BUILD_INTERRUPT(name, nr) /* The include is where all of the SMP etc. interrupts come from */ #include <asm/entry_arch.h>
@@ -880,14 +872,14 @@ ENTRY(xen_failsafe_callback) ENDPROC(xen_failsafe_callback) BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR, - xen_evtchn_do_upcall) + xen_evtchn_do_upcall) #endif /* CONFIG_XEN */ #if IS_ENABLED(CONFIG_HYPERV) BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR, - hyperv_vector_handler) + hyperv_vector_handler) #endif /* CONFIG_HYPERV */
arch/x86/entry/entry_64.S +0 -13
@@ -748,18 +748,6 @@ ENTRY(\sym) END(\sym) .endm -#ifdef CONFIG_TRACING -#define trace(sym) trace_##sym -#define smp_trace(sym) smp_trace_##sym - -.macro trace_apicinterrupt num sym -apicinterrupt3 \num trace(\sym) smp_trace(\sym) -.endm -#else -.macro trace_apicinterrupt num sym do_sym -.endm -#endif - /* Make sure APIC interrupt handlers end up in the irqentry section: */ #if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_KASAN) # define PUSH_SECTION_IRQENTRY .pushsection .irqentry.text, "ax"
@@ -772,7 +760,6 @@ apicinterrupt3 \num trace(\sym) smp_trac .macro apicinterrupt num sym do_sym PUSH_SECTION_IRQENTRY apicinterrupt3 \num \sym \do_sym -trace_apicinterrupt \num \sym POP_SECTION_IRQENTRY .endm
arch/x86/include/asm/desc.h +6 -76
108 lines not on this page · raw message
arch/x86/include/asm/hw_irq.h +0 -20
@@ -46,26 +46,6 @@ extern asmlinkage void deferred_error_in extern asmlinkage void call_function_interrupt(void); extern asmlinkage void call_function_single_interrupt(void); -#ifdef CONFIG_TRACING -/* Interrupt handlers registered during init_IRQ */ -#define trace_reschedule_interrupt reschedule_interrupt -#define trace_call_function_interrupt call_function_interrupt -#define trace_call_function_single_interrupt call_function_single_interrupt -#define trace_thermal_interrupt thermal_interrupt -#define trace_threshold_interrupt threshold_interrupt -#define trace_deferred_error_interrupt deferred_error_interrupt -#define trace_irq_work_interrupt irq_work_interrupt -#define trace_error_interrupt error_interrupt -#define trace_spurious_interrupt spurious_interrupt -#define trace_x86_platform_ipi x86_platform_ipi -#define trace_apic_timer_interrupt apic_timer_interrupt -#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt -#define trace_reboot_interrupt reboot_interrupt -#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi -#define trace_kvm_posted_intr_wakeup_ipi kvm_posted_intr_wakeup_ipi -#define trace_kvm_posted_intr_nested_ipi kvm_posted_intr_nested_ipi -#endif /* CONFIG_TRACING */ -#ifdef CONFIG_X86_LOCAL_APIC struct irq_data ;struct pci_dev ;
arch/x86/include/asm/segment.h +0 -3
@@ -238,9 +238,6 @@#ifndef __ASSEMBLY__extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS ][EARLY_IDT_HANDLER_SIZE ]; -#ifdef CONFIG_TRACING -# define trace_early_idt_handler_array early_idt_handler_array -#endif /* * Load a segment. Fall back on loading the zero segment if something goes
arch/x86/kernel/tracepoint.c +0 -43
58 lines not on this page · raw message
arch/x86/kernel/traps.c +1 -5
@@ -939,12 +939,8 @@ void __init early_trap_init(void)* stack. Using the original stack works well enough at this * early stage. DEBUG_STACK will be equipped after cpu_init() in * trap_init(). -* -* We don't need to set trace_idt_table like set_intr_gate(), -* since we don't have trace_debug and it will be reset to -* 'debug' in trap_init() by set_intr_gate_ist(). */ -set_intr_gate_notrace (X86_TRAP_DB , debug); +set_intr_gate (X86_TRAP_DB , debug);/* int3 can be called from all */ set_system_intr_gate (X86_TRAP_BP , &int3);#ifdef CONFIG_X86_32
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Remove the tracing IDT completely
x86/idt: Remove the tracing IDT completely
Commit-ID: 4b9a8dca0e58b6fee229795f77e902a4dfd116fe Gitweb: http://git.kernel.org/tip/4b9a8dca0e58b6fee229795f77e902a4dfd116fe Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:31 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:28 +0200
x86/idt: Remove the tracing IDT completely
No more users of the tracing IDT. All exception tracepoints have been moved into the regular handlers. Get rid of the mess which shouldn't have been created in the first place.
--- arch/x86/entry/entry_32.S | 12 ++----- arch/x86/entry/entry_64.S | 13 ------- arch/x86/include/asm/desc.h | 82 ++++-------------------------------------- arch/x86/include/asm/hw_irq.h | 20 ----------- arch/x86/include/asm/segment.h | 3 -- arch/x86/kernel/tracepoint.c | 43 ---------------------- arch/x86/kernel/traps.c | 6 +--- 7 files changed, 9 insertions(+), 170 deletions(-)
arch/x86/entry/entry_32.S +2 -10
@@ -673,16 +673,8 @@ ENTRY(name) \ jmp ret_from_intr; \ ENDPROC(name) - -#ifdef CONFIG_TRACING -# define TRACE_BUILD_INTERRUPT(name, nr) BUILD_INTERRUPT3(trace_##name, nr, smp_trace_##name) -#else -# define TRACE_BUILD_INTERRUPT(name, nr) -#endif - #define BUILD_INTERRUPT(name, nr) \ BUILD_INTERRUPT3(name, nr, smp_##name); \ - TRACE_BUILD_INTERRUPT(name, nr) /* The include is where all of the SMP etc. interrupts come from */ #include <asm/entry_arch.h>
@@ -880,14 +872,14 @@ ENTRY(xen_failsafe_callback) ENDPROC(xen_failsafe_callback) BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR, - xen_evtchn_do_upcall) + xen_evtchn_do_upcall) #endif /* CONFIG_XEN */ #if IS_ENABLED(CONFIG_HYPERV) BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR, - hyperv_vector_handler) + hyperv_vector_handler) #endif /* CONFIG_HYPERV */
arch/x86/entry/entry_64.S +0 -13
@@ -748,18 +748,6 @@ ENTRY(\sym) END(\sym) .endm -#ifdef CONFIG_TRACING -#define trace(sym) trace_##sym -#define smp_trace(sym) smp_trace_##sym - -.macro trace_apicinterrupt num sym -apicinterrupt3 \num trace(\sym) smp_trace(\sym) -.endm -#else -.macro trace_apicinterrupt num sym do_sym -.endm -#endif - /* Make sure APIC interrupt handlers end up in the irqentry section: */ #if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_KASAN) # define PUSH_SECTION_IRQENTRY .pushsection .irqentry.text, "ax"
@@ -772,7 +760,6 @@ apicinterrupt3 \num trace(\sym) smp_trace(\sym) .macro apicinterrupt num sym do_sym PUSH_SECTION_IRQENTRY apicinterrupt3 \num \sym \do_sym -trace_apicinterrupt \num \sym POP_SECTION_IRQENTRY .endm
arch/x86/include/asm/desc.h +6 -76
108 lines not on this page · raw message
arch/x86/include/asm/hw_irq.h +0 -20
@@ -46,26 +46,6 @@ extern asmlinkage void deferred_error_interrupt(void); extern asmlinkage void call_function_interrupt(void); extern asmlinkage void call_function_single_interrupt(void); -#ifdef CONFIG_TRACING -/* Interrupt handlers registered during init_IRQ */ -#define trace_reschedule_interrupt reschedule_interrupt -#define trace_call_function_interrupt call_function_interrupt -#define trace_call_function_single_interrupt call_function_single_interrupt -#define trace_thermal_interrupt thermal_interrupt -#define trace_threshold_interrupt threshold_interrupt -#define trace_deferred_error_interrupt deferred_error_interrupt -#define trace_irq_work_interrupt irq_work_interrupt -#define trace_error_interrupt error_interrupt -#define trace_spurious_interrupt spurious_interrupt -#define trace_x86_platform_ipi x86_platform_ipi -#define trace_apic_timer_interrupt apic_timer_interrupt -#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt -#define trace_reboot_interrupt reboot_interrupt -#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi -#define trace_kvm_posted_intr_wakeup_ipi kvm_posted_intr_wakeup_ipi -#define trace_kvm_posted_intr_nested_ipi kvm_posted_intr_nested_ipi -#endif /* CONFIG_TRACING */ -#ifdef CONFIG_X86_LOCAL_APIC struct irq_data ;struct pci_dev ;
arch/x86/include/asm/segment.h +0 -3
@@ -238,9 +238,6 @@#ifndef __ASSEMBLY__extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS ][EARLY_IDT_HANDLER_SIZE ]; -#ifdef CONFIG_TRACING -# define trace_early_idt_handler_array early_idt_handler_array -#endif /* * Load a segment. Fall back on loading the zero segment if something goes
arch/x86/kernel/tracepoint.c +0 -43
58 lines not on this page · raw message
arch/x86/kernel/traps.c +1 -5
@@ -939,12 +939,8 @@ void __init early_trap_init(void)* stack. Using the original stack works well enough at this * early stage. DEBUG_STACK will be equipped after cpu_init() in * trap_init(). -* -* We don't need to set trace_idt_table like set_intr_gate(), -* since we don't have trace_debug and it will be reset to -* 'debug' in trap_init() by set_intr_gate_ist(). */ -set_intr_gate_notrace (X86_TRAP_DB , debug); +set_intr_gate (X86_TRAP_DB , debug);/* int3 can be called from all */ set_system_intr_gate (X86_TRAP_BP , &int3);#ifdef CONFIG_X86_32
PATCH v3 17/44 x86/idt: Cleanup the i386 low level entry macros
In reply to Thomas GleixnerSome of the entry function defines for i386 were explictely using the BUILD_INTERRUPT3() macro to prevent that the extra trace entry got added via BUILD_INTERRUPT(). No that the trace cruft is gone, the file can be cleaned up and converted to use BUILD_INTERRUPT() which avoids the ugly line breaks.
--- arch/x86/include/asm/entry_arch.h | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
arch/x86/include/asm/entry_arch.h +5 -9
@@ -13,20 +13,16 @@ BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) -BUILD_INTERRUPT3 (irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR , - smp_irq_move_cleanup_interrupt) -BUILD_INTERRUPT3(reboot_interrupt, REBOOT_VECTOR, smp_reboot_interrupt) +BUILD_INTERRUPT(irq_move_cleanup_interrupt, IRQ_MOVE_CLEANUP_VECTOR) +BUILD_INTERRUPT(reboot_interrupt, REBOOT_VECTOR)#endif BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR)#ifdef CONFIG_HAVE_KVM -BUILD_INTERRUPT3 (kvm_posted_intr_ipi,POSTED_INTR_VECTOR , - smp_kvm_posted_intr_ipi) -BUILD_INTERRUPT3 (kvm_posted_intr_wakeup_ipi,POSTED_INTR_WAKEUP_VECTOR , - smp_kvm_posted_intr_wakeup_ipi) -BUILD_INTERRUPT3 (kvm_posted_intr_nested_ipi,POSTED_INTR_NESTED_VECTOR , - smp_kvm_posted_intr_nested_ipi) +BUILD_INTERRUPT(kvm_posted_intr_ipi, POSTED_INTR_VECTOR) +BUILD_INTERRUPT(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR) +BUILD_INTERRUPT(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR)#endif /*
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Clean up the i386 low level entry macros
x86/idt: Clean up the i386 low level entry macros
Commit-ID: 6f54f3ec6c5d866c0517e9cf444bed762c2a05b7 Gitweb: http://git.kernel.org/tip/6f54f3ec6c5d866c0517e9cf444bed762c2a05b7 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:32 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:28 +0200
x86/idt: Clean up the i386 low level entry macros
Some of the entry function defines for i386 were explictely using the BUILD_INTERRUPT3() macro to prevent that the extra trace entry got added via BUILD_INTERRUPT(). No that the trace cruft is gone, the file can be cleaned up and converted to use BUILD_INTERRUPT() which avoids the ugly line breaks.
--- arch/x86/include/asm/entry_arch.h | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
arch/x86/include/asm/entry_arch.h +5 -9
@@ -13,20 +13,16 @@ BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) -BUILD_INTERRUPT3 (irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR , - smp_irq_move_cleanup_interrupt) -BUILD_INTERRUPT3(reboot_interrupt, REBOOT_VECTOR, smp_reboot_interrupt) +BUILD_INTERRUPT(irq_move_cleanup_interrupt, IRQ_MOVE_CLEANUP_VECTOR) +BUILD_INTERRUPT(reboot_interrupt, REBOOT_VECTOR)#endif BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR)#ifdef CONFIG_HAVE_KVM -BUILD_INTERRUPT3 (kvm_posted_intr_ipi,POSTED_INTR_VECTOR , - smp_kvm_posted_intr_ipi) -BUILD_INTERRUPT3 (kvm_posted_intr_wakeup_ipi,POSTED_INTR_WAKEUP_VECTOR , - smp_kvm_posted_intr_wakeup_ipi) -BUILD_INTERRUPT3 (kvm_posted_intr_nested_ipi,POSTED_INTR_NESTED_VECTOR , - smp_kvm_posted_intr_nested_ipi) +BUILD_INTERRUPT(kvm_posted_intr_ipi, POSTED_INTR_VECTOR) +BUILD_INTERRUPT(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR) +BUILD_INTERRUPT(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR)#endif /*
PATCH v3 18/44 x86/tracing: Disentangle pagefault and resched IPI tracing key
In reply to Thomas GleixnerThe pagefault and the resched IPI handler are the only ones where it is worth to optimize the code further in case tracepoints are disabled. But it makes no sense to have a single static key for both.
Seperate the static keys so the facilities are handled seperately.
--- arch/x86/include/asm/trace/common.h | 15 ++++++++------- arch/x86/include/asm/trace/exceptions.h | 6 ++++-- arch/x86/include/asm/trace/irq_vectors.h | 29 +++++++++++++++++++++++------ arch/x86/kernel/smp.c | 2 +- arch/x86/kernel/tracepoint.c | 27 ++++++++++++++++++++++----- arch/x86/mm/fault.c | 2 +- 6 files changed, 59 insertions(+), 22 deletions(-)
arch/x86/include/asm/trace/common.h +8 -7
@@ -1,15 +1,16 @@#ifndef _ASM_TRACE_COMMON_H#define _ASM_TRACE_COMMON_H -extern int trace_irq_vector_regfunc (void ); -extern void trace_irq_vector_unregfunc (void ); -#ifdef CONFIG_TRACING -DECLARE_STATIC_KEY_FALSE (trace_irqvectors_key); -#define trace_irqvectors_enabled () \ - static_branch_unlikely(&trace_irqvectors_key) +DECLARE_STATIC_KEY_FALSE (trace_pagefault_key); +#define trace_pagefault_enabled () \ + static_branch_unlikely(&trace_pagefault_key) +DECLARE_STATIC_KEY_FALSE (trace_resched_ipi_key); +#define trace_resched_ipi_enabled () \ + static_branch_unlikely(&trace_resched_ipi_key)#else -static inline bool trace_irqvectors_enabled (void ) {return false; } +static inline bool trace_pagefault_enabled (void ) {return false; } +static inline bool trace_resched_ipi_enabled (void ) {return false; }#endif #endif
arch/x86/include/asm/trace/exceptions.h +4 -2
@@ -7,6 +7,9 @@#include <linux/tracepoint.h> #include <asm/trace/common.h> +extern int trace_pagefault_reg (void ); +extern void trace_pagefault_unreg (void ); + DECLARE_EVENT_CLASS(x86_exceptions, TP_PROTO(unsigned long address, struct pt_regs *regs,
@@ -35,8 +38,7 @@ DEFINE_EVENT_FN(x86_exceptions, name, TP_PROTO(unsigned long address, struct pt_regs *regs, \ unsigned long error_code), \TP_ARGS (address, regs, error_code), \ - trace_irq_vector_regfunc, \ - trace_irq_vector_unregfunc); + trace_pagefault_reg, trace_pagefault_unreg);DEFINE_PAGE_FAULT_EVENT (page_fault_user);DEFINE_PAGE_FAULT_EVENT (page_fault_kernel);
arch/x86/include/asm/trace/irq_vectors.h +23 -6
@@ -7,6 +7,9 @@#include <linux/tracepoint.h> #include <asm/trace/common.h> +extern int trace_resched_ipi_reg (void ); +extern void trace_resched_ipi_unreg (void ); + DECLARE_EVENT_CLASS(x86_irq_vector, TP_PROTO(int vector),
@@ -26,15 +29,22 @@ DECLARE_EVENT_CLASS(x86_irq_vector,#define DEFINE_IRQ_VECTOR_EVENT (name) \ DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ TP_PROTO(int vector), \ + TP_ARGS(vector), NULL, NULL); \ +DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ + TP_PROTO(int vector), \ + TP_ARGS(vector), NULL, NULL); + +#define DEFINE_RESCHED_IPI_EVENT (name) \ +DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ + TP_PROTO(int vector), \ TP_ARGS(vector), \ - trace_irq_vector_regfunc, \ - trace_irq_vector_unregfunc); \ + trace_resched_ipi_reg, \ + trace_resched_ipi_unreg); \ DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ TP_PROTO(int vector), \ TP_ARGS(vector), \ - trace_irq_vector_regfunc, \ - trace_irq_vector_unregfunc); - + trace_resched_ipi_reg, \ + trace_resched_ipi_unreg);/* * local_timer - called when entering/exiting a local timer interrupt
@@ -43,9 +53,16 @@ DEFINE_EVENT_FN(x86_irq_vector, name##_eDEFINE_IRQ_VECTOR_EVENT (local_timer);/* +* The ifdef is required because that tracepoint macro hell emits tracepoint +* code in files which include this header even if the tracepoint is not +* enabled. Brilliant stuff that. +*/ +#ifdef CONFIG_SMP +/* * reschedule - called when entering/exiting a reschedule vector handler */ -DEFINE_IRQ_VECTOR_EVENT (reschedule); +DEFINE_RESCHED_IPI_EVENT (reschedule); +#endif /* * spurious_apic - called when entering/exiting a spurious apic vector handler
arch/x86/kernel/smp.c +1 -1
@@ -262,7 +262,7 @@ static void native_stop_other_cpus(int wack_APIC_irq ();inc_irq_stat (irq_resched_count); -if (trace_irqvectors_enabled ()) { +if (trace_resched_ipi_enabled ()) {/* * scheduler_ipi() might call irq_enter() as well, but * nested calls are fine.
arch/x86/kernel/tracepoint.c +22 -5
@@ -10,15 +10,32 @@#include <asm/hw_irq.h> #include <asm/desc.h> -DEFINE_STATIC_KEY_FALSE (trace_irqvectors_key); +DEFINE_STATIC_KEY_FALSE (trace_pagefault_key); -int trace_irq_vector_regfunc (void ) +int trace_pagefault_reg (void ) { -static_branch_inc (&trace_irqvectors_key); +static_branch_inc (&trace_pagefault_key);return 0 ; } -void trace_irq_vector_unregfunc (void ) +void trace_pagefault_unreg (void ) { -static_branch_dec (&trace_irqvectors_key); +static_branch_dec (&trace_pagefault_key); } + +#ifdef CONFIG_SMP + +DEFINE_STATIC_KEY_FALSE (trace_resched_ipi_key); + +int trace_resched_ipi_reg (void ) +{ +static_branch_inc (&trace_resched_ipi_key); +return 0 ; +} + +void trace_resched_ipi_unreg (void ) +{ +static_branch_dec (&trace_resched_ipi_key); +} + +#endif
arch/x86/mm/fault.c +1 -1
@@ -1510,7 +1510,7 @@ do_page_fault(struct pt_regs *regs, unsienum ctx_state prev_state; prev_state =exception_enter (); -if (trace_irqvectors_enabled ()) +if (trace_pagefault_enabled ())trace_page_fault_entries (address, regs, error_code);__do_page_fault (regs, error_code, address);
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/tracing: Disentangle pagefault and resched IPI tracing key
x86/tracing: Disentangle pagefault and resched IPI tracing key
Commit-ID: 809547472edae0bc68f2b5abc37b92c8a988bc8a Gitweb: http://git.kernel.org/tip/809547472edae0bc68f2b5abc37b92c8a988bc8a Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:33 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:29 +0200
x86/tracing: Disentangle pagefault and resched IPI tracing key
The pagefault and the resched IPI handler are the only ones where it is worth to optimize the code further in case tracepoints are disabled. But it makes no sense to have a single static key for both.
Seperate the static keys so the facilities are handled seperately.
--- arch/x86/include/asm/trace/common.h | 15 ++++++++------- arch/x86/include/asm/trace/exceptions.h | 6 ++++-- arch/x86/include/asm/trace/irq_vectors.h | 29 +++++++++++++++++++++++------ arch/x86/kernel/smp.c | 2 +- arch/x86/kernel/tracepoint.c | 27 ++++++++++++++++++++++----- arch/x86/mm/fault.c | 2 +- 6 files changed, 59 insertions(+), 22 deletions(-)
arch/x86/include/asm/trace/common.h +8 -7
@@ -1,15 +1,16 @@#ifndef _ASM_TRACE_COMMON_H#define _ASM_TRACE_COMMON_H -extern int trace_irq_vector_regfunc (void ); -extern void trace_irq_vector_unregfunc (void ); -#ifdef CONFIG_TRACING -DECLARE_STATIC_KEY_FALSE (trace_irqvectors_key); -#define trace_irqvectors_enabled () \ - static_branch_unlikely(&trace_irqvectors_key) +DECLARE_STATIC_KEY_FALSE (trace_pagefault_key); +#define trace_pagefault_enabled () \ + static_branch_unlikely(&trace_pagefault_key) +DECLARE_STATIC_KEY_FALSE (trace_resched_ipi_key); +#define trace_resched_ipi_enabled () \ + static_branch_unlikely(&trace_resched_ipi_key)#else -static inline bool trace_irqvectors_enabled (void ) {return false; } +static inline bool trace_pagefault_enabled (void ) {return false; } +static inline bool trace_resched_ipi_enabled (void ) {return false; }#endif #endif
arch/x86/include/asm/trace/exceptions.h +4 -2
@@ -7,6 +7,9 @@#include <linux/tracepoint.h> #include <asm/trace/common.h> +extern int trace_pagefault_reg (void ); +extern void trace_pagefault_unreg (void ); + DECLARE_EVENT_CLASS(x86_exceptions, TP_PROTO(unsigned long address, struct pt_regs *regs,
@@ -35,8 +38,7 @@ DEFINE_EVENT_FN(x86_exceptions, name, \ TP_PROTO(unsigned long address, struct pt_regs *regs, \ unsigned long error_code), \TP_ARGS (address, regs, error_code), \ - trace_irq_vector_regfunc, \ - trace_irq_vector_unregfunc); + trace_pagefault_reg, trace_pagefault_unreg);DEFINE_PAGE_FAULT_EVENT (page_fault_user);DEFINE_PAGE_FAULT_EVENT (page_fault_kernel);
arch/x86/include/asm/trace/irq_vectors.h +23 -6
@@ -7,6 +7,9 @@#include <linux/tracepoint.h> #include <asm/trace/common.h> +extern int trace_resched_ipi_reg (void ); +extern void trace_resched_ipi_unreg (void ); + DECLARE_EVENT_CLASS(x86_irq_vector, TP_PROTO(int vector),
@@ -26,15 +29,22 @@ DECLARE_EVENT_CLASS(x86_irq_vector,#define DEFINE_IRQ_VECTOR_EVENT (name) \ DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ TP_PROTO(int vector), \ + TP_ARGS(vector), NULL, NULL); \ +DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ + TP_PROTO(int vector), \ + TP_ARGS(vector), NULL, NULL); + +#define DEFINE_RESCHED_IPI_EVENT (name) \ +DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ + TP_PROTO(int vector), \ TP_ARGS(vector), \ - trace_irq_vector_regfunc, \ - trace_irq_vector_unregfunc); \ + trace_resched_ipi_reg, \ + trace_resched_ipi_unreg); \ DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ TP_PROTO(int vector), \ TP_ARGS(vector), \ - trace_irq_vector_regfunc, \ - trace_irq_vector_unregfunc); - + trace_resched_ipi_reg, \ + trace_resched_ipi_unreg);/* * local_timer - called when entering/exiting a local timer interrupt
@@ -43,9 +53,16 @@ DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \DEFINE_IRQ_VECTOR_EVENT (local_timer);/* +* The ifdef is required because that tracepoint macro hell emits tracepoint +* code in files which include this header even if the tracepoint is not +* enabled. Brilliant stuff that. +*/ +#ifdef CONFIG_SMP +/* * reschedule - called when entering/exiting a reschedule vector handler */ -DEFINE_IRQ_VECTOR_EVENT (reschedule); +DEFINE_RESCHED_IPI_EVENT (reschedule); +#endif /* * spurious_apic - called when entering/exiting a spurious apic vector handler
arch/x86/kernel/smp.c +1 -1
@@ -262,7 +262,7 @@ __visible void __irq_entry smp_reschedule_interrupt(struct pt_regs *regs)ack_APIC_irq ();inc_irq_stat (irq_resched_count); -if (trace_irqvectors_enabled ()) { +if (trace_resched_ipi_enabled ()) {/* * scheduler_ipi() might call irq_enter() as well, but * nested calls are fine.
arch/x86/kernel/tracepoint.c +22 -5
@@ -10,15 +10,32 @@#include <asm/hw_irq.h> #include <asm/desc.h> -DEFINE_STATIC_KEY_FALSE (trace_irqvectors_key); +DEFINE_STATIC_KEY_FALSE (trace_pagefault_key); -int trace_irq_vector_regfunc (void ) +int trace_pagefault_reg (void ) { -static_branch_inc (&trace_irqvectors_key); +static_branch_inc (&trace_pagefault_key);return 0 ; } -void trace_irq_vector_unregfunc (void ) +void trace_pagefault_unreg (void ) { -static_branch_dec (&trace_irqvectors_key); +static_branch_dec (&trace_pagefault_key); } + +#ifdef CONFIG_SMP + +DEFINE_STATIC_KEY_FALSE (trace_resched_ipi_key); + +int trace_resched_ipi_reg (void ) +{ +static_branch_inc (&trace_resched_ipi_key); +return 0 ; +} + +void trace_resched_ipi_unreg (void ) +{ +static_branch_dec (&trace_resched_ipi_key); +} + +#endif
arch/x86/mm/fault.c +1 -1
@@ -1510,7 +1510,7 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)enum ctx_state prev_state; prev_state =exception_enter (); -if (trace_irqvectors_enabled ()) +if (trace_pagefault_enabled ())trace_page_fault_entries (address, regs, error_code);__do_page_fault (regs, error_code, address);
PATCH v3 19/44 x86/ipi: Make platform IPI depend on APIC
In reply to Thomas GleixnerThe platform IPI vector is only installed when the local APIC is enabled. All users of it depend on the local APIC anyway.
Make the related code conditional on CONFIG_X86_LOCAL_APIC.
--- arch/x86/include/asm/entry_arch.h | 3 +-- arch/x86/kernel/irq.c | 11 ++++++----- 2 files changed, 7 insertions(+), 7 deletions(-)
arch/x86/include/asm/entry_arch.h +1 -2
@@ -17,8 +17,6 @@ BUILD_INTERRUPT(irq_move_cleanup_interru BUILD_INTERRUPT(reboot_interrupt, REBOOT_VECTOR)#endif -BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) -#ifdef CONFIG_HAVE_KVM BUILD_INTERRUPT(kvm_posted_intr_ipi, POSTED_INTR_VECTOR)BUILD_INTERRUPT (kvm_posted_intr_wakeup_ipi,POSTED_INTR_WAKEUP_VECTOR )
@@ -37,6 +35,7 @@ BUILD_INTERRUPT(kvm_posted_intr_nested_i BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) +BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR)#ifdef CONFIG_IRQ_WORK BUILD_INTERRUPT (irq_work_interrupt,IRQ_WORK_VECTOR )
arch/x86/kernel/irq.c +6 -5
@@ -29,9 +29,6 @@ EXPORT_PER_CPU_SYMBOL(irq_regs);atomic_t irq_err_count; -/* Function pointer for generic interrupt vector handling */ -void (*x86_platform_ipi_callback)(void ) =NULL ; -/* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves.
@@ -87,13 +84,13 @@ int arch_show_interrupts(struct seq_filefor_each_online_cpu (j)seq_printf (p,"%10u " ,irq_stats (j)->icr_read_retry_count);seq_puts (p," APIC ICR read retries\n" ); -#endif if (x86_platform_ipi_callback) {seq_printf (p,"%*s: " , prec,"PLT" );for_each_online_cpu (j)seq_printf (p,"%10u " ,irq_stats (j)->x86_platform_ipis);seq_puts (p," Platform interrupts\n" ); } +#endif #ifdef CONFIG_SMP seq_printf (p,"%*s: " , prec,"RES" );for_each_online_cpu (j)
@@ -183,9 +180,9 @@ u64 arch_irq_stat_cpu(unsigned int cpu) sum +=irq_stats (cpu)->apic_perf_irqs; sum +=irq_stats (cpu)->apic_irq_work_irqs; sum +=irq_stats (cpu)->icr_read_retry_count; -#endif if (x86_platform_ipi_callback) sum +=irq_stats (cpu)->x86_platform_ipis; +#endif #ifdef CONFIG_SMP sum +=irq_stats (cpu)->irq_resched_count; sum +=irq_stats (cpu)->irq_call_count;
@@ -259,6 +256,9 @@ u64 arch_irq_stat(void)return 1 ; } +#ifdef CONFIG_X86_LOCAL_APIC +/* Function pointer for generic interrupt vector handling */ +void (*x86_platform_ipi_callback)(void ) =NULL ;/* * Handler for X86_PLATFORM_IPI_VECTOR. */
@@ -275,6 +275,7 @@ u64 arch_irq_stat(void)exiting_irq (); set_irq_regs(old_regs); } +#endif #ifdef CONFIG_HAVE_KVM static void dummy_handler (void ) {}
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/ipi: Make platform IPI depend on APIC
x86/ipi: Make platform IPI depend on APIC
Commit-ID: 0428e01a2f13a6b7dae8289fb10030dbea336dee Gitweb: http://git.kernel.org/tip/0428e01a2f13a6b7dae8289fb10030dbea336dee Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:34 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:29 +0200
x86/ipi: Make platform IPI depend on APIC
The platform IPI vector is only installed when the local APIC is enabled. All users of it depend on the local APIC anyway.
Make the related code conditional on CONFIG_X86_LOCAL_APIC=y.
--- arch/x86/include/asm/entry_arch.h | 3 +-- arch/x86/kernel/irq.c | 11 ++++++----- 2 files changed, 7 insertions(+), 7 deletions(-)
arch/x86/include/asm/entry_arch.h +1 -2
@@ -17,8 +17,6 @@ BUILD_INTERRUPT(irq_move_cleanup_interrupt, IRQ_MOVE_CLEANUP_VECTOR) BUILD_INTERRUPT(reboot_interrupt, REBOOT_VECTOR)#endif -BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) -#ifdef CONFIG_HAVE_KVM BUILD_INTERRUPT(kvm_posted_intr_ipi, POSTED_INTR_VECTOR)BUILD_INTERRUPT (kvm_posted_intr_wakeup_ipi,POSTED_INTR_WAKEUP_VECTOR )
@@ -37,6 +35,7 @@ BUILD_INTERRUPT(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR) BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) +BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR)#ifdef CONFIG_IRQ_WORK BUILD_INTERRUPT (irq_work_interrupt,IRQ_WORK_VECTOR )
arch/x86/kernel/irq.c +6 -5
@@ -29,9 +29,6 @@ EXPORT_PER_CPU_SYMBOL(irq_regs);atomic_t irq_err_count; -/* Function pointer for generic interrupt vector handling */ -void (*x86_platform_ipi_callback)(void ) =NULL ; -/* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves.
@@ -87,13 +84,13 @@ int arch_show_interrupts(struct seq_file *p, int prec)for_each_online_cpu (j)seq_printf (p,"%10u " ,irq_stats (j)->icr_read_retry_count);seq_puts (p," APIC ICR read retries\n" ); -#endif if (x86_platform_ipi_callback) {seq_printf (p,"%*s: " , prec,"PLT" );for_each_online_cpu (j)seq_printf (p,"%10u " ,irq_stats (j)->x86_platform_ipis);seq_puts (p," Platform interrupts\n" ); } +#endif #ifdef CONFIG_SMP seq_printf (p,"%*s: " , prec,"RES" );for_each_online_cpu (j)
@@ -183,9 +180,9 @@ u64 arch_irq_stat_cpu(unsigned int cpu) sum +=irq_stats (cpu)->apic_perf_irqs; sum +=irq_stats (cpu)->apic_irq_work_irqs; sum +=irq_stats (cpu)->icr_read_retry_count; -#endif if (x86_platform_ipi_callback) sum +=irq_stats (cpu)->x86_platform_ipis; +#endif #ifdef CONFIG_SMP sum +=irq_stats (cpu)->irq_resched_count; sum +=irq_stats (cpu)->irq_call_count;
@@ -259,6 +256,9 @@ __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs)return 1 ; } +#ifdef CONFIG_X86_LOCAL_APIC +/* Function pointer for generic interrupt vector handling */ +void (*x86_platform_ipi_callback)(void ) =NULL ;/* * Handler for X86_PLATFORM_IPI_VECTOR. */
@@ -275,6 +275,7 @@ __visible void __irq_entry smp_x86_platform_ipi(struct pt_regs *regs)exiting_irq (); set_irq_regs(old_regs); } +#endif #ifdef CONFIG_HAVE_KVM static void dummy_handler (void ) {}
PATCH v3 20/44 x86/irq_work: Make it depend on APIC
In reply to Thomas GleixnerThe irq work interrupt vector is only installed when CONFIG_X86_LOCAL_APIC is enabled, but the interrupt handler is compiled in unconditionally.
Compile the cruft out when the APIC is disabled.
--- arch/x86/include/asm/irq_work.h | 8 ++++++++ arch/x86/kernel/irq_work.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-)
arch/x86/include/asm/irq_work.h +8 -0
@@ -3,9 +3,17 @@#include <asm/cpufeature.h> +#ifdef CONFIG_X86_LOCAL_APIC static inline bool arch_irq_work_has_interrupt (void ) {return boot_cpu_has (X86_FEATURE_APIC ); } +extern void arch_irq_work_raise (void ); +#else +static inline bool arch_irq_work_has_interrupt (void ) +{ +return false; +} +#endif #endif /* _ASM_IRQ_WORK_H */
arch/x86/kernel/irq_work.c +2 -2
@@ -11,6 +11,7 @@#include <asm/trace/irq_vectors.h> #include <linux/interrupt.h> +#ifdef CONFIG_X86_LOCAL_APIC __visible void __irq_entry smp_irq_work_interrupt(struct pt_regs *regs) {ipi_entering_ack_irq ();
@@ -23,11 +24,10 @@void arch_irq_work_raise (void ) { -#ifdef CONFIG_X86_LOCAL_APIC if (!arch_irq_work_has_interrupt ())return ; apic->send_IPI_self (IRQ_WORK_VECTOR );apic_wait_icr_idle (); -#endif } +#endif
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/irq_work: Make it depend on APIC
x86/irq_work: Make it depend on APIC
Commit-ID: a45525b5b47c10c0446eda21227792b39af233dc Gitweb: http://git.kernel.org/tip/a45525b5b47c10c0446eda21227792b39af233dc Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:35 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 11:42:30 +0200
x86/irq_work: Make it depend on APIC
The irq work interrupt vector is only installed when CONFIG_X86_LOCAL_APIC is enabled, but the interrupt handler is compiled in unconditionally.
Compile the cruft out when the APIC is disabled.
--- arch/x86/include/asm/irq_work.h | 8 ++++++++ arch/x86/kernel/irq_work.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-)
arch/x86/include/asm/irq_work.h +8 -0
@@ -3,9 +3,17 @@#include <asm/cpufeature.h> +#ifdef CONFIG_X86_LOCAL_APIC static inline bool arch_irq_work_has_interrupt (void ) {return boot_cpu_has (X86_FEATURE_APIC ); } +extern void arch_irq_work_raise (void ); +#else +static inline bool arch_irq_work_has_interrupt (void ) +{ +return false; +} +#endif #endif /* _ASM_IRQ_WORK_H */
arch/x86/kernel/irq_work.c +2 -2
@@ -11,6 +11,7 @@#include <asm/trace/irq_vectors.h> #include <linux/interrupt.h> +#ifdef CONFIG_X86_LOCAL_APIC __visible void __irq_entry smp_irq_work_interrupt(struct pt_regs *regs) {ipi_entering_ack_irq ();
@@ -23,11 +24,10 @@ __visible void __irq_entry smp_irq_work_interrupt(struct pt_regs *regs)void arch_irq_work_raise (void ) { -#ifdef CONFIG_X86_LOCAL_APIC if (!arch_irq_work_has_interrupt ())return ; apic->send_IPI_self (IRQ_WORK_VECTOR );apic_wait_icr_idle (); -#endif } +#endif
PATCH v3 21/44 x86/tracing: Build tracepoints only when they are used
In reply to Thomas GleixnerThe tracepoint macro magic emits code for all tracepoints in a event header file. That code stays around even if the tracepoint is not used at all. The linker does not discard it.
Build the various irq_vector tracepoints dependent on the appropriate CONFIG switches.
--- arch/x86/include/asm/trace/irq_vectors.h | 36 ++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 12 deletions(-)
arch/x86/include/asm/trace/irq_vectors.h +24 -12
@@ -7,6 +7,8 @@#include <linux/tracepoint.h> #include <asm/trace/common.h> +#ifdef CONFIG_X86_LOCAL_APIC +extern int trace_resched_ipi_reg (void );extern void trace_resched_ipi_unreg (void );
@@ -53,18 +55,6 @@ DEFINE_EVENT_FN(x86_irq_vector, name##_eDEFINE_IRQ_VECTOR_EVENT (local_timer);/* -* The ifdef is required because that tracepoint macro hell emits tracepoint -* code in files which include this header even if the tracepoint is not -* enabled. Brilliant stuff that. -*/ -#ifdef CONFIG_SMP -/* -* reschedule - called when entering/exiting a reschedule vector handler -*/ -DEFINE_RESCHED_IPI_EVENT (reschedule); -#endif - -/* * spurious_apic - called when entering/exiting a spurious apic vector handler */ DEFINE_IRQ_VECTOR_EVENT (spurious_apic);
@@ -80,6 +70,7 @@ DEFINE_IRQ_VECTOR_EVENT(error_apic);*/ DEFINE_IRQ_VECTOR_EVENT (x86_platform_ipi); +#ifdef CONFIG_IRQ_WORK /* * irq_work - called when entering/exiting a irq work interrupt * vector handler
@@ -96,6 +87,18 @@ DEFINE_IRQ_VECTOR_EVENT(irq_work);* 4) goto 1 */ TRACE_EVENT_PERF_PERM (irq_work_exit,is_sampling_event (p_event) ? -EPERM :0 ); +#endif + +/* +* The ifdef is required because that tracepoint macro hell emits tracepoint +* code in files which include this header even if the tracepoint is not +* enabled. Brilliant stuff that. +*/ +#ifdef CONFIG_SMP +/* +* reschedule - called when entering/exiting a reschedule vector handler +*/ +DEFINE_RESCHED_IPI_EVENT (reschedule);/* * call_function - called when entering/exiting a call function interrupt
@@ -108,24 +111,33 @@ DEFINE_IRQ_VECTOR_EVENT(call_function);* single interrupt vector handler */ DEFINE_IRQ_VECTOR_EVENT (call_function_single); +#endif +#ifdef CONFIG_X86_MCE_THRESHOLD /* * threshold_apic - called when entering/exiting a threshold apic interrupt * vector handler */ DEFINE_IRQ_VECTOR_EVENT (threshold_apic); +#endif +#ifdef CONFIG_X86_MCE_AMD /* * deferred_error_apic - called when entering/exiting a deferred apic interrupt * vector handler */ DEFINE_IRQ_VECTOR_EVENT (deferred_error_apic); +#endif +#ifdef CONFIG_X86_THERMAL_VECTOR /* * thermal_apic - called when entering/exiting a thermal apic interrupt * vector handler */ DEFINE_IRQ_VECTOR_EVENT (thermal_apic); +#endif + +#endif /* CONFIG_X86_LOCAL_APIC */ #undef TRACE_INCLUDE_PATH#define TRACE_INCLUDE_PATH .
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/tracing: Build tracepoints only when they are used
x86/tracing: Build tracepoints only when they are used
Commit-ID: 73285527804402befe5d5140aeede21c16544b4c Gitweb: http://git.kernel.org/tip/73285527804402befe5d5140aeede21c16544b4c Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:36 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:24 +0200
x86/tracing: Build tracepoints only when they are used
The tracepoint macro magic emits code for all tracepoints in a event header file. That code stays around even if the tracepoint is not used at all. The linker does not discard it.
Build the various irq_vector tracepoints dependent on the appropriate CONFIG switches.
--- arch/x86/include/asm/trace/irq_vectors.h | 36 +++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 12 deletions(-)
arch/x86/include/asm/trace/irq_vectors.h +24 -12
@@ -7,6 +7,8 @@#include <linux/tracepoint.h> #include <asm/trace/common.h> +#ifdef CONFIG_X86_LOCAL_APIC +extern int trace_resched_ipi_reg (void );extern void trace_resched_ipi_unreg (void );
@@ -53,18 +55,6 @@ DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \DEFINE_IRQ_VECTOR_EVENT (local_timer);/* -* The ifdef is required because that tracepoint macro hell emits tracepoint -* code in files which include this header even if the tracepoint is not -* enabled. Brilliant stuff that. -*/ -#ifdef CONFIG_SMP -/* -* reschedule - called when entering/exiting a reschedule vector handler -*/ -DEFINE_RESCHED_IPI_EVENT (reschedule); -#endif - -/* * spurious_apic - called when entering/exiting a spurious apic vector handler */ DEFINE_IRQ_VECTOR_EVENT (spurious_apic);
@@ -80,6 +70,7 @@ DEFINE_IRQ_VECTOR_EVENT(error_apic);*/ DEFINE_IRQ_VECTOR_EVENT (x86_platform_ipi); +#ifdef CONFIG_IRQ_WORK /* * irq_work - called when entering/exiting a irq work interrupt * vector handler
@@ -96,6 +87,18 @@ DEFINE_IRQ_VECTOR_EVENT(irq_work);* 4) goto 1 */ TRACE_EVENT_PERF_PERM (irq_work_exit,is_sampling_event (p_event) ? -EPERM :0 ); +#endif + +/* +* The ifdef is required because that tracepoint macro hell emits tracepoint +* code in files which include this header even if the tracepoint is not +* enabled. Brilliant stuff that. +*/ +#ifdef CONFIG_SMP +/* +* reschedule - called when entering/exiting a reschedule vector handler +*/ +DEFINE_RESCHED_IPI_EVENT (reschedule);/* * call_function - called when entering/exiting a call function interrupt
@@ -108,24 +111,33 @@ DEFINE_IRQ_VECTOR_EVENT(call_function);* single interrupt vector handler */ DEFINE_IRQ_VECTOR_EVENT (call_function_single); +#endif +#ifdef CONFIG_X86_MCE_THRESHOLD /* * threshold_apic - called when entering/exiting a threshold apic interrupt * vector handler */ DEFINE_IRQ_VECTOR_EVENT (threshold_apic); +#endif +#ifdef CONFIG_X86_MCE_AMD /* * deferred_error_apic - called when entering/exiting a deferred apic interrupt * vector handler */ DEFINE_IRQ_VECTOR_EVENT (deferred_error_apic); +#endif +#ifdef CONFIG_X86_THERMAL_VECTOR /* * thermal_apic - called when entering/exiting a thermal apic interrupt * vector handler */ DEFINE_IRQ_VECTOR_EVENT (thermal_apic); +#endif + +#endif /* CONFIG_X86_LOCAL_APIC */ #undef TRACE_INCLUDE_PATH#define TRACE_INCLUDE_PATH .
PATCH v3 22/44 x86/idt: Unify gate_struct handling for 32/64bit
In reply to Thomas GleixnerThe first 32bits of gate struct are the same for 32 and 64 bit. The 32bit version uses desc_struct and no designated data structure, so we need different accessors for 32 and 64 bit. Aside of that the macros which are necessary to build the 32bit gate descriptor are horrible to read.
Unify the gate structs and switch all code fiddling with it over.
--- arch/x86/boot/compressed/eboot.c | 8 ++--- arch/x86/include/asm/desc.h | 45 +++++++++++++----------------- arch/x86/include/asm/desc_defs.h | 57 +++++++++++++++++++++++++-------------- arch/x86/kvm/vmx.c | 2 - arch/x86/xen/enlighten_pv.c | 12 ++++---- 5 files changed, 67 insertions(+), 57 deletions(-)
arch/x86/boot/compressed/eboot.c +4 -4
@@ -1058,7 +1058,7 @@ struct boot_params *efi_main(struct efi_ desc->s =DESC_TYPE_CODE_DATA ; desc->dpl =0 ; desc->p =1 ; - desc->limit =0xf ; + desc->limit1 =0xf ; desc->avl =0 ; desc->l =0 ; desc->d =SEG_OP_SIZE_32BIT ;
@@ -1078,7 +1078,7 @@ struct boot_params *efi_main(struct efi_ desc->s =DESC_TYPE_CODE_DATA ; desc->dpl =0 ; desc->p =1 ; - desc->limit =0xf ; + desc->limit1 =0xf ; desc->avl =0 ;if (IS_ENABLED (CONFIG_X86_64 )) { desc->l =1 ;
@@ -1099,7 +1099,7 @@ struct boot_params *efi_main(struct efi_ desc->s =DESC_TYPE_CODE_DATA ; desc->dpl =0 ; desc->p =1 ; - desc->limit =0xf ; + desc->limit1 =0xf ; desc->avl =0 ; desc->l =0 ; desc->d =SEG_OP_SIZE_32BIT ;
@@ -1116,7 +1116,7 @@ struct boot_params *efi_main(struct efi_ desc->s =0 ; desc->dpl =0 ; desc->p =1 ; - desc->limit =0x0 ; + desc->limit1 =0x0 ; desc->avl =0 ; desc->l =0 ; desc->d =0 ;
arch/x86/include/asm/desc.h +19 -26
72 lines not on this page · raw message
arch/x86/include/asm/desc_defs.h +37 -20
77 lines not on this page · raw message
arch/x86/kvm/vmx.c +1 -1
@@ -8786,7 +8786,7 @@ static void vmx_handle_external_intr(str vector = exit_intr_info &INTR_INFO_VECTOR_MASK ; desc = (gate_desc *)vmx->host_idt_base + vector; - entry =gate_offset (*desc); + entry =gate_offset (desc); asmvolatile ( #ifdef CONFIG_X86_64 "mov %%" _ASM_SP ", %[sp]\n\t"
arch/x86/xen/enlighten_pv.c +6 -6
@@ -584,12 +584,12 @@ static int cvt_gate_to_trap(int vector, {unsigned long addr; -if (val->type !=GATE_TRAP && val->type !=GATE_INTERRUPT ) +if (val->bits.type !=GATE_TRAP && val->bits.type !=GATE_INTERRUPT )return 0 ; info->vector = vector; - addr =gate_offset (*val); + addr =gate_offset (val);#ifdef CONFIG_X86_64 /* * Look for known traps using IST, and substitute them
@@ -622,16 +622,16 @@ static int cvt_gate_to_trap(int vector, ; else {/* Some other trap using IST? */ -if (WARN_ON (val->ist !=0 )) +if (WARN_ON (val->bits.ist !=0 ))return 0 ; }#endif /* CONFIG_X86_64 */ info->address = addr; - info->cs =gate_segment (*val); - info->flags = val->dpl; + info->cs =gate_segment (val); + info->flags = val->bits.dpl;/* interrupt gates clear IF */ -if (val->type ==GATE_INTERRUPT ) +if (val->bits.type ==GATE_INTERRUPT ) info->flags |=1 <<2 ;return 1 ;
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Unify gate_struct handling for 32/64-bit kernels
x86/idt: Unify gate_struct handling for 32/64-bit kernels
Commit-ID: 64b163fab684e3de47aa8db6cc08ae7d2e194373 Gitweb: http://git.kernel.org/tip/64b163fab684e3de47aa8db6cc08ae7d2e194373 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:37 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:24 +0200
x86/idt: Unify gate_struct handling for 32/64-bit kernels
The first 32 bits of gate struct are the same for 32 and 64 bit kernels.
The 32-bit version uses desc_struct and no designated data structure, so we need different accessors for 32 and 64 bit kernels.
Aside of that the macros which are necessary to build the 32-bit gate descriptor are horrible to read.
Unify the gate structs and switch all code fiddling with it over.
--- arch/x86/boot/compressed/eboot.c | 8 +++--- arch/x86/include/asm/desc.h | 45 ++++++++++++++----------------- arch/x86/include/asm/desc_defs.h | 57 ++++++++++++++++++++++++++-------------- arch/x86/kvm/vmx.c | 2 +- arch/x86/xen/enlighten_pv.c | 12 ++++----- 5 files changed, 67 insertions(+), 57 deletions(-)
arch/x86/boot/compressed/eboot.c +4 -4
@@ -1058,7 +1058,7 @@ struct boot_params *efi_main(struct efi_config *c, desc->s =DESC_TYPE_CODE_DATA ; desc->dpl =0 ; desc->p =1 ; - desc->limit =0xf ; + desc->limit1 =0xf ; desc->avl =0 ; desc->l =0 ; desc->d =SEG_OP_SIZE_32BIT ;
@@ -1078,7 +1078,7 @@ struct boot_params *efi_main(struct efi_config *c, desc->s =DESC_TYPE_CODE_DATA ; desc->dpl =0 ; desc->p =1 ; - desc->limit =0xf ; + desc->limit1 =0xf ; desc->avl =0 ;if (IS_ENABLED (CONFIG_X86_64 )) { desc->l =1 ;
@@ -1099,7 +1099,7 @@ struct boot_params *efi_main(struct efi_config *c, desc->s =DESC_TYPE_CODE_DATA ; desc->dpl =0 ; desc->p =1 ; - desc->limit =0xf ; + desc->limit1 =0xf ; desc->avl =0 ; desc->l =0 ; desc->d =SEG_OP_SIZE_32BIT ;
@@ -1116,7 +1116,7 @@ struct boot_params *efi_main(struct efi_config *c, desc->s =0 ; desc->dpl =0 ; desc->p =1 ; - desc->limit =0x0 ; + desc->limit1 =0x0 ; desc->avl =0 ; desc->l =0 ; desc->d =0 ;
arch/x86/include/asm/desc.h +19 -26
72 lines not on this page · raw message
arch/x86/include/asm/desc_defs.h +37 -20
77 lines not on this page · raw message
arch/x86/kvm/vmx.c +1 -1
@@ -8779,7 +8779,7 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu) vector = exit_intr_info &INTR_INFO_VECTOR_MASK ; desc = (gate_desc *)vmx->host_idt_base + vector; - entry =gate_offset (*desc); + entry =gate_offset (desc); asmvolatile ( #ifdef CONFIG_X86_64 "mov %%" _ASM_SP ", %[sp]\n\t"
arch/x86/xen/enlighten_pv.c +6 -6
@@ -584,12 +584,12 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val, {unsigned long addr; -if (val->type !=GATE_TRAP && val->type !=GATE_INTERRUPT ) +if (val->bits.type !=GATE_TRAP && val->bits.type !=GATE_INTERRUPT )return 0 ; info->vector = vector; - addr =gate_offset (*val); + addr =gate_offset (val);#ifdef CONFIG_X86_64 /* * Look for known traps using IST, and substitute them
@@ -622,16 +622,16 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val, ; else {/* Some other trap using IST? */ -if (WARN_ON (val->ist !=0 )) +if (WARN_ON (val->bits.ist !=0 ))return 0 ; }#endif /* CONFIG_X86_64 */ info->address = addr; - info->cs =gate_segment (*val); - info->flags = val->dpl; + info->cs =gate_segment (val); + info->flags = val->bits.dpl;/* interrupt gates clear IF */ -if (val->type ==GATE_INTERRUPT ) +if (val->bits.type ==GATE_INTERRUPT ) info->flags |=1 <<2 ;return 1 ;
PATCH v3 23/44 x86/percpu: Use static initializer for GDT entry
In reply to Thomas GleixnerThe IDT cleanup is about to remove pack_descriptor(). The GDT setup for the percpu storage can be achieved with the static initializer as well. Replace it.
--- arch/x86/kernel/setup_percpu.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
arch/x86/kernel/setup_percpu.c +3 -6
@@ -155,13 +155,10 @@ static void __init pcpup_populate_pte(unstatic inline void setup_percpu_segment (int cpu) {#ifdef CONFIG_X86_32 -struct desc_struct gdt; +struct desc_struct d =GDT_ENTRY_INIT (0x8092 ,per_cpu_offset (cpu), +0xFFFFF ); -pack_descriptor (&gdt,per_cpu_offset (cpu),0xFFFFF , -0x2 |DESCTYPE_S ,0x8 ); - gdt.s =1 ; -write_gdt_entry (get_cpu_gdt_rw (cpu), -GDT_ENTRY_PERCPU , &gdt,DESCTYPE_S ); +write_gdt_entry (get_cpu_gdt_rw (cpu),GDT_ENTRY_PERCPU , &d,DESCTYPE_S );#endif }
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/percpu: Use static initializer for GDT entry
x86/percpu: Use static initializer for GDT entry
Commit-ID: 1dd439fe97e1a32cbb980c180f1bcb54bb6a2a55 Gitweb: http://git.kernel.org/tip/1dd439fe97e1a32cbb980c180f1bcb54bb6a2a55 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:38 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:24 +0200
x86/percpu: Use static initializer for GDT entry
The IDT cleanup is about to remove pack_descriptor(). The GDT setup for the per-cpu storage can be achieved with the static initializer as well. Replace it.
--- arch/x86/kernel/setup_percpu.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
arch/x86/kernel/setup_percpu.c +3 -6
@@ -155,13 +155,10 @@ static void __init pcpup_populate_pte(unsigned long addr)static inline void setup_percpu_segment (int cpu) {#ifdef CONFIG_X86_32 -struct desc_struct gdt; +struct desc_struct d =GDT_ENTRY_INIT (0x8092 ,per_cpu_offset (cpu), +0xFFFFF ); -pack_descriptor (&gdt,per_cpu_offset (cpu),0xFFFFF , -0x2 |DESCTYPE_S ,0x8 ); - gdt.s =1 ; -write_gdt_entry (get_cpu_gdt_rw (cpu), -GDT_ENTRY_PERCPU , &gdt,DESCTYPE_S ); +write_gdt_entry (get_cpu_gdt_rw (cpu),GDT_ENTRY_PERCPU , &d,DESCTYPE_S );#endif }
PATCH v3 24/44 x86/fpu: Use bitfield accessors for desc_struct
In reply to Thomas Gleixnerdesc_struct is a union of u32 fields and bitfields. The access to the u32 fields is done with magic macros.
Convert it to use the bitfields and replace the macro magic with parseable inline functions.
--- arch/x86/math-emu/fpu_entry.c | 11 ++++----- arch/x86/math-emu/fpu_system.h | 48 ++++++++++++++++++++++++++++++---------- arch/x86/math-emu/get_address.c | 17 +++++++------- 3 files changed, 51 insertions(+), 25 deletions(-)
arch/x86/math-emu/fpu_entry.c +5 -6
@@ -147,7 +147,7 @@ void math_emulate(struct math_emu_info * } code_descriptor =FPU_get_ldt_descriptor (FPU_CS ); -if (SEG_D_SIZE (code_descriptor)) { +if (code_descriptor.d) {/* The above test may be wrong, the book is not clear */ /* Segmented 32 bit protected mode */ addr_modes.default_mode =SEG32 ;
@@ -155,11 +155,10 @@ void math_emulate(struct math_emu_info */* 16 bit protected mode */ addr_modes.default_mode =PM16 ; } -FPU_EIP += code_base =SEG_BASE_ADDR (code_descriptor); - code_limit = code_base - + (SEG_LIMIT (code_descriptor) + -1 ) *SEG_GRANULARITY (code_descriptor) - -1 ; +FPU_EIP += code_base =seg_get_base (&code_descriptor); + code_limit =seg_get_limit (&code_descriptor) +1 ; + code_limit *=seg_get_granularity (&code_descriptor); + code_limit += code_base -1 ;if (code_limit < code_base) code_limit =0xffffffff ; }
arch/x86/math-emu/fpu_system.h +37 -11
54 lines not on this page · raw message
arch/x86/math-emu/get_address.c +9 -8
@@ -159,17 +159,18 @@ static long pm_address(u_char FPU_modrm, } descriptor =FPU_get_ldt_descriptor (addr->selector); - base_address =SEG_BASE_ADDR (descriptor); + base_address =seg_get_base (&descriptor); address = base_address + offset; - limit = base_address - + (SEG_LIMIT (descriptor) +1 ) *SEG_GRANULARITY (descriptor) -1 ; + limit =seg_get_limit (&descriptor) +1 ; + limit *=seg_get_granularity (&descriptor); + limit += base_address -1 ;if (limit < base_address) limit =0xffffffff ; -if (SEG_EXPAND_DOWN (descriptor)) { -if (SEG_G_BIT (descriptor)) +if (seg_expands_down (&descriptor)) { +if (descriptor.g) { seg_top =0xffffffff ; -else { + }else { seg_top = base_address + (1 <<20 );if (seg_top < base_address) seg_top =0xffffffff ;
@@ -182,8 +183,8 @@ static long pm_address(u_char FPU_modrm, (address > limit) || (address < base_address) ?0 : ((limit - address) >=254 ?255 : limit - address +1 ); } -if (SEG_EXECUTE_ONLY (descriptor) || - (!SEG_WRITE_PERM (descriptor) && (FPU_modrm &FPU_WRITE_BIT ))) { +if (seg_execute_only (&descriptor) || + (!seg_writable (&descriptor) && (FPU_modrm &FPU_WRITE_BIT ))) { access_limit =0 ; }return address;
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/fpu: Use bitfield accessors for desc_struct
x86/fpu: Use bitfield accessors for desc_struct
Commit-ID: 718f5d0030da8669404dab873336b16c169b430b Gitweb: http://git.kernel.org/tip/718f5d0030da8669404dab873336b16c169b430b Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:39 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:25 +0200
x86/fpu: Use bitfield accessors for desc_struct
desc_struct is a union of u32 fields and bitfields. The access to the u32 fields is done with magic macros.
Convert it to use the bitfields and replace the macro magic with parseable inline functions.
--- arch/x86/math-emu/fpu_entry.c | 11 +++++----- arch/x86/math-emu/fpu_system.h | 48 +++++++++++++++++++++++++++++++---------- arch/x86/math-emu/get_address.c | 17 ++++++++------- 3 files changed, 51 insertions(+), 25 deletions(-)
arch/x86/math-emu/fpu_entry.c +5 -6
@@ -147,7 +147,7 @@ void math_emulate(struct math_emu_info *info) } code_descriptor =FPU_get_ldt_descriptor (FPU_CS ); -if (SEG_D_SIZE (code_descriptor)) { +if (code_descriptor.d) {/* The above test may be wrong, the book is not clear */ /* Segmented 32 bit protected mode */ addr_modes.default_mode =SEG32 ;
@@ -155,11 +155,10 @@ void math_emulate(struct math_emu_info *info)/* 16 bit protected mode */ addr_modes.default_mode =PM16 ; } -FPU_EIP += code_base =SEG_BASE_ADDR (code_descriptor); - code_limit = code_base - + (SEG_LIMIT (code_descriptor) + -1 ) *SEG_GRANULARITY (code_descriptor) - -1 ; +FPU_EIP += code_base =seg_get_base (&code_descriptor); + code_limit =seg_get_limit (&code_descriptor) +1 ; + code_limit *=seg_get_granularity (&code_descriptor); + code_limit += code_base -1 ;if (code_limit < code_base) code_limit =0xffffffff ; }
arch/x86/math-emu/fpu_system.h +37 -11
54 lines not on this page · raw message
arch/x86/math-emu/get_address.c +9 -8
@@ -159,17 +159,18 @@ static long pm_address(u_char FPU_modrm, u_char segment, } descriptor =FPU_get_ldt_descriptor (addr->selector); - base_address =SEG_BASE_ADDR (descriptor); + base_address =seg_get_base (&descriptor); address = base_address + offset; - limit = base_address - + (SEG_LIMIT (descriptor) +1 ) *SEG_GRANULARITY (descriptor) -1 ; + limit =seg_get_limit (&descriptor) +1 ; + limit *=seg_get_granularity (&descriptor); + limit += base_address -1 ;if (limit < base_address) limit =0xffffffff ; -if (SEG_EXPAND_DOWN (descriptor)) { -if (SEG_G_BIT (descriptor)) +if (seg_expands_down (&descriptor)) { +if (descriptor.g) { seg_top =0xffffffff ; -else { + }else { seg_top = base_address + (1 <<20 );if (seg_top < base_address) seg_top =0xffffffff ;
@@ -182,8 +183,8 @@ static long pm_address(u_char FPU_modrm, u_char segment, (address > limit) || (address < base_address) ?0 : ((limit - address) >=254 ?255 : limit - address +1 ); } -if (SEG_EXECUTE_ONLY (descriptor) || - (!SEG_WRITE_PERM (descriptor) && (FPU_modrm &FPU_WRITE_BIT ))) { +if (seg_execute_only (&descriptor) || + (!seg_writable (&descriptor) && (FPU_modrm &FPU_WRITE_BIT ))) { access_limit =0 ; }return address;
PATCH v3 25/44 x86: Replace access to desc_struct:a/b fields
In reply to Thomas GleixnerThe union inside of desc_struct which allows access to the raw u32 parts of the descriptors. This raw access part is about to go away.
Replace the few code parts which access those fields.
--- arch/x86/include/asm/xen/hypercall.h | 6 ++++-- arch/x86/kernel/tls.c | 2 +- arch/x86/xen/enlighten_pv.c | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-)
arch/x86/include/asm/xen/hypercall.h +4 -2
@@ -552,6 +552,8 @@ static inline void MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr, struct desc_struct desc) { + u32 *p = (u32 *) &desc; + mcl->op = __HYPERVISOR_update_descriptor;if (sizeof (maddr) ==sizeof (long )) { mcl->args[0 ] = maddr;
@@ -559,8 +561,8 @@ MULTI_update_descriptor(struct multicall }else { mcl->args[0 ] = maddr; mcl->args[1 ] = maddr >>32 ; - mcl->args[2 ] = desc.a; - mcl->args[3 ] = desc.b; + mcl->args[2 ] = *p++; + mcl->args[3 ] = *p; }trace_xen_mc_entry (mcl,sizeof (maddr) ==sizeof (long ) ?2 :4 );
arch/x86/kernel/tls.c +1 -1
@@ -93,7 +93,7 @@ static void set_tls_desc(struct task_strwhile (n-- >0 ) {if (LDT_empty (info) ||LDT_zero (info)) { - desc->a = desc->b =0 ; +memset (desc,0 ,sizeof (*desc)); }else {fill_ldt (desc, info);
arch/x86/xen/enlighten_pv.c +1 -1
@@ -494,7 +494,7 @@ static void __init xen_load_gdt_boot(constatic inline bool desc_equal (const struct desc_struct *d1,const struct desc_struct *d2) { -return d1->a == d2->a && d1->b == d2->b; +return !memcmp (d1, d2,sizeof (*d1)); } static void load_TLS_descriptor(struct thread_struct *t,
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/asm: Replace access to desc_struct:a/b fields
x86/asm: Replace access to desc_struct:a/b fields
Commit-ID: 9a98e7780022aa7cd201eb8a88a4f1d607b73cde Gitweb: http://git.kernel.org/tip/9a98e7780022aa7cd201eb8a88a4f1d607b73cde Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:40 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:25 +0200
x86/asm: Replace access to desc_struct:a/b fields
The union inside of desc_struct which allows access to the raw u32 parts of the descriptors. This raw access part is about to go away.
Replace the few code parts which access those fields.
--- arch/x86/include/asm/xen/hypercall.h | 6 ++++-- arch/x86/kernel/tls.c | 2 +- arch/x86/xen/enlighten_pv.c | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-)
arch/x86/include/asm/xen/hypercall.h +4 -2
@@ -552,6 +552,8 @@ static inline void MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr, struct desc_struct desc) { + u32 *p = (u32 *) &desc; + mcl->op = __HYPERVISOR_update_descriptor;if (sizeof (maddr) ==sizeof (long )) { mcl->args[0 ] = maddr;
@@ -559,8 +561,8 @@ MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr, }else { mcl->args[0 ] = maddr; mcl->args[1 ] = maddr >>32 ; - mcl->args[2 ] = desc.a; - mcl->args[3 ] = desc.b; + mcl->args[2 ] = *p++; + mcl->args[3 ] = *p; }trace_xen_mc_entry (mcl,sizeof (maddr) ==sizeof (long ) ?2 :4 );
arch/x86/kernel/tls.c +1 -1
@@ -93,7 +93,7 @@ static void set_tls_desc(struct task_struct *p, int idx,while (n-- >0 ) {if (LDT_empty (info) ||LDT_zero (info)) { - desc->a = desc->b =0 ; +memset (desc,0 ,sizeof (*desc)); }else {fill_ldt (desc, info);
arch/x86/xen/enlighten_pv.c +1 -1
@@ -494,7 +494,7 @@ static void __init xen_load_gdt_boot(const struct desc_ptr *dtr)static inline bool desc_equal (const struct desc_struct *d1,const struct desc_struct *d2) { -return d1->a == d2->a && d1->b == d2->b; +return !memcmp (d1, d2,sizeof (*d1)); } static void load_TLS_descriptor(struct thread_struct *t,
PATCH v3 26/44 x86/gdt: Use bitfields for initialization
In reply to Thomas GleixnerThe GDT entry related code uses partially bitfields and macros which initialize the two 16 bit parts of the entry by magic shift and mask operations.
Clean it up and use the bitfields to initialize and access entries.
--- arch/x86/entry/vdso/vma.c | 2 - arch/x86/include/asm/desc.h | 26 ++++++++++++++--------- arch/x86/include/asm/desc_defs.h | 44 +++++++++++++++++---------------------- arch/x86/math-emu/fpu_system.h | 2 - 4 files changed, 38 insertions(+), 36 deletions(-)
arch/x86/entry/vdso/vma.c +1 -1
@@ -351,7 +351,7 @@ static void vgetcpu_cpu_init(void *arg)* and 8 bits for the node) */ d.limit0 = cpu | ((node &0xf ) <<12 ); - d.limit = node >>4 ; + d.limit1 = node >>4 ; d.type =5 ;/* RO data, expand down, accessed */ d.dpl =3 ;/* Visible to user code */ d.s =1 ;/* Not a system segment */
arch/x86/include/asm/desc.h +16 -10
@@ -23,7 +23,7 @@ static inline void fill_ldt(struct desc_ desc->s =1 ; desc->dpl =0x3 ; desc->p = info->seg_not_present ^1 ; - desc->limit = (info->limit &0xf0000 ) >>16 ; + desc->limit1 = (info->limit &0xf0000 ) >>16 ; desc->avl = info->useable; desc->d = info->seg_32bit; desc->g = info->limit_in_pages;
@@ -170,14 +170,20 @@ static inline void pack_descriptor(struc unsigned long limit, unsigned char type, unsigned char flags) { - desc->a = ((base & 0xffff) << 16) | (limit & 0xffff); - desc->b = (base &0xff000000 ) | ((base &0xff0000 ) >>16 ) | - (limit &0x000f0000 ) | ((type &0xff ) <<8 ) | - ((flags &0xf ) <<20 ); - desc->p =1 ; + desc->limit0 = (u16) limit; + desc->base0 = (u16 ) base; + desc->base1 = (base >>16 ) &0xFF ; + desc->type = type &0x0F ; + desc->s =0 ; + desc->dpl =0 ; + desc->p =1 ; + desc->limit1 = (limit >>16 ) &0xF ; + desc->avl = (flags >>0 ) &0x01 ; + desc->l = (flags >>1 ) &0x01 ; + desc->d = (flags >>2 ) &0x01 ; + desc->g = (flags >>3 ) &0x01 ; } -static inline void set_tssldt_descriptor (void *d,unsigned long addr,unsigned type,unsigned size) {
@@ -195,7 +201,7 @@ static inline void set_tssldt_descriptor desc->base2 = (addr >>24 ) &0xFF ; desc->base3 = (u32) (addr >>32 );#else -pack_descriptor ((struct desc_struct *)d, addr, size,0x80 | type,0 ); +pack_descriptor ((struct desc_struct *)d, addr, size, type,0 );#endif }
@@ -395,13 +401,13 @@ static inline void set_desc_base(structstatic inline unsigned long get_desc_limit (const struct desc_struct *desc) { -return desc->limit0 | (desc->limit <<16 ); +return desc->limit0 | (desc->limit1 <<16 ); }static inline void set_desc_limit (struct desc_struct *desc,unsigned long limit) { desc->limit0 = limit &0xffff ; - desc->limit = (limit >>16 ) &0xf ; + desc->limit1 = (limit >>16 ) &0xf ; }#ifdef CONFIG_X86_64
arch/x86/include/asm/desc_defs.h +20 -24
54 lines not on this page · raw message
arch/x86/math-emu/fpu_system.h +1 -1
@@ -49,7 +49,7 @@ static inline unsigned long seg_get_basestatic inline unsigned long seg_get_limit (struct desc_struct *d) { -return ((unsigned long )d->limit <<16 ) | d->limit0; +return ((unsigned long )d->limit1 <<16 ) | d->limit0; }static inline unsigned long seg_get_granularity (struct desc_struct *d)
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/gdt: Use bitfields for initialization
x86/gdt: Use bitfields for initialization
Commit-ID: 38e9e81f4c81c75799b002d5811de7241b307676 Gitweb: http://git.kernel.org/tip/38e9e81f4c81c75799b002d5811de7241b307676 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:41 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:25 +0200
x86/gdt: Use bitfields for initialization
The GDT entry related code uses two ways to access entries via union fields:
- bitfields
- macros which initialize the two 16-bit parts of the entry by magic shift and mask operations.
Clean it up and only use the bitfields to initialize and access entries.
( The old access patterns were partly done due to GCC optimizing bitfield
accesses in a horrible way - that's mostly fixed these days and clarity of code in such low level accessors is very important. )
--- arch/x86/entry/vdso/vma.c | 2 +- arch/x86/include/asm/desc.h | 26 +++++++++++++++--------- arch/x86/include/asm/desc_defs.h | 44 ++++++++++++++++++---------------------- arch/x86/math-emu/fpu_system.h | 2 +- 4 files changed, 38 insertions(+), 36 deletions(-)
arch/x86/entry/vdso/vma.c +1 -1
@@ -351,7 +351,7 @@ static void vgetcpu_cpu_init(void *arg)* and 8 bits for the node) */ d.limit0 = cpu | ((node &0xf ) <<12 ); - d.limit = node >>4 ; + d.limit1 = node >>4 ; d.type =5 ;/* RO data, expand down, accessed */ d.dpl =3 ;/* Visible to user code */ d.s =1 ;/* Not a system segment */
arch/x86/include/asm/desc.h +16 -10
@@ -23,7 +23,7 @@ static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *in desc->s =1 ; desc->dpl =0x3 ; desc->p = info->seg_not_present ^1 ; - desc->limit = (info->limit &0xf0000 ) >>16 ; + desc->limit1 = (info->limit &0xf0000 ) >>16 ; desc->avl = info->useable; desc->d = info->seg_32bit; desc->g = info->limit_in_pages;
@@ -170,14 +170,20 @@ static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, unsigned long limit, unsigned char type, unsigned char flags) { - desc->a = ((base & 0xffff) << 16) | (limit & 0xffff); - desc->b = (base &0xff000000 ) | ((base &0xff0000 ) >>16 ) | - (limit &0x000f0000 ) | ((type &0xff ) <<8 ) | - ((flags &0xf ) <<20 ); - desc->p =1 ; + desc->limit0 = (u16) limit; + desc->base0 = (u16 ) base; + desc->base1 = (base >>16 ) &0xFF ; + desc->type = type &0x0F ; + desc->s =0 ; + desc->dpl =0 ; + desc->p =1 ; + desc->limit1 = (limit >>16 ) &0xF ; + desc->avl = (flags >>0 ) &0x01 ; + desc->l = (flags >>1 ) &0x01 ; + desc->d = (flags >>2 ) &0x01 ; + desc->g = (flags >>3 ) &0x01 ; } -static inline void set_tssldt_descriptor (void *d,unsigned long addr,unsigned type,unsigned size) {
@@ -195,7 +201,7 @@ static inline void set_tssldt_descriptor(void *d, unsigned long addr, desc->base2 = (addr >>24 ) &0xFF ; desc->base3 = (u32) (addr >>32 );#else -pack_descriptor ((struct desc_struct *)d, addr, size,0x80 | type,0 ); +pack_descriptor ((struct desc_struct *)d, addr, size, type,0 );#endif }
@@ -395,13 +401,13 @@ static inline void set_desc_base(struct desc_struct *desc, unsigned long base)static inline unsigned long get_desc_limit (const struct desc_struct *desc) { -return desc->limit0 | (desc->limit <<16 ); +return desc->limit0 | (desc->limit1 <<16 ); }static inline void set_desc_limit (struct desc_struct *desc,unsigned long limit) { desc->limit0 = limit &0xffff ; - desc->limit = (limit >>16 ) &0xf ; + desc->limit1 = (limit >>16 ) &0xf ; }#ifdef CONFIG_X86_64
arch/x86/include/asm/desc_defs.h +20 -24
54 lines not on this page · raw message
arch/x86/math-emu/fpu_system.h +1 -1
@@ -49,7 +49,7 @@ static inline unsigned long seg_get_base(struct desc_struct *d)static inline unsigned long seg_get_limit (struct desc_struct *d) { -return ((unsigned long )d->limit <<16 ) | d->limit0; +return ((unsigned long )d->limit1 <<16 ) | d->limit0; }static inline unsigned long seg_get_granularity (struct desc_struct *d)
PATCH v3 27/44 x86/ldttss: Cleanup 32bit descriptors
In reply to Thomas GleixnerLike the IDT descriptors the LDT/TSS descriptors are pointlessly different on 32 and 64 bit.
Unify them and get rid of the duplicated code.
--- arch/x86/include/asm/desc.h | 26 +++----------------------- arch/x86/include/asm/desc_defs.h | 27 ++++++++++++--------------- 2 files changed, 15 insertions(+), 38 deletions(-)
arch/x86/include/asm/desc.h +3 -23
@@ -166,42 +166,22 @@ native_write_gdt_entry(struct desc_strucmemcpy (&gdt[entry], desc, size); } -static inline void pack_descriptor (struct desc_struct *desc,unsigned long base, -unsigned long limit,unsigned char type, -unsigned char flags) -{ - desc->limit0 = (u16 ) limit; - desc->base0 = (u16 ) base; - desc->base1 = (base >>16 ) &0xFF ; - desc->type = type &0x0F ; - desc->s =0 ; - desc->dpl =0 ; - desc->p =1 ; - desc->limit1 = (limit >>16 ) &0xF ; - desc->avl = (flags >>0 ) &0x01 ; - desc->l = (flags >>1 ) &0x01 ; - desc->d = (flags >>2 ) &0x01 ; - desc->g = (flags >>3 ) &0x01 ; -} -static inline void set_tssldt_descriptor (void *d,unsigned long addr,unsigned type,unsigned size) { -#ifdef CONFIG_X86_64 -struct ldttss_desc64 *desc = d; +struct ldttss_desc *desc = d;memset (desc,0 ,sizeof (*desc)); - desc->limit0 = size &0xFFFF ; + desc->limit0 = (u16 ) size; desc->base0 = (u16 ) addr; desc->base1 = (addr >>16 ) &0xFF ; desc->type = type; desc->p =1 ; desc->limit1 = (size >>16 ) &0xF ; desc->base2 = (addr >>24 ) &0xFF ; +#ifdef CONFIG_X86_64 desc->base3 = (u32) (addr >>32 ); -#else -pack_descriptor ((struct desc_struct *)d, addr, size, type,0 );#endif }
arch/x86/include/asm/desc_defs.h +12 -15
@@ -49,24 +49,21 @@ enum { DESCTYPE_S = 0x10, /* !system */ }; -/* LDT or TSS descriptor in the GDT. 16 bytes. */ -struct ldttss_desc64 { -u16 limit0; -u16 base0; -unsigned base1 :8 , type :5 , dpl :2 , p :1 ; -unsigned limit1 :4 , zero0 :3 , g :1 , base2 :8 ; -u32 base3; -u32 zero1; -} __attribute__((packed)); - +/* LDT or TSS descriptor in the GDT. */ +struct ldttss_desc { +u16 limit0; +u16 base0; +u16 base1 :8 , type :5 , dpl :2 , p :1 ; +u16 limit1 :4 , zero0 :3 , g :1 , base2 :8 ;#ifdef CONFIG_X86_64 -typedef struct ldttss_desc64 ldt_desc ; -typedef struct ldttss_desc64 tss_desc ; -#else -typedef struct desc_struct ldt_desc ; -typedef struct desc_struct tss_desc ; +u32 base3; +u32 zero1;#endif +} __attribute__((packed)); + +typedef struct ldttss_desc ldt_desc ; +typedef struct ldttss_desc tss_desc ;struct idt_bits { u16 ist : 3,
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/ldttss: Clean up 32-bit descriptors
x86/ldttss: Clean up 32-bit descriptors
Commit-ID: 87cc037674342cbf6213829b2cc59bb71be60777 Gitweb: http://git.kernel.org/tip/87cc037674342cbf6213829b2cc59bb71be60777 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:42 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:25 +0200
x86/ldttss: Clean up 32-bit descriptors
Like the IDT descriptors, the LDT/TSS descriptors are pointlessly different on 32 and 64 bit kernels.
Unify them and get rid of the duplicated code.
--- arch/x86/include/asm/desc.h | 26 +++----------------------- arch/x86/include/asm/desc_defs.h | 27 ++++++++++++--------------- 2 files changed, 15 insertions(+), 38 deletions(-)
arch/x86/include/asm/desc.h +3 -23
@@ -166,42 +166,22 @@ native_write_gdt_entry(struct desc_struct *gdt, int entry, const void *desc, intmemcpy (&gdt[entry], desc, size); } -static inline void pack_descriptor (struct desc_struct *desc,unsigned long base, -unsigned long limit,unsigned char type, -unsigned char flags) -{ - desc->limit0 = (u16 ) limit; - desc->base0 = (u16 ) base; - desc->base1 = (base >>16 ) &0xFF ; - desc->type = type &0x0F ; - desc->s =0 ; - desc->dpl =0 ; - desc->p =1 ; - desc->limit1 = (limit >>16 ) &0xF ; - desc->avl = (flags >>0 ) &0x01 ; - desc->l = (flags >>1 ) &0x01 ; - desc->d = (flags >>2 ) &0x01 ; - desc->g = (flags >>3 ) &0x01 ; -} -static inline void set_tssldt_descriptor (void *d,unsigned long addr,unsigned type,unsigned size) { -#ifdef CONFIG_X86_64 -struct ldttss_desc64 *desc = d; +struct ldttss_desc *desc = d;memset (desc,0 ,sizeof (*desc)); - desc->limit0 = size &0xFFFF ; + desc->limit0 = (u16 ) size; desc->base0 = (u16 ) addr; desc->base1 = (addr >>16 ) &0xFF ; desc->type = type; desc->p =1 ; desc->limit1 = (size >>16 ) &0xF ; desc->base2 = (addr >>24 ) &0xFF ; +#ifdef CONFIG_X86_64 desc->base3 = (u32) (addr >>32 ); -#else -pack_descriptor ((struct desc_struct *)d, addr, size, type,0 );#endif }
arch/x86/include/asm/desc_defs.h +12 -15
@@ -49,24 +49,21 @@ enum { DESCTYPE_S = 0x10, /* !system */ }; -/* LDT or TSS descriptor in the GDT. 16 bytes. */ -struct ldttss_desc64 { -u16 limit0; -u16 base0; -unsigned base1 :8 , type :5 , dpl :2 , p :1 ; -unsigned limit1 :4 , zero0 :3 , g :1 , base2 :8 ; -u32 base3; -u32 zero1; -} __attribute__((packed)); - +/* LDT or TSS descriptor in the GDT. */ +struct ldttss_desc { +u16 limit0; +u16 base0; +u16 base1 :8 , type :5 , dpl :2 , p :1 ; +u16 limit1 :4 , zero0 :3 , g :1 , base2 :8 ;#ifdef CONFIG_X86_64 -typedef struct ldttss_desc64 ldt_desc ; -typedef struct ldttss_desc64 tss_desc ; -#else -typedef struct desc_struct ldt_desc ; -typedef struct desc_struct tss_desc ; +u32 base3; +u32 zero1;#endif +} __attribute__((packed)); + +typedef struct ldttss_desc ldt_desc ; +typedef struct ldttss_desc tss_desc ;struct idt_bits { u16 ist : 3,
PATCH v3 28/44 x86/idt: Create file for IDT related code
In reply to Thomas GleixnerIDT related code lives in different places. Create a new source file to hold it.
Move the idt_tables and descriptors to it for a start. Follow up patches will gradually move more code over.
--- arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/cpu/common.c | 9 --------- arch/x86/kernel/idt.c | 26 ++++++++++++++++++++++++++ arch/x86/kernel/traps.c | 6 ------ 4 files changed, 27 insertions(+), 16 deletions(-)
arch/x86/kernel/Makefile +1 -1
@@ -42,7 +42,7 @@ CFLAGS_irq.o := -I$(src)/../include/asm/ obj-y := process_$(BITS).o signal.o obj-$(CONFIG_COMPAT) += signal_compat.o -obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o +obj-y += traps.o idt.o irq.o irq_$(BITS).o dumpstack_$(BITS).o obj-y += time.o ioport.o dumpstack.o nmi.o obj-$(CONFIG_MODIFY_LDT_SYSCALL) += ldt.o obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o
arch/x86/kernel/cpu/common.c +0 -9
@@ -1289,15 +1289,6 @@ static __init int setup_disablecpuid(cha__setup ("clearcpuid=" , setup_disablecpuid);#ifdef CONFIG_X86_64 -struct desc_ptr idt_descr__ro_after_init = { - .size =NR_VECTORS *16 -1 , - .address = (unsigned long ) idt_table, -}; -const struct desc_ptr debug_idt_descr = { - .size =NR_VECTORS *16 -1 , - .address = (unsigned long ) debug_idt_table, -}; - DEFINE_PER_CPU_FIRST(union irq_stack_union, irq_stack_union)__aligned(PAGE_SIZE) __visible;
arch/x86/kernel/idt.c new file +26 -0
@@ -0,0 +1,26 @@ +/* +* Interrupt descriptor table related code +* +* This file is licensed under the GPL V2 +*/ +#include <linux/interrupt.h> + +#include <asm/desc.h> + +/* Must be page-aligned because the real IDT is used in a fixmap. */ +gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss; + +#ifdef CONFIG_X86_64 +/* No need to be aligned, but done to keep all IDTs defined the same way. */ +gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss; + +struct desc_ptr idt_descr__ro_after_init = { + .size =IDT_ENTRIES *16 -1 , + .address = (unsigned long ) idt_table, +}; + +const struct desc_ptr debug_idt_descr = { + .size =IDT_ENTRIES *16 -1 , + .address = (unsigned long ) debug_idt_table, +}; +#endif
arch/x86/kernel/traps.c +0 -6
@@ -65,18 +65,12 @@#include <asm/x86_init.h> #include <asm/pgalloc.h> #include <asm/proto.h> - -/* No need to be aligned, but done to keep all IDTs defined the same way. */ -gate_desc debug_idt_table[NR_VECTORS] __page_aligned_bss;#else #include <asm/processor-flags.h> #include <asm/setup.h> #include <asm/proto.h> #endif -/* Must be page-aligned because the real IDT is used in a fixmap. */ -gate_desc idt_table[NR_VECTORS] __page_aligned_bss; -DECLARE_BITMAP (used_vectors,NR_VECTORS );static inline void cond_local_irq_enable (struct pt_regs *regs)
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Create file for IDT related code
x86/idt: Create file for IDT related code
Commit-ID: d8ed9d48266a27ab02a4bbcb81e755d63aec108a Gitweb: http://git.kernel.org/tip/d8ed9d48266a27ab02a4bbcb81e755d63aec108a Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:43 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:25 +0200
x86/idt: Create file for IDT related code
IDT related code lives scattered around in various places. Create a new source file in arch/x86/kernel/idt.c to hold it.
Move the idt_tables and descriptors to it for a start. Follow up patches will gradually move more code over.
--- arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/cpu/common.c | 9 --------- arch/x86/kernel/idt.c | 26 ++++++++++++++++++++++++++ arch/x86/kernel/traps.c | 6 ------ 4 files changed, 27 insertions(+), 16 deletions(-)
arch/x86/kernel/Makefile +1 -1
@@ -42,7 +42,7 @@ CFLAGS_irq.o := -I$(src)/../include/asm/trace obj-y := process_$(BITS).o signal.o obj-$(CONFIG_COMPAT) += signal_compat.o -obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o +obj-y += traps.o idt.o irq.o irq_$(BITS).o dumpstack_$(BITS).o obj-y += time.o ioport.o dumpstack.o nmi.o obj-$(CONFIG_MODIFY_LDT_SYSCALL) += ldt.o obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o
arch/x86/kernel/cpu/common.c +0 -9
@@ -1289,15 +1289,6 @@ static __init int setup_disablecpuid(char *arg)__setup ("clearcpuid=" , setup_disablecpuid);#ifdef CONFIG_X86_64 -struct desc_ptr idt_descr__ro_after_init = { - .size =NR_VECTORS *16 -1 , - .address = (unsigned long ) idt_table, -}; -const struct desc_ptr debug_idt_descr = { - .size =NR_VECTORS *16 -1 , - .address = (unsigned long ) debug_idt_table, -}; - DEFINE_PER_CPU_FIRST(union irq_stack_union, irq_stack_union)__aligned(PAGE_SIZE) __visible;
arch/x86/kernel/idt.c new file +26 -0
@@ -0,0 +1,26 @@ +/* +* Interrupt descriptor table related code +* +* This file is licensed under the GPL V2 +*/ +#include <linux/interrupt.h> + +#include <asm/desc.h> + +/* Must be page-aligned because the real IDT is used in a fixmap. */ +gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss; + +#ifdef CONFIG_X86_64 +/* No need to be aligned, but done to keep all IDTs defined the same way. */ +gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss; + +struct desc_ptr idt_descr__ro_after_init = { + .size =IDT_ENTRIES *16 -1 , + .address = (unsigned long ) idt_table, +}; + +const struct desc_ptr debug_idt_descr = { + .size =IDT_ENTRIES *16 -1 , + .address = (unsigned long ) debug_idt_table, +}; +#endif
arch/x86/kernel/traps.c +0 -6
@@ -65,18 +65,12 @@#include <asm/x86_init.h> #include <asm/pgalloc.h> #include <asm/proto.h> - -/* No need to be aligned, but done to keep all IDTs defined the same way. */ -gate_desc debug_idt_table[NR_VECTORS] __page_aligned_bss;#else #include <asm/processor-flags.h> #include <asm/setup.h> #include <asm/proto.h> #endif -/* Must be page-aligned because the real IDT is used in a fixmap. */ -gate_desc idt_table[NR_VECTORS] __page_aligned_bss; -DECLARE_BITMAP (used_vectors,NR_VECTORS );static inline void cond_local_irq_enable (struct pt_regs *regs)
PATCH v3 29/44 x86/idt: Move 32bit idt_descr to C code
In reply to Thomas Gleixner32bit has the idt_descr sitting in the low level assembly entry code. There is no reason for that. Move it into the C file and use the 64bit version of it.
--- arch/x86/kernel/head_32.S | 6 ------ arch/x86/kernel/idt.c | 10 +++++----- 2 files changed, 5 insertions(+), 11 deletions(-)
arch/x86/kernel/head_32.S +0 -6
@@ -622,7 +622,6 @@ ENTRY(initial_stack) .data .globl boot_gdt_descr -.globl idt_descr ALIGN # early boot GDT descriptor (must use 1:1 address mapping)
@@ -631,11 +630,6 @@ ENTRY(initial_stack) .word __BOOT_DS+7 .long boot_gdt - __PAGE_OFFSET - .word 0 # 32-bit align idt_desc.address -idt_descr: - .word IDT_ENTRIES*8-1 # idt contains 256 entries - .long idt_table - # boot GDT descriptor (later on used by CPU#0): .word 0 # 32 bit align gdt_desc.address ENTRY(early_gdt_descr)
arch/x86/kernel/idt.c +5 -5
@@ -10,15 +10,15 @@/* Must be page-aligned because the real IDT is used in a fixmap. */ gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss; -#ifdef CONFIG_X86_64 -/* No need to be aligned, but done to keep all IDTs defined the same way. */ -gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss; -struct desc_ptr idt_descr__ro_after_init = { - .size =IDT_ENTRIES *16 -1 , + .size = (IDT_ENTRIES *2 *sizeof (unsigned long )) -1 , .address = (unsigned long ) idt_table, }; +#ifdef CONFIG_X86_64 +/* No need to be aligned, but done to keep all IDTs defined the same way. */ +gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss; +const struct desc_ptr debug_idt_descr = { .size =IDT_ENTRIES *16 -1 , .address = (unsigned long) debug_idt_table,
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Move 32-bit idt_descr to C code
x86/idt: Move 32-bit idt_descr to C code
Commit-ID: 16bc18d895cee95f12bd722e5a3016676dfcf084 Gitweb: http://git.kernel.org/tip/16bc18d895cee95f12bd722e5a3016676dfcf084 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:44 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:26 +0200
x86/idt: Move 32-bit idt_descr to C code
32-bit kernels have the idt_descr defined in the low level assembly entry code, but there is no good reason for that.
Move it into the C file and use the 64-bit version of it.
--- arch/x86/kernel/head_32.S | 6 ------ arch/x86/kernel/idt.c | 10 +++++----- 2 files changed, 5 insertions(+), 11 deletions(-)
arch/x86/kernel/head_32.S +0 -6
@@ -622,7 +622,6 @@ int_msg: .data .globl boot_gdt_descr -.globl idt_descr ALIGN # early boot GDT descriptor (must use 1:1 address mapping)
@@ -631,11 +630,6 @@ boot_gdt_descr: .word __BOOT_DS+7 .long boot_gdt - __PAGE_OFFSET - .word 0 # 32-bit align idt_desc.address -idt_descr: - .word IDT_ENTRIES*8-1 # idt contains 256 entries - .long idt_table - # boot GDT descriptor (later on used by CPU#0): .word 0 # 32 bit align gdt_desc.address ENTRY(early_gdt_descr)
arch/x86/kernel/idt.c +5 -5
@@ -10,15 +10,15 @@/* Must be page-aligned because the real IDT is used in a fixmap. */ gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss; -#ifdef CONFIG_X86_64 -/* No need to be aligned, but done to keep all IDTs defined the same way. */ -gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss; -struct desc_ptr idt_descr__ro_after_init = { - .size =IDT_ENTRIES *16 -1 , + .size = (IDT_ENTRIES *2 *sizeof (unsigned long )) -1 , .address = (unsigned long ) idt_table, }; +#ifdef CONFIG_X86_64 +/* No need to be aligned, but done to keep all IDTs defined the same way. */ +gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss; +const struct desc_ptr debug_idt_descr = { .size =IDT_ENTRIES *16 -1 , .address = (unsigned long) debug_idt_table,
PATCH v3 30/44 x86/idt: Remove unused set_trap_gate()
In reply to Thomas GleixnerThis inline is not used at all.
--- arch/x86/include/asm/desc.h | 12 ------------ 1 file changed, 12 deletions(-)
arch/x86/include/asm/desc.h +0 -12
@@ -446,18 +446,6 @@ static inline void set_system_intr_gate(_set_gate (n,GATE_INTERRUPT , addr,0x3 ,0 , __KERNEL_CS); } -static inline void set_system_trap_gate (unsigned int n,void *addr) -{ -BUG_ON ((unsigned )n >0xFF ); -_set_gate (n,GATE_TRAP , addr,0x3 ,0 , __KERNEL_CS); -} - -static inline void set_trap_gate (unsigned int n,void *addr) -{ -BUG_ON ((unsigned )n >0xFF ); -_set_gate (n,GATE_TRAP , addr,0 ,0 , __KERNEL_CS); -} -static inline void set_task_gate (unsigned int n,unsigned int gdt_entry) {BUG_ON ((unsigned )n >0xFF );
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Remove unused set_trap_gate()
x86/idt: Remove unused set_trap_gate()
Commit-ID: 8f55868f9e42fea56021b17421914b9e4fda4960 Gitweb: http://git.kernel.org/tip/8f55868f9e42fea56021b17421914b9e4fda4960 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:45 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:26 +0200
x86/idt: Remove unused set_trap_gate()
This inline is not used at all.
--- arch/x86/include/asm/desc.h | 12 ------------ 1 file changed, 12 deletions(-)
arch/x86/include/asm/desc.h +0 -12
@@ -446,18 +446,6 @@ static inline void set_system_intr_gate(unsigned int n, void *addr)_set_gate (n,GATE_INTERRUPT , addr,0x3 ,0 , __KERNEL_CS); } -static inline void set_system_trap_gate (unsigned int n,void *addr) -{ -BUG_ON ((unsigned )n >0xFF ); -_set_gate (n,GATE_TRAP , addr,0x3 ,0 , __KERNEL_CS); -} - -static inline void set_trap_gate (unsigned int n,void *addr) -{ -BUG_ON ((unsigned )n >0xFF ); -_set_gate (n,GATE_TRAP , addr,0 ,0 , __KERNEL_CS); -} -static inline void set_task_gate (unsigned int n,unsigned int gdt_entry) {BUG_ON ((unsigned )n >0xFF );
PATCH v3 31/44 x86/idt: Consolidate IDT invalidation
In reply to Thomas Gleixnerkexec and reboot have both code to invalidate IDT. Create a common function and use it.
--- arch/x86/include/asm/desc.h | 3 +++ arch/x86/kernel/idt.c | 11 +++++++++++ arch/x86/kernel/machine_kexec_32.c | 14 +------------- arch/x86/kernel/reboot.c | 4 +--- 4 files changed, 16 insertions(+), 16 deletions(-)
arch/x86/include/asm/desc.h +3 -0
@@ -503,4 +503,7 @@ static inline void load_current_idt(void else load_idt((const struct desc_ptr *)&idt_descr); } + +extern void idt_invalidate (void *addr); +#endif /* _ASM_X86_DESC_H */
arch/x86/kernel/idt.c +11 -0
@@ -24,3 +24,14 @@ const struct desc_ptr debug_idt_descr = .address = (unsigned long) debug_idt_table, };#endif + +/** +* idt_invalidate - Invalidate interrupt descriptor table +* @addr: The virtual address of the 'invalid' IDT +*/ +void idt_invalidate (void *addr) +{ +struct desc_ptr idt = { .address = (unsigned long ) addr, .size =0 }; + +load_idt (&idt); +}
arch/x86/kernel/machine_kexec_32.c +1 -13
@@ -26,18 +26,6 @@#include <asm/set_memory.h> #include <asm/debugreg.h> -static void set_idt (void *newidt,__u16 limit) -{ -struct desc_ptr curidt; - -/* ia32 supports unaliged loads & stores */ - curidt.size = limit; - curidt.address = (unsigned long )newidt; - -load_idt (&curidt); -} - -static void set_gdt (void *newgdt,__u16 limit) {struct desc_ptr curgdt;
@@ -245,7 +233,7 @@ void machine_kexec(struct kimage *image)* If you want to load them you must set up your own idt & gdt. */ set_gdt (phys_to_virt (0 ),0 ); -set_idt (phys_to_virt (0 ),0 ); +idt_invalidate (phys_to_virt (0 ));/* now call it */ image->start = relocate_kernel_ptr((unsigned long)image->head,
arch/x86/kernel/reboot.c +1 -3
@@ -38,8 +38,6 @@void (*pm_power_off)(void );EXPORT_SYMBOL (pm_power_off); -static const struct desc_ptr no_idt = {}; -/* * This is set if we need to go through the 'emergency' path. * When machine_emergency_restart() is called, we may be on
@@ -638,7 +636,7 @@ static void native_machine_emergency_resbreak ;case BOOT_TRIPLE : -load_idt (&no_idt); +idt_invalidate (NULL ); __asm__ __volatile__("int3" );/* We're probably dead after this, but... */
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Consolidate IDT invalidation
x86/idt: Consolidate IDT invalidation
Commit-ID: e802a51ede91350438c051da2f238f5e8c918ead Gitweb: http://git.kernel.org/tip/e802a51ede91350438c051da2f238f5e8c918ead Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:46 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:26 +0200
x86/idt: Consolidate IDT invalidation
kexec and reboot have both code to invalidate IDT. Create a common function and use it.
--- arch/x86/include/asm/desc.h | 3 +++ arch/x86/kernel/idt.c | 11 +++++++++++ arch/x86/kernel/machine_kexec_32.c | 14 +------------- arch/x86/kernel/reboot.c | 4 +--- 4 files changed, 16 insertions(+), 16 deletions(-)
arch/x86/include/asm/desc.h +3 -0
@@ -503,4 +503,7 @@ static inline void load_current_idt(void) else load_idt((const struct desc_ptr *)&idt_descr); } + +extern void idt_invalidate (void *addr); +#endif /* _ASM_X86_DESC_H */
arch/x86/kernel/idt.c +11 -0
@@ -24,3 +24,14 @@ const struct desc_ptr debug_idt_descr = { .address = (unsigned long) debug_idt_table, };#endif + +/** +* idt_invalidate - Invalidate interrupt descriptor table +* @addr: The virtual address of the 'invalid' IDT +*/ +void idt_invalidate (void *addr) +{ +struct desc_ptr idt = { .address = (unsigned long ) addr, .size =0 }; + +load_idt (&idt); +}
arch/x86/kernel/machine_kexec_32.c +1 -13
@@ -26,18 +26,6 @@#include <asm/set_memory.h> #include <asm/debugreg.h> -static void set_idt (void *newidt,__u16 limit) -{ -struct desc_ptr curidt; - -/* ia32 supports unaliged loads & stores */ - curidt.size = limit; - curidt.address = (unsigned long )newidt; - -load_idt (&curidt); -} - -static void set_gdt (void *newgdt,__u16 limit) {struct desc_ptr curgdt;
@@ -245,7 +233,7 @@ void machine_kexec(struct kimage *image)* If you want to load them you must set up your own idt & gdt. */ set_gdt (phys_to_virt (0 ),0 ); -set_idt (phys_to_virt (0 ),0 ); +idt_invalidate (phys_to_virt (0 ));/* now call it */ image->start = relocate_kernel_ptr((unsigned long)image->head,
arch/x86/kernel/reboot.c +1 -3
@@ -38,8 +38,6 @@void (*pm_power_off)(void );EXPORT_SYMBOL (pm_power_off); -static const struct desc_ptr no_idt = {}; -/* * This is set if we need to go through the 'emergency' path. * When machine_emergency_restart() is called, we may be on
@@ -638,7 +636,7 @@ static void native_machine_emergency_restart(void)break ;case BOOT_TRIPLE : -load_idt (&no_idt); +idt_invalidate (NULL ); __asm__ __volatile__("int3" );/* We're probably dead after this, but... */
PATCH v3 32/44 x86/idt: Move early IDT handler setup to IDT code
In reply to Thomas GleixnerThe early IDT handler setup is done in C entry code for 64 bit and in ASM entry code for 32 bit. Move the 64bit variant to the IDT code so it can be shared with 32bit in the next step.
--- arch/x86/include/asm/desc.h | 9 +++++++++ arch/x86/kernel/head64.c | 6 +----- arch/x86/kernel/idt.c | 12 ++++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-)
arch/x86/include/asm/desc.h +9 -0
@@ -504,6 +504,15 @@ static inline void load_current_idt(void load_idt((const struct desc_ptr *)&idt_descr); } +extern void idt_setup_early_handler (void ); +extern void idt_setup_early_traps (void ); + +#ifdef CONFIG_X86_64 +extern void idt_setup_early_pf (void ); +#else +static inline void idt_setup_early_pf (void ) { } +#endif +extern void idt_invalidate (void *addr);#endif /* _ASM_X86_DESC_H */
arch/x86/kernel/head64.c +1 -5
@@ -255,8 +255,6 @@ static void __init copy_bootdata(char *r asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) { -int i; -/* * Build-time sanity checks on the kernel image and module * area mappings. (these are purely build-time and produce no code)
@@ -282,9 +280,7 @@ asmlinkage __visible void __init x86_64_kasan_early_init (); -for (i =0 ; i <NUM_EXCEPTION_VECTORS ; i++) -set_intr_gate (i, early_idt_handler_array[i]); -load_idt ((const struct desc_ptr *)&idt_descr); +idt_setup_early_handler ();copy_bootdata (__va (real_mode_data));
arch/x86/kernel/idt.c +12 -0
@@ -26,6 +26,18 @@ const struct desc_ptr debug_idt_descr =#endif /** +* idt_setup_early_handler - Initializes the idt table with early handlers +*/ +void __init idt_setup_early_handler (void ) +{ +int i; + +for (i =0 ; i <NUM_EXCEPTION_VECTORS ; i++) +set_intr_gate (i, early_idt_handler_array[i]); +load_idt (&idt_descr); +} + +/** * idt_invalidate - Invalidate interrupt descriptor table * @addr: The virtual address of the 'invalid' IDT */
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Move early IDT handler setup to IDT code
x86/idt: Move early IDT handler setup to IDT code
Commit-ID: 588787fde7aa346f345e1a7600f84d88039fc9df Gitweb: http://git.kernel.org/tip/588787fde7aa346f345e1a7600f84d88039fc9df Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:47 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:26 +0200
x86/idt: Move early IDT handler setup to IDT code
The early IDT handler setup is done in C entry code on 64-bit kernels and in ASM entry code on 32-bit kernels.
Move the 64-bit variant to the IDT code so it can be shared with 32-bit in the next step.
--- arch/x86/include/asm/desc.h | 9 +++++++++ arch/x86/kernel/head64.c | 6 +----- arch/x86/kernel/idt.c | 12 ++++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-)
arch/x86/include/asm/desc.h +9 -0
@@ -504,6 +504,15 @@ static inline void load_current_idt(void) load_idt((const struct desc_ptr *)&idt_descr); } +extern void idt_setup_early_handler (void ); +extern void idt_setup_early_traps (void ); + +#ifdef CONFIG_X86_64 +extern void idt_setup_early_pf (void ); +#else +static inline void idt_setup_early_pf (void ) { } +#endif +extern void idt_invalidate (void *addr);#endif /* _ASM_X86_DESC_H */
arch/x86/kernel/head64.c +1 -5
@@ -255,8 +255,6 @@ static void __init copy_bootdata(char *real_mode_data) asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) { -int i; -/* * Build-time sanity checks on the kernel image and module * area mappings. (these are purely build-time and produce no code)
@@ -282,9 +280,7 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)kasan_early_init (); -for (i =0 ; i <NUM_EXCEPTION_VECTORS ; i++) -set_intr_gate (i, early_idt_handler_array[i]); -load_idt ((const struct desc_ptr *)&idt_descr); +idt_setup_early_handler ();copy_bootdata (__va (real_mode_data));
arch/x86/kernel/idt.c +12 -0
@@ -26,6 +26,18 @@ const struct desc_ptr debug_idt_descr = {#endif /** +* idt_setup_early_handler - Initializes the idt table with early handlers +*/ +void __init idt_setup_early_handler (void ) +{ +int i; + +for (i =0 ; i <NUM_EXCEPTION_VECTORS ; i++) +set_intr_gate (i, early_idt_handler_array[i]); +load_idt (&idt_descr); +} + +/** * idt_invalidate - Invalidate interrupt descriptor table * @addr: The virtual address of the 'invalid' IDT */
PATCH v3 33/44 x86/idt: Move early IDT setup out of 32bit asm
In reply to Thomas GleixnerThe early IDT setup can be done in C code like it's done on 64 bit. Reuse the 64 bit version.
--- arch/x86/include/asm/segment.h | 1 + arch/x86/kernel/head32.c | 4 ++++ arch/x86/kernel/head_32.S | 36 ++---------------------------------- arch/x86/kernel/idt.c | 4 ++++ 4 files changed, 11 insertions(+), 34 deletions(-)
arch/x86/include/asm/segment.h +1 -0
@@ -238,6 +238,7 @@#ifndef __ASSEMBLY__extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS ][EARLY_IDT_HANDLER_SIZE ]; +extern void early_ignore_irq (void );/* * Load a segment. Fall back on loading the zero segment if something goes
arch/x86/kernel/head32.c +4 -0
@@ -10,6 +10,7 @@#include <linux/mm.h> #include <linux/memblock.h> +#include <asm/desc.h> #include <asm/setup.h> #include <asm/sections.h> #include <asm/e820/api.h>
@@ -30,6 +31,9 @@ static void __init i386_default_early_se asmlinkage __visible void __init i386_start_kernel(void) {cr4_init_shadow (); + +idt_setup_early_handler (); +sanitize_boot_params (&boot_params);x86_early_init_platform_quirks ();
arch/x86/kernel/head_32.S +2 -34
@@ -345,7 +345,6 @@ ENTRY(startup_32_smp) movl %eax,%cr0 lgdt early_gdt_descr - lidt idt_descr ljmp $(__KERNEL_CS),$1f 1: movl $(__KERNEL_DS),%eax # reload all the segment registers movl %eax,%ss # after changing gdt.
@@ -378,37 +377,6 @@ ENDPROC(startup_32_smp) */ __INIT setup_once: - /* - * Set up a idt with 256 interrupt gates that push zero if there - * is no error code and then jump to early_idt_handler_common. - * It doesn't actually load the idt - that needs to be done on - * each CPU. Interrupts are enabled elsewhere, when we can be - * relatively sure everything is ok. - */ - - movl $idt_table,%edi - movl $early_idt_handler_array,%eax - movl $NUM_EXCEPTION_VECTORS,%ecx -1: - movl %eax,(%edi) - movl %eax,4(%edi) - /* interrupt gate, dpl=0, present */ - movl $(0x8E000000 + __KERNEL_CS),2(%edi) - addl $EARLY_IDT_HANDLER_SIZE,%eax - addl $8,%edi - loop 1b - - movl $256 - NUM_EXCEPTION_VECTORS,%ecx - movl $ignore_int,%edx - movl $(__KERNEL_CS << 16),%eax - movw %dx,%ax /* selector = 0x0010 = cs */ - movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ -2: - movl %eax,(%edi) - movl %edx,4(%edi) - addl $8,%edi - loop 2b - #ifdef CONFIG_CC_STACKPROTECTOR /* * Configure the stack canary. The linker can't handle this by
@@ -498,7 +466,7 @@ ENDPROC(early_idt_handler_common) /* This is the default interrupt "handler" :-) */ ALIGN -ignore_int: +ENTRY(early_ignore_irq) cld #ifdef CONFIG_PRINTK pushl %eax
@@ -533,7 +501,7 @@ ENDPROC(early_idt_handler_common) hlt_loop: hlt jmp hlt_loop -ENDPROC(ignore_int) +ENDPROC(early_ignore_irq) __INITDATA .align 4 GLOBAL(early_recursion_flag)
arch/x86/kernel/idt.c +4 -0
@@ -34,6 +34,10 @@ void __init idt_setup_early_handler(voidfor (i =0 ; i <NUM_EXCEPTION_VECTORS ; i++)set_intr_gate (i, early_idt_handler_array[i]); +#ifdef CONFIG_X86_32 +for ( ; i <NR_VECTORS ; i++) +set_intr_gate (i, early_ignore_irq); +#endif load_idt (&idt_descr); }
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Move early IDT setup out of 32-bit asm
x86/idt: Move early IDT setup out of 32-bit asm
Commit-ID: 87e81786b13b267c4355e0d23e33c7e4c08fa63f Gitweb: http://git.kernel.org/tip/87e81786b13b267c4355e0d23e33c7e4c08fa63f Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:48 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:26 +0200
x86/idt: Move early IDT setup out of 32-bit asm
The early IDT setup can be done in C code like it's done on 64-bit kernels. Reuse the 64-bit version.
--- arch/x86/include/asm/segment.h | 1 + arch/x86/kernel/head32.c | 4 ++++ arch/x86/kernel/head_32.S | 36 ++---------------------------------- arch/x86/kernel/idt.c | 4 ++++ 4 files changed, 11 insertions(+), 34 deletions(-)
arch/x86/include/asm/segment.h +1 -0
@@ -238,6 +238,7 @@#ifndef __ASSEMBLY__extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS ][EARLY_IDT_HANDLER_SIZE ]; +extern void early_ignore_irq (void );/* * Load a segment. Fall back on loading the zero segment if something goes
arch/x86/kernel/head32.c +4 -0
@@ -10,6 +10,7 @@#include <linux/mm.h> #include <linux/memblock.h> +#include <asm/desc.h> #include <asm/setup.h> #include <asm/sections.h> #include <asm/e820/api.h>
@@ -30,6 +31,9 @@ static void __init i386_default_early_setup(void) asmlinkage __visible void __init i386_start_kernel(void) {cr4_init_shadow (); + +idt_setup_early_handler (); +sanitize_boot_params (&boot_params);x86_early_init_platform_quirks ();
arch/x86/kernel/head_32.S +2 -34
@@ -345,7 +345,6 @@ ENTRY(startup_32_smp) movl %eax,%cr0 lgdt early_gdt_descr - lidt idt_descr ljmp $(__KERNEL_CS),$1f 1: movl $(__KERNEL_DS),%eax # reload all the segment registers movl %eax,%ss # after changing gdt.
@@ -378,37 +377,6 @@ ENDPROC(startup_32_smp) */ __INIT setup_once: - /* - * Set up a idt with 256 interrupt gates that push zero if there - * is no error code and then jump to early_idt_handler_common. - * It doesn't actually load the idt - that needs to be done on - * each CPU. Interrupts are enabled elsewhere, when we can be - * relatively sure everything is ok. - */ - - movl $idt_table,%edi - movl $early_idt_handler_array,%eax - movl $NUM_EXCEPTION_VECTORS,%ecx -1: - movl %eax,(%edi) - movl %eax,4(%edi) - /* interrupt gate, dpl=0, present */ - movl $(0x8E000000 + __KERNEL_CS),2(%edi) - addl $EARLY_IDT_HANDLER_SIZE,%eax - addl $8,%edi - loop 1b - - movl $256 - NUM_EXCEPTION_VECTORS,%ecx - movl $ignore_int,%edx - movl $(__KERNEL_CS << 16),%eax - movw %dx,%ax /* selector = 0x0010 = cs */ - movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ -2: - movl %eax,(%edi) - movl %edx,4(%edi) - addl $8,%edi - loop 2b - #ifdef CONFIG_CC_STACKPROTECTOR /* * Configure the stack canary. The linker can't handle this by
@@ -498,7 +466,7 @@ ENDPROC(early_idt_handler_common) /* This is the default interrupt "handler" :-) */ ALIGN -ignore_int: +ENTRY(early_ignore_irq) cld #ifdef CONFIG_PRINTK pushl %eax
@@ -533,7 +501,7 @@ ignore_int: hlt_loop: hlt jmp hlt_loop -ENDPROC(ignore_int) +ENDPROC(early_ignore_irq) __INITDATA .align 4 GLOBAL(early_recursion_flag)
arch/x86/kernel/idt.c +4 -0
@@ -34,6 +34,10 @@ void __init idt_setup_early_handler(void)for (i =0 ; i <NUM_EXCEPTION_VECTORS ; i++)set_intr_gate (i, early_idt_handler_array[i]); +#ifdef CONFIG_X86_32 +for ( ; i <NR_VECTORS ; i++) +set_intr_gate (i, early_ignore_irq); +#endif load_idt (&idt_descr); }
PATCH v3 34/44 x86/idt: Prepare for table based init
In reply to Thomas GleixnerThe IDT setup code is handled in several places. All of them use variants of set_intr_gate() inlines. This can be done with a table based initialization, which allows to reduce the inline zoo and puts all IDT related code and information into a single place.
Add the infrastructure.
--- arch/x86/kernel/idt.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
arch/x86/kernel/idt.c +67 -0
@@ -5,8 +5,49 @@*/ #include <linux/interrupt.h> +#include <asm/traps.h> +#include <asm/proto.h> #include <asm/desc.h> +struct idt_data { +unsigned int vector; +unsigned int segment; +struct idt_bits bits; +const void *addr; +}; + +#define DPL0 0x0 +#define DPL3 0x3 + +#define DEFAULT_STACK 0 + +#define G (_vector, _addr, _ist, _type, _dpl, _segment) \ + { \ + .vector = _vector, \ + .bits.ist = _ist, \ + .bits.type = _type, \ + .bits.dpl = _dpl, \ + .bits.p = 1, \ + .addr = _addr, \ + .segment = _segment, \ + } + +/* Interrupt gate */ +#define INTG (_vector, _addr) \ + G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL0, __KERNEL_CS) + +/* System interrupt gate */ +#define SYSG (_vector, _addr) \ + G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL3, __KERNEL_CS) + +/* Interrupt gate with interrupt stack */ +#define ISTG (_vector, _addr, _ist) \ + G(_vector, _addr, _ist, GATE_INTERRUPT, DPL0, __KERNEL_CS) + +/* Task gate */ +#define TSKG (_vector, _gdt) \ + G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3) +/* Must be page-aligned because the real IDT is used in a fixmap. */ gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss;
@@ -25,6 +66,32 @@ const struct desc_ptr debug_idt_descr = };#endif +static inline void idt_init_desc (gate_desc *gate,const struct idt_data *d) +{ +unsigned long addr = (unsigned long ) d->addr; + + gate->offset_low = (u16 ) addr; + gate->segment = (u16 ) d->segment; + gate->bits = d->bits; + gate->offset_middle = (u16) (addr >>16 ); +#ifdef CONFIG_X86_64 + gate->offset_high = (u32) (addr >>32 ); + gate->reserved =0 ; +#endif +} + +static __init void +idt_setup_from_table (gate_desc *idt,const struct idt_data *t,int size) +{ +gate_desc desc; + +for (; size >0 ; t++, size--) { +idt_init_desc (&desc, t); +set_bit (t->vector, used_vectors); +write_idt_entry (idt, t->vector, &desc); + } +} +/** * idt_setup_early_handler - Initializes the idt table with early handlers */
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Prepare for table based init
x86/idt: Prepare for table based init
Commit-ID: 3318e9744244a415ee9481ca7e54234caf5e12c5 Gitweb: http://git.kernel.org/tip/3318e9744244a415ee9481ca7e54234caf5e12c5 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:49 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:27 +0200
x86/idt: Prepare for table based init
The IDT setup code is handled in several places. All of them use variants of set_intr_gate() inlines. This can be done with a table based initialization, which allows to reduce the inline zoo and puts all IDT related code and information into a single place.
Add the infrastructure.
--- arch/x86/kernel/idt.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
arch/x86/kernel/idt.c +67 -0
@@ -5,8 +5,49 @@*/ #include <linux/interrupt.h> +#include <asm/traps.h> +#include <asm/proto.h> #include <asm/desc.h> +struct idt_data { +unsigned int vector; +unsigned int segment; +struct idt_bits bits; +const void *addr; +}; + +#define DPL0 0x0 +#define DPL3 0x3 + +#define DEFAULT_STACK 0 + +#define G (_vector, _addr, _ist, _type, _dpl, _segment) \ + { \ + .vector = _vector, \ + .bits.ist = _ist, \ + .bits.type = _type, \ + .bits.dpl = _dpl, \ + .bits.p = 1, \ + .addr = _addr, \ + .segment = _segment, \ + } + +/* Interrupt gate */ +#define INTG (_vector, _addr) \ + G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL0, __KERNEL_CS) + +/* System interrupt gate */ +#define SYSG (_vector, _addr) \ + G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL3, __KERNEL_CS) + +/* Interrupt gate with interrupt stack */ +#define ISTG (_vector, _addr, _ist) \ + G(_vector, _addr, _ist, GATE_INTERRUPT, DPL0, __KERNEL_CS) + +/* Task gate */ +#define TSKG (_vector, _gdt) \ + G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3) +/* Must be page-aligned because the real IDT is used in a fixmap. */ gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss;
@@ -25,6 +66,32 @@ const struct desc_ptr debug_idt_descr = { };#endif +static inline void idt_init_desc (gate_desc *gate,const struct idt_data *d) +{ +unsigned long addr = (unsigned long ) d->addr; + + gate->offset_low = (u16 ) addr; + gate->segment = (u16 ) d->segment; + gate->bits = d->bits; + gate->offset_middle = (u16) (addr >>16 ); +#ifdef CONFIG_X86_64 + gate->offset_high = (u32) (addr >>32 ); + gate->reserved =0 ; +#endif +} + +static __init void +idt_setup_from_table (gate_desc *idt,const struct idt_data *t,int size) +{ +gate_desc desc; + +for (; size >0 ; t++, size--) { +idt_init_desc (&desc, t); +set_bit (t->vector, used_vectors); +write_idt_entry (idt, t->vector, &desc); + } +} +/** * idt_setup_early_handler - Initializes the idt table with early handlers */
PATCH v3 35/44 x86/idt: Switch early trap init to IDT tables
In reply to Thomas GleixnerAdd the initialization table for the early trap setup and replace the early trap init code.
--- arch/x86/kernel/idt.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/setup.c | 4 +-- arch/x86/kernel/traps.c | 27 ------------------------ 3 files changed, 55 insertions(+), 29 deletions(-)
arch/x86/kernel/idt.c +53 -0
@@ -48,6 +48,28 @@ struct idt_data {#define TSKG (_vector, _gdt) \ G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3) +/* +* Early traps running on the DEFAULT_STACK because the other interrupt +* stacks work only after cpu_init(). +*/ +static const __initdata struct idt_data early_idts[] = { +INTG (X86_TRAP_DB , debug), +SYSG (X86_TRAP_BP , int3), +#ifdef CONFIG_X86_32 +INTG (X86_TRAP_PF , page_fault), +#endif +}; + +#ifdef CONFIG_X86_64 +/* +* Early traps running on the DEFAULT_STACK because the other interrupt +* stacks work only after cpu_init(). +*/ +static const __initdata struct idt_data early_pf_idts[] = { +INTG (X86_TRAP_PF , page_fault), +}; +#endif +/* Must be page-aligned because the real IDT is used in a fixmap. */ gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss;
@@ -93,6 +115,37 @@ idt_setup_from_table(gate_desc *idt, con }/** +* idt_setup_early_traps - Initialize the idt table with early traps +* +* On X8664 these traps do not use interrupt stacks as they can't work +* before cpu_init() is invoked and sets up TSS. The IST variants are +* installed after that. +*/ +void __init idt_setup_early_traps (void ) +{ +idt_setup_from_table (idt_table, early_idts,ARRAY_SIZE (early_idts)); +load_idt (&idt_descr); +} + +#ifdef CONFIG_X86_64 +/** +* idt_setup_early_pf - Initialize the idt table with early pagefault handler +* +* On X8664 this does not use interrupt stacks as they can't work before +* cpu_init() is invoked and sets up TSS. The IST variant is installed +* after that. +* +* FIXME: Why is 32bit and 64bit installing the PF handler at different +* places in the early setup code? +*/ +void __init idt_setup_early_pf (void ) +{ +idt_setup_from_table (idt_table, early_pf_idts, +ARRAY_SIZE (early_pf_idts)); +} +#endif + +/** * idt_setup_early_handler - Initializes the idt table with early handlers */ void __init idt_setup_early_handler (void )
arch/x86/kernel/setup.c +2 -2
@@ -891,7 +891,7 @@ void __init setup_arch(char **cmdline_p)*/ olpc_ofw_detect (); -early_trap_init (); +idt_setup_early_traps ();early_cpu_init ();early_ioremap_init ();
@@ -1162,7 +1162,7 @@ void __init setup_arch(char **cmdline_p)init_mem_mapping (); -early_trap_pf_init (); +idt_setup_early_pf ();/* * Update mmu_cr4_features (and, indirectly, trampoline_cr4_features)
arch/x86/kernel/traps.c +0 -27
@@ -923,33 +923,6 @@ dotraplinkage void do_iret_error(struct }#endif -/* Set of traps needed for early debugging. */ -void __init early_trap_init (void ) -{ -/* -* Don't use IST to set DEBUG_STACK as it doesn't work until TSS -* is ready in cpu_init() <-- trap_init(). Before trap_init(), -* CPU runs at ring 0 so it is impossible to hit an invalid -* stack. Using the original stack works well enough at this -* early stage. DEBUG_STACK will be equipped after cpu_init() in -* trap_init(). -*/ -set_intr_gate (X86_TRAP_DB , debug); -/* int3 can be called from all */ -set_system_intr_gate (X86_TRAP_BP , &int3); -#ifdef CONFIG_X86_32 -set_intr_gate (X86_TRAP_PF , page_fault); -#endif -load_idt (&idt_descr); -} - -void __init early_trap_pf_init (void ) -{ -#ifdef CONFIG_X86_64 -set_intr_gate (X86_TRAP_PF , page_fault); -#endif -} -void __init trap_init (void ) {int i;
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Switch early trap init to IDT tables
x86/idt: Switch early trap init to IDT tables
Commit-ID: 433f8924fa8e55a50ce57f3b8a33ed095c405644 Gitweb: http://git.kernel.org/tip/433f8924fa8e55a50ce57f3b8a33ed095c405644 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:50 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:27 +0200
x86/idt: Switch early trap init to IDT tables
Add the initialization table for the early trap setup and replace the early trap init code.
--- arch/x86/kernel/idt.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/setup.c | 4 ++-- arch/x86/kernel/traps.c | 27 ------------------------- 3 files changed, 55 insertions(+), 29 deletions(-)
arch/x86/kernel/idt.c +53 -0
@@ -48,6 +48,28 @@ struct idt_data {#define TSKG (_vector, _gdt) \ G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3) +/* +* Early traps running on the DEFAULT_STACK because the other interrupt +* stacks work only after cpu_init(). +*/ +static const __initdata struct idt_data early_idts[] = { +INTG (X86_TRAP_DB , debug), +SYSG (X86_TRAP_BP , int3), +#ifdef CONFIG_X86_32 +INTG (X86_TRAP_PF , page_fault), +#endif +}; + +#ifdef CONFIG_X86_64 +/* +* Early traps running on the DEFAULT_STACK because the other interrupt +* stacks work only after cpu_init(). +*/ +static const __initdata struct idt_data early_pf_idts[] = { +INTG (X86_TRAP_PF , page_fault), +}; +#endif +/* Must be page-aligned because the real IDT is used in a fixmap. */ gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss;
@@ -93,6 +115,37 @@ idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size) }/** +* idt_setup_early_traps - Initialize the idt table with early traps +* +* On X8664 these traps do not use interrupt stacks as they can't work +* before cpu_init() is invoked and sets up TSS. The IST variants are +* installed after that. +*/ +void __init idt_setup_early_traps (void ) +{ +idt_setup_from_table (idt_table, early_idts,ARRAY_SIZE (early_idts)); +load_idt (&idt_descr); +} + +#ifdef CONFIG_X86_64 +/** +* idt_setup_early_pf - Initialize the idt table with early pagefault handler +* +* On X8664 this does not use interrupt stacks as they can't work before +* cpu_init() is invoked and sets up TSS. The IST variant is installed +* after that. +* +* FIXME: Why is 32bit and 64bit installing the PF handler at different +* places in the early setup code? +*/ +void __init idt_setup_early_pf (void ) +{ +idt_setup_from_table (idt_table, early_pf_idts, +ARRAY_SIZE (early_pf_idts)); +} +#endif + +/** * idt_setup_early_handler - Initializes the idt table with early handlers */ void __init idt_setup_early_handler (void )
arch/x86/kernel/setup.c +2 -2
@@ -891,7 +891,7 @@ void __init setup_arch(char **cmdline_p)*/ olpc_ofw_detect (); -early_trap_init (); +idt_setup_early_traps ();early_cpu_init ();early_ioremap_init ();
@@ -1162,7 +1162,7 @@ void __init setup_arch(char **cmdline_p)init_mem_mapping (); -early_trap_pf_init (); +idt_setup_early_pf ();/* * Update mmu_cr4_features (and, indirectly, trampoline_cr4_features)
arch/x86/kernel/traps.c +0 -27
@@ -923,33 +923,6 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) }#endif -/* Set of traps needed for early debugging. */ -void __init early_trap_init (void ) -{ -/* -* Don't use IST to set DEBUG_STACK as it doesn't work until TSS -* is ready in cpu_init() <-- trap_init(). Before trap_init(), -* CPU runs at ring 0 so it is impossible to hit an invalid -* stack. Using the original stack works well enough at this -* early stage. DEBUG_STACK will be equipped after cpu_init() in -* trap_init(). -*/ -set_intr_gate (X86_TRAP_DB , debug); -/* int3 can be called from all */ -set_system_intr_gate (X86_TRAP_BP , &int3); -#ifdef CONFIG_X86_32 -set_intr_gate (X86_TRAP_PF , page_fault); -#endif -load_idt (&idt_descr); -} - -void __init early_trap_pf_init (void ) -{ -#ifdef CONFIG_X86_64 -set_intr_gate (X86_TRAP_PF , page_fault); -#endif -} -void __init trap_init (void ) {int i;
PATCH v3 36/44 x86/idt: Move debug stack init to table based
In reply to Thomas GleixnerAdd the debug_idt init table and make use of it.
--- arch/x86/include/asm/desc.h | 2 ++ arch/x86/kernel/idt.c | 23 +++++++++++++++++++++++ arch/x86/kernel/traps.c | 6 +----- 3 files changed, 26 insertions(+), 5 deletions(-)
arch/x86/include/asm/desc.h +2 -0
@@ -509,8 +509,10 @@ extern void idt_setup_early_traps(void);#ifdef CONFIG_X86_64 extern void idt_setup_early_pf (void ); +extern void idt_setup_debugidt_traps (void );#else static inline void idt_setup_early_pf (void ) { } +static inline void idt_setup_debugidt_traps (void ) { }#endif extern void idt_invalidate (void *addr);
arch/x86/kernel/idt.c +23 -0
@@ -68,6 +68,15 @@ static const __initdata struct idt_datastatic const __initdata struct idt_data early_pf_idts[] = {INTG (X86_TRAP_PF , page_fault), }; + +/* +* Override for the debug_idt. Same as the default, but with interrupt +* stack set to DEFAULT_STACK (0). Required for NMI trap handling. +*/ +static const __initdata struct idt_data dbg_idts[] = { +INTG (X86_TRAP_DB , debug), +INTG (X86_TRAP_BP , int3), +};#endif /* Must be page-aligned because the real IDT is used in a fixmap. */
@@ -82,6 +91,10 @@ struct desc_ptr idt_descr __ro_after_ini/* No need to be aligned, but done to keep all IDTs defined the same way. */ gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss; +/* +* Override for the debug_idt. Same as the default, but with interrupt +* stack set to DEFAULT_STACK (0). Required for NMI trap handling. +*/ const struct desc_ptr debug_idt_descr = { .size =IDT_ENTRIES *16 -1 , .address = (unsigned long ) debug_idt_table,
@@ -143,6 +156,16 @@ void __init idt_setup_early_pf(void)idt_setup_from_table (idt_table, early_pf_idts, ARRAY_SIZE(early_pf_idts)); } + +/** +* idt_setup_debugidt_traps - Initialize the debug idt table with debug traps +*/ +void __init idt_setup_debugidt_traps (void ) +{ +memcpy (&debug_idt_table, &idt_table,IDT_ENTRIES *16 ); + +idt_setup_from_table (debug_idt_table, dbg_idts,ARRAY_SIZE (dbg_idts)); +}#endif /**
arch/x86/kernel/traps.c +1 -5
@@ -990,9 +990,5 @@ void __init trap_init(void) x86_init.irqs.trap_init (); -#ifdef CONFIG_X86_64 -memcpy (&debug_idt_table, &idt_table,IDT_ENTRIES *16 ); -set_nmi_gate (X86_TRAP_DB , &debug); -set_nmi_gate (X86_TRAP_BP , &int3); -#endif +idt_setup_debugidt_traps (); }
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Move debug stack init to table based
x86/idt: Move debug stack init to table based
Commit-ID: 0a30908b9149b2b332ccf817261125a634765566 Gitweb: http://git.kernel.org/tip/0a30908b9149b2b332ccf817261125a634765566 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:51 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:27 +0200
x86/idt: Move debug stack init to table based
Add the debug_idt init table and make use of it.
--- arch/x86/include/asm/desc.h | 2 ++ arch/x86/kernel/idt.c | 23 +++++++++++++++++++++++ arch/x86/kernel/traps.c | 6 +----- 3 files changed, 26 insertions(+), 5 deletions(-)
arch/x86/include/asm/desc.h +2 -0
@@ -509,8 +509,10 @@ extern void idt_setup_early_traps(void);#ifdef CONFIG_X86_64 extern void idt_setup_early_pf (void ); +extern void idt_setup_debugidt_traps (void );#else static inline void idt_setup_early_pf (void ) { } +static inline void idt_setup_debugidt_traps (void ) { }#endif extern void idt_invalidate (void *addr);
arch/x86/kernel/idt.c +23 -0
@@ -68,6 +68,15 @@ static const __initdata struct idt_data early_idts[] = {static const __initdata struct idt_data early_pf_idts[] = {INTG (X86_TRAP_PF , page_fault), }; + +/* +* Override for the debug_idt. Same as the default, but with interrupt +* stack set to DEFAULT_STACK (0). Required for NMI trap handling. +*/ +static const __initdata struct idt_data dbg_idts[] = { +INTG (X86_TRAP_DB , debug), +INTG (X86_TRAP_BP , int3), +};#endif /* Must be page-aligned because the real IDT is used in a fixmap. */
@@ -82,6 +91,10 @@ struct desc_ptr idt_descr __ro_after_init = {/* No need to be aligned, but done to keep all IDTs defined the same way. */ gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss; +/* +* Override for the debug_idt. Same as the default, but with interrupt +* stack set to DEFAULT_STACK (0). Required for NMI trap handling. +*/ const struct desc_ptr debug_idt_descr = { .size =IDT_ENTRIES *16 -1 , .address = (unsigned long ) debug_idt_table,
@@ -143,6 +156,16 @@ void __init idt_setup_early_pf(void)idt_setup_from_table (idt_table, early_pf_idts, ARRAY_SIZE(early_pf_idts)); } + +/** +* idt_setup_debugidt_traps - Initialize the debug idt table with debug traps +*/ +void __init idt_setup_debugidt_traps (void ) +{ +memcpy (&debug_idt_table, &idt_table,IDT_ENTRIES *16 ); + +idt_setup_from_table (debug_idt_table, dbg_idts,ARRAY_SIZE (dbg_idts)); +}#endif /**
arch/x86/kernel/traps.c +1 -5
@@ -990,9 +990,5 @@ void __init trap_init(void) x86_init.irqs.trap_init (); -#ifdef CONFIG_X86_64 -memcpy (&debug_idt_table, &idt_table,IDT_ENTRIES *16 ); -set_nmi_gate (X86_TRAP_DB , &debug); -set_nmi_gate (X86_TRAP_BP , &int3); -#endif +idt_setup_debugidt_traps (); }
PATCH v3 37/44 x86/idt: Move ist stack based traps to table init
In reply to Thomas GleixnerInitialize the IST based traps via a table
--- arch/x86/include/asm/desc.h | 2 ++ arch/x86/kernel/idt.c | 22 ++++++++++++++++++++++ arch/x86/kernel/traps.c | 9 +-------- 3 files changed, 25 insertions(+), 8 deletions(-)
arch/x86/include/asm/desc.h +2 -0
@@ -509,9 +509,11 @@ extern void idt_setup_early_traps(void);#ifdef CONFIG_X86_64 extern void idt_setup_early_pf (void ); +extern void idt_setup_ist_traps (void );extern void idt_setup_debugidt_traps (void );#else static inline void idt_setup_early_pf (void ) { } +static inline void idt_setup_ist_traps (void ) { }static inline void idt_setup_debugidt_traps (void ) { }#endif
arch/x86/kernel/idt.c +22 -0
@@ -92,6 +92,20 @@ struct desc_ptr idt_descr __ro_after_ini gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss;/* +* The exceptions which use Interrupt stacks. They are setup after +* cpu_init() when the TSS has been initialized. +*/ +static const __initdata struct idt_data ist_idts[] = { +ISTG (X86_TRAP_DB , debug,DEBUG_STACK ), +ISTG (X86_TRAP_NMI , nmi,NMI_STACK ), +ISTG (X86_TRAP_BP , int3,DEBUG_STACK ), +ISTG (X86_TRAP_DF , double_fault,DOUBLEFAULT_STACK ), +#ifdef CONFIG_X86_MCE +ISTG (X86_TRAP_MC , &machine_check,MCE_STACK ), +#endif +}; + +/* * Override for the debug_idt. Same as the default, but with interrupt * stack set to DEFAULT_STACK (0). Required for NMI trap handling. */
@@ -158,6 +172,14 @@ void __init idt_setup_early_pf(void) }/** +* idt_setup_ist_traps - Initialize the idt table with traps using IST +*/ +void __init idt_setup_ist_traps (void ) +{ +idt_setup_from_table (idt_table, ist_idts,ARRAY_SIZE (ist_idts)); +} + +/** * idt_setup_debugidt_traps - Initialize the debug idt table with debug traps */ void __init idt_setup_debugidt_traps (void )
arch/x86/kernel/traps.c +1 -8
@@ -979,14 +979,7 @@ void __init trap_init(void)*/ cpu_init (); -/* -* X86_TRAP_DB and X86_TRAP_BP have been set -* in early_trap_init(). However, ITS works only after -* cpu_init() loads TSS. See comments in early_trap_init(). -*/ -set_intr_gate_ist (X86_TRAP_DB , &debug,DEBUG_STACK ); -/* int3 can be called from all */ -set_system_intr_gate_ist (X86_TRAP_BP , &int3,DEBUG_STACK ); +idt_setup_ist_traps (); x86_init.irqs.trap_init ();
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Move IST stack based traps to table init
x86/idt: Move IST stack based traps to table init
Commit-ID: 90f6225fba0c732f3f5f9f5e265bdefa021ff12d Gitweb: http://git.kernel.org/tip/90f6225fba0c732f3f5f9f5e265bdefa021ff12d Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:52 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:27 +0200
x86/idt: Move IST stack based traps to table init
Initialize the IST based traps via a table.
--- arch/x86/include/asm/desc.h | 2 ++ arch/x86/kernel/idt.c | 22 ++++++++++++++++++++++ arch/x86/kernel/traps.c | 9 +-------- 3 files changed, 25 insertions(+), 8 deletions(-)
arch/x86/include/asm/desc.h +2 -0
@@ -509,9 +509,11 @@ extern void idt_setup_early_traps(void);#ifdef CONFIG_X86_64 extern void idt_setup_early_pf (void ); +extern void idt_setup_ist_traps (void );extern void idt_setup_debugidt_traps (void );#else static inline void idt_setup_early_pf (void ) { } +static inline void idt_setup_ist_traps (void ) { }static inline void idt_setup_debugidt_traps (void ) { }#endif
arch/x86/kernel/idt.c +22 -0
@@ -92,6 +92,20 @@ struct desc_ptr idt_descr __ro_after_init = { gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss;/* +* The exceptions which use Interrupt stacks. They are setup after +* cpu_init() when the TSS has been initialized. +*/ +static const __initdata struct idt_data ist_idts[] = { +ISTG (X86_TRAP_DB , debug,DEBUG_STACK ), +ISTG (X86_TRAP_NMI , nmi,NMI_STACK ), +ISTG (X86_TRAP_BP , int3,DEBUG_STACK ), +ISTG (X86_TRAP_DF , double_fault,DOUBLEFAULT_STACK ), +#ifdef CONFIG_X86_MCE +ISTG (X86_TRAP_MC , &machine_check,MCE_STACK ), +#endif +}; + +/* * Override for the debug_idt. Same as the default, but with interrupt * stack set to DEFAULT_STACK (0). Required for NMI trap handling. */
@@ -158,6 +172,14 @@ void __init idt_setup_early_pf(void) }/** +* idt_setup_ist_traps - Initialize the idt table with traps using IST +*/ +void __init idt_setup_ist_traps (void ) +{ +idt_setup_from_table (idt_table, ist_idts,ARRAY_SIZE (ist_idts)); +} + +/** * idt_setup_debugidt_traps - Initialize the debug idt table with debug traps */ void __init idt_setup_debugidt_traps (void )
arch/x86/kernel/traps.c +1 -8
@@ -979,14 +979,7 @@ void __init trap_init(void)*/ cpu_init (); -/* -* X86_TRAP_DB and X86_TRAP_BP have been set -* in early_trap_init(). However, ITS works only after -* cpu_init() loads TSS. See comments in early_trap_init(). -*/ -set_intr_gate_ist (X86_TRAP_DB , &debug,DEBUG_STACK ); -/* int3 can be called from all */ -set_system_intr_gate_ist (X86_TRAP_BP , &int3,DEBUG_STACK ); +idt_setup_ist_traps (); x86_init.irqs.trap_init ();
Re: [tip:x86/apic] x86/idt: Move IST stack based traps to table init
Hi Thomas,
We run CRIU tests for linux-next and today they detected an issue. I've bisected this problem and it looks like a problem is in this patch.
[root@fc24 criu]# python ./test/zdtm.py run -t zdtm/static/env00 === Run 1/1 ================ zdtm/static/env00
========================== Run zdtm/static/env00 in h ========================== Start test
./env00 --pidfile=env00.pid --outfile=env00.out --envname=ENV_00_TEST
Run criu dump
=[log]=> dump/zdtm/static/env00/36/1/dump.log
------------------------ grep Error ------------------------
(00.004013) Dump private signals of 36
(00.004022) Dump shared signals of 36
(00.004036) Parasite syscall_ip at 0x400000
(00.004097) ** delivering signal 11 si_code=128
(00.004103) Error (compel/src/lib/infect.c:528): Unexpected 36 task interruption, aborting (00.004118) Error (criu/cr-dump.c:1371): Can't infect (pid: 36) with parasite (00.004208) Unlock network
(00.004218) Unfreezing tasks into 1
(00.004223) Unseizing 36 into 1
(00.004244) Error (criu/cr-dump.c:1807): Dumping FAILED. ------------------------ ERROR OVER ------------------------ ################### Test zdtm/static/env00 FAIL at CRIU dump ################### Send the 9 signal to 36
Wait for zdtm/static/env00(36) to die for 0.100000 ##################################### FAIL #####################################
Here is a line in a code where we get this unexpected error:
https://github.com/xemul/criu/blob/criu-dev/compel/src/lib/infect.c#L735
At this moment criu tries to execute the memfd_create syscall in a context of another task with help of ptrace.
Here is a link to a test job:
https://travis-ci.org/avagin/linux/builds/270623449
Thanks,
Andrei
Quoted 105 lines · tip-bot for Jacob Shin
Commit-ID: 90f6225fba0c732f3f5f9f5e265bdefa021ff12d Gitweb: http://git.kernel.org/tip/90f6225fba0c732f3f5f9f5e265bdefa021ff12d Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:52 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:27 +0200x86/idt: Move IST stack based traps to table init
Initialize the IST based traps via a table.
Signed-off-by Thomas Gleixner <[email protected]>Cc Andy Lutomirski <[email protected]>Cc Borislav Petkov <[email protected]>Cc Brian Gerst <[email protected]>Cc Denys Vlasenko <[email protected]>Cc H. Peter Anvin <[email protected]>Cc Josh Poimboeuf <[email protected]>Cc Linus Torvalds <[email protected]>Cc Peter Zijlstra <[email protected]>Cc Steven Rostedt <[email protected]>Signed-off-by Ingo Molnar <[email protected]>--- arch/x86/include/asm/desc.h | 2 ++ arch/x86/kernel/idt.c | 22 ++++++++++++++++++++++ arch/x86/kernel/traps.c | 9 +-------- 3 files changed, 25 insertions(+), 8 deletions(-)arch/x86/include/asm/desc.h +2
-0@@ -509,9 +509,11 @@ extern void idt_setup_early_traps(void);#ifdef CONFIG_X86_64 extern void idt_setup_early_pf (void ); +extern void idt_setup_ist_traps (void );extern void idt_setup_debugidt_traps (void );#else static inline void idt_setup_early_pf (void ) { } +static inline void idt_setup_ist_traps (void ) { }static inline void idt_setup_debugidt_traps (void ) { }#endif arch/x86/kernel/idt.c +22
-0@@ -92,6 +92,20 @@ struct desc_ptr idt_descr __ro_after_init = { gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss;/* +* The exceptions which use Interrupt stacks. They are setup after +* cpu_init() when the TSS has been initialized. +*/ +static const __initdata struct idt_data ist_idts[] = { +ISTG (X86_TRAP_DB , debug,DEBUG_STACK ), +ISTG (X86_TRAP_NMI , nmi,NMI_STACK ), +ISTG (X86_TRAP_BP , int3,DEBUG_STACK ), +ISTG (X86_TRAP_DF , double_fault,DOUBLEFAULT_STACK ), +#ifdef CONFIG_X86_MCE +ISTG (X86_TRAP_MC , &machine_check,MCE_STACK ), +#endif +}; + +/* * Override for the debug_idt. Same as the default, but with interrupt * stack set to DEFAULT_STACK (0). Required for NMI trap handling. */ @@ -158,6 +172,14 @@ void __init idt_setup_early_pf(void) }/** +* idt_setup_ist_traps - Initialize the idt table with traps using IST +*/ +void __init idt_setup_ist_traps (void ) +{ +idt_setup_from_table (idt_table, ist_idts,ARRAY_SIZE (ist_idts)); +} + +/** * idt_setup_debugidt_traps - Initialize the debug idt table with debug traps */ void __init idt_setup_debugidt_traps (void )arch/x86/kernel/traps.c +1
-8@@ -979,14 +979,7 @@ void __init trap_init(void)*/ cpu_init (); -/* -* X86_TRAP_DB and X86_TRAP_BP have been set -* in early_trap_init(). However, ITS works only after -* cpu_init() loads TSS. See comments in early_trap_init(). -*/ -set_intr_gate_ist (X86_TRAP_DB , &debug,DEBUG_STACK ); -/* int3 can be called from all */ -set_system_intr_gate_ist (X86_TRAP_BP , &int3,DEBUG_STACK ); +idt_setup_ist_traps (); x86_init.irqs.trap_init ();
PATCH 1/1 x86/idt: Fix the X86_TRAP_BP gate
Hi Andrei,
Quoted 4 lines · Andrei Vagin
Hi Thomas,
We run CRIU tests for linux-next and today they detected an issue. I've bisected this problem and it looks like a problem is in this patch.
Ok, there appears to be a bug in that conversion - does the patch below fix the regression for you?
Thanks,
Ingo
================================>
Subject: x86/idt: Fix the X86_TRAP_BP gate
From: Ingo Molnar <[email protected]>
Andrei Vagin reported a CRIU regression and bisected it back to:
90f6225fba0c ("x86/idt: Move IST stack based traps to table init")
This table init conversion loses the system-gate property of X86_TRAP_BP and erroneously moves it from DPL3 to DPL0.
Fix it.
---arch/x86/kernel/idt.c | 6 +++++-
arch/x86/kernel/idt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/x86/kernel/idt.c +5 -1
@@ -44,6 +44,10 @@ struct idt_data {#define ISTG (_vector, _addr, _ist) \ G(_vector, _addr, _ist, GATE_INTERRUPT, DPL0, __KERNEL_CS) +/* System interrupt gate with interrupt stack */ +#define SISTG (_vector, _addr, _ist) \ + G(_vector, _addr, _ist, GATE_INTERRUPT, DPL3, __KERNEL_CS) +/* Task gate */ #define TSKG (_vector, _gdt) \ G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3)
@@ -181,7 +185,7 @@ gate_desc debug_idt_table[IDT_ENTRIES] _static const __initdata struct idt_data ist_idts[] = {ISTG (X86_TRAP_DB , debug,DEBUG_STACK ),ISTG (X86_TRAP_NMI , nmi,NMI_STACK ), -ISTG (X86_TRAP_BP , int3,DEBUG_STACK ), +SISTG (X86_TRAP_BP , int3,DEBUG_STACK ),ISTG (X86_TRAP_DF , double_fault,DOUBLEFAULT_STACK ), #ifdef CONFIG_X86_MCE ISTG(X86_TRAP_MC, &machine_check, MCE_STACK),
Re: [PATCH] x86/idt: Fix the X86_TRAP_BP gate
Quoted 9 lines · Ingo Molnar
Subject: x86/idt: Fix the
X86_TRAP_BPgate
From: Ingo Molnar <[email protected]>Andrei Vagin reported a CRIU regression and bisected it back to:
90f6225fba0c("x86/idt: Move IST stack based traps to table init")This table init conversion loses the system-gate property of
X86_TRAP_BPand erroneously moves it from DPL3 to DPL0.
Duh, yes. Thanks for spotting it.
Quoted 37 lines
Fix it.
Reported-by Andrei Vagin <[email protected]>Cc Linus Torvalds <[email protected]>Cc Peter Zijlstra <[email protected]>Cc Thomas Gleixner <[email protected]>Signed-off-by Ingo Molnar <[email protected]>---
arch/x86/kernel/idt.c| 6 +++++-arch/x86/kernel/idt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)Index:
tip/arch/x86/kernel/idt.c
===================================================================arch/x86/kernel/idt.c +5
-1@@ -44,6 +44,10 @@ struct idt_data {#define ISTG (_vector, _addr, _ist) \ G(_vector, _addr, _ist, GATE_INTERRUPT, DPL0, __KERNEL_CS) +/* System interrupt gate with interrupt stack */ +#define SISTG (_vector, _addr, _ist) \ + G(_vector, _addr, _ist, GATE_INTERRUPT, DPL3, __KERNEL_CS) +/* Task gate */ #define TSKG (_vector, _gdt) \ G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3)@@ -181,7 +185,7 @@ gate_desc debug_idt_table[IDT_ENTRIES] _static const __initdata struct idt_data ist_idts[] = {ISTG (X86_TRAP_DB , debug,DEBUG_STACK ),ISTG (X86_TRAP_NMI , nmi,NMI_STACK ), -ISTG (X86_TRAP_BP , int3,DEBUG_STACK ), +SISTG (X86_TRAP_BP , int3,DEBUG_STACK ),ISTG (X86_TRAP_DF , double_fault,DOUBLEFAULT_STACK ), #ifdef CONFIG_X86_MCE ISTG(X86_TRAP_MC, &machine_check, MCE_STACK),
tip-bot for Ingo Molnar
merge bot[tip:x86/apic] x86/idt: Fix the X86_TRAP_BP gate
In reply to Ingo Molnarx86/idt: Fix the X86_TRAP_BP gate
Commit-ID: c6ef89421e236d75693ae968d80d44a52409889d Gitweb: http://git.kernel.org/tip/c6ef89421e236d75693ae968d80d44a52409889d Author: Ingo Molnar <[email protected]> AuthorDate: Fri, 1 Sep 2017 11:04:56 +0200 Committer: Thomas Gleixner <[email protected]> CommitDate: Fri, 1 Sep 2017 11:04:56 +0200
x86/idt: Fix the X86_TRAP_BP gate
Andrei Vagin reported a CRIU regression and bisected it back to:
90f6225fba0c ("x86/idt: Move IST stack based traps to table init")
This table init conversion loses the system-gate property of X86_TRAP_BP and erroneously moves it from DPL3 to DPL0.
Fix it.
--- arch/x86/kernel/idt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/x86/kernel/idt.c +5 -1
@@ -44,6 +44,10 @@ struct idt_data {#define ISTG (_vector, _addr, _ist) \ G(_vector, _addr, _ist, GATE_INTERRUPT, DPL0, __KERNEL_CS) +/* System interrupt gate with interrupt stack */ +#define SISTG (_vector, _addr, _ist) \ + G(_vector, _addr, _ist, GATE_INTERRUPT, DPL3, __KERNEL_CS) +/* Task gate */ #define TSKG (_vector, _gdt) \ G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3)
@@ -181,7 +185,7 @@ gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss;static const __initdata struct idt_data ist_idts[] = {ISTG (X86_TRAP_DB , debug,DEBUG_STACK ),ISTG (X86_TRAP_NMI , nmi,NMI_STACK ), -ISTG (X86_TRAP_BP , int3,DEBUG_STACK ), +SISTG (X86_TRAP_BP , int3,DEBUG_STACK ),ISTG (X86_TRAP_DF , double_fault,DOUBLEFAULT_STACK ), #ifdef CONFIG_X86_MCE ISTG(X86_TRAP_MC, &machine_check, MCE_STACK),
Re: [PATCH] x86/idt: Fix the X86_TRAP_BP gate
In reply to Ingo MolnarQuoted 5 lines · Ingo Molnar
Hi Andrei,
* Andrei Vagin <[email protected]> wrote:
Quoted 7 lines
Quoted 4 lines
Hi Thomas,
We run CRIU tests for linux-next and today they detected an issue. I've bisected this problem and it looks like a problem is in this patch.
Ok, there appears to be a bug in that conversion - does the patch below fix the regression for you?
Yes, it is.
Thank you!
Quoted 52 lines
Thanks,
Ingo
================================>
Subject: x86/idt: Fix theX86_TRAP_BPgate
From: Ingo Molnar <[email protected]>Andrei Vagin reported a CRIU regression and bisected it back to:
90f6225fba0c("x86/idt: Move IST stack based traps to table init")This table init conversion loses the system-gate property of
X86_TRAP_BPand erroneously moves it from DPL3 to DPL0.Fix it.
Reported-by Andrei Vagin <[email protected]>Cc Linus Torvalds <[email protected]>Cc Peter Zijlstra <[email protected]>Cc Thomas Gleixner <[email protected]>Signed-off-by Ingo Molnar <[email protected]>---
arch/x86/kernel/idt.c| 6 +++++-arch/x86/kernel/idt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)Index:
tip/arch/x86/kernel/idt.c
===================================================================arch/x86/kernel/idt.c +5
-1@@ -44,6 +44,10 @@ struct idt_data {#define ISTG (_vector, _addr, _ist) \ G(_vector, _addr, _ist, GATE_INTERRUPT, DPL0, __KERNEL_CS) +/* System interrupt gate with interrupt stack */ +#define SISTG (_vector, _addr, _ist) \ + G(_vector, _addr, _ist, GATE_INTERRUPT, DPL3, __KERNEL_CS) +/* Task gate */ #define TSKG (_vector, _gdt) \ G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3)@@ -181,7 +185,7 @@ gate_desc debug_idt_table[IDT_ENTRIES] _static const __initdata struct idt_data ist_idts[] = {ISTG (X86_TRAP_DB , debug,DEBUG_STACK ),ISTG (X86_TRAP_NMI , nmi,NMI_STACK ), -ISTG (X86_TRAP_BP , int3,DEBUG_STACK ), +SISTG (X86_TRAP_BP , int3,DEBUG_STACK ),ISTG (X86_TRAP_DF , double_fault,DOUBLEFAULT_STACK ), #ifdef CONFIG_X86_MCE ISTG(X86_TRAP_MC, &machine_check, MCE_STACK),
PATCH v3 38/44 x86/idt: Move regular trap init to tables
In reply to Thomas GleixnerInitialize the regular traps with a table.
--- arch/x86/include/asm/desc.h | 1 arch/x86/kernel/idt.c | 51 ++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/traps.c | 41 ----------------------------------- 3 files changed, 53 insertions(+), 40 deletions(-)
arch/x86/include/asm/desc.h +1 -0
@@ -506,6 +506,7 @@ static inline void load_current_idt(voidextern void idt_setup_early_handler (void );extern void idt_setup_early_traps (void ); +extern void idt_setup_traps (void );#ifdef CONFIG_X86_64 extern void idt_setup_early_pf (void );
arch/x86/kernel/idt.c +51 -0
63 lines not on this page · raw message
arch/x86/kernel/traps.c +1 -40
47 lines not on this page · raw message
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Move regular trap init to tables
x86/idt: Move regular trap init to tables
Commit-ID: b70543a0b2b680f8953b6917a83b9203b20d7abd Gitweb: http://git.kernel.org/tip/b70543a0b2b680f8953b6917a83b9203b20d7abd Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:53 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:27 +0200
x86/idt: Move regular trap init to tables
Initialize the regular traps with a table.
--- arch/x86/include/asm/desc.h | 1 + arch/x86/kernel/idt.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/traps.c | 41 +----------------------------------- 3 files changed, 53 insertions(+), 40 deletions(-)
arch/x86/include/asm/desc.h +1 -0
@@ -506,6 +506,7 @@ static inline void load_current_idt(void)extern void idt_setup_early_handler (void );extern void idt_setup_early_traps (void ); +extern void idt_setup_traps (void );#ifdef CONFIG_X86_64 extern void idt_setup_early_pf (void );
arch/x86/kernel/idt.c +51 -0
63 lines not on this page · raw message
arch/x86/kernel/traps.c +1 -40
47 lines not on this page · raw message
PATCH v3 39/44 x86/idt: Move APIC gate initialization to tables
In reply to Thomas GleixnerReplace the APIC/SMP vector gate initialization with the table based mechanism.
--- arch/x86/include/asm/desc.h | 1 arch/x86/kernel/idt.c | 48 ++++++++++++++++++++++++++++++ arch/x86/kernel/irqinit.c | 69 -------------------------------------------- 3 files changed, 50 insertions(+), 68 deletions(-)
arch/x86/include/asm/desc.h +1 -0
@@ -507,6 +507,7 @@ static inline void load_current_idt(voidextern void idt_setup_early_handler (void );extern void idt_setup_early_traps (void );extern void idt_setup_traps (void ); +extern void idt_setup_apic_and_irq_gates (void );#ifdef CONFIG_X86_64 extern void idt_setup_early_pf (void );
arch/x86/kernel/idt.c +48 -0
60 lines not on this page · raw message
arch/x86/kernel/irqinit.c +1 -68
81 lines not on this page · raw message
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Move APIC gate initialization to tables
x86/idt: Move APIC gate initialization to tables
Commit-ID: 636a7598f65938e1dbacafec74c2e3acdc66bd4d Gitweb: http://git.kernel.org/tip/636a7598f65938e1dbacafec74c2e3acdc66bd4d Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:54 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:28 +0200
x86/idt: Move APIC gate initialization to tables
Replace the APIC/SMP vector gate initialization with the table based mechanism.
--- arch/x86/include/asm/desc.h | 1 + arch/x86/kernel/idt.c | 48 +++++++++++++++++++++++++++++++ arch/x86/kernel/irqinit.c | 69 +-------------------------------------------- 3 files changed, 50 insertions(+), 68 deletions(-)
arch/x86/include/asm/desc.h +1 -0
@@ -507,6 +507,7 @@ static inline void load_current_idt(void)extern void idt_setup_early_handler (void );extern void idt_setup_early_traps (void );extern void idt_setup_traps (void ); +extern void idt_setup_apic_and_irq_gates (void );#ifdef CONFIG_X86_64 extern void idt_setup_early_pf (void );
arch/x86/kernel/idt.c +48 -0
60 lines not on this page · raw message
arch/x86/kernel/irqinit.c +1 -68
81 lines not on this page · raw message
PATCH v3 40/44 x86/idt: Move interrupt gate initialization to IDT code
In reply to Thomas GleixnerMove the gate intialization from interrupt init to the IDT code so all IDT related operations are at a single place.
--- arch/x86/kernel/idt.c | 18 ++++++++++++++++++ arch/x86/kernel/irqinit.c | 18 ------------------ 2 files changed, 18 insertions(+), 18 deletions(-)
arch/x86/kernel/idt.c +18 -0
@@ -286,7 +286,25 @@ void __init idt_setup_debugidt_traps(voi*/ void __init idt_setup_apic_and_irq_gates (void ) { +int i =FIRST_EXTERNAL_VECTOR ; +void *entry; +idt_setup_from_table (idt_table, apic_idts,ARRAY_SIZE (apic_idts)); + +for_each_clear_bit_from (i, used_vectors,FIRST_SYSTEM_VECTOR ) { + entry = irq_entries_start +8 * (i -FIRST_EXTERNAL_VECTOR ); +set_intr_gate (i, entry); + } + +for_each_clear_bit_from (i, used_vectors,NR_VECTORS ) { +#ifdef CONFIG_X86_LOCAL_APIC +set_bit (i, used_vectors); +set_intr_gate (i, spurious_interrupt); +#else + entry = irq_entries_start +8 * (i -FIRST_EXTERNAL_VECTOR ); +set_intr_gate (i, entry); +#endif + } }/**
arch/x86/kernel/irqinit.c +0 -18
@@ -89,29 +89,11 @@ void __init init_IRQ(void)void __init native_init_IRQ (void ) { -int i; -/* Execute any quirks before the call gates are initialised: */ x86_init.irqs.pre_vector_init ();idt_setup_apic_and_irq_gates (); -/* -* Cover the whole vector space, no vector can escape -* us. (some of these will be overridden and become -* 'special' SMP interrupts) -*/ - i =FIRST_EXTERNAL_VECTOR ; -for_each_clear_bit_from (i, used_vectors,FIRST_SYSTEM_VECTOR ) { -/* IA32_SYSCALL_VECTOR could be used in trap_init already. */ -set_intr_gate (i, irq_entries_start + -8 * (i -FIRST_EXTERNAL_VECTOR )); - } -#ifdef CONFIG_X86_LOCAL_APIC -for_each_clear_bit_from (i, used_vectors,NR_VECTORS ) -set_intr_gate (i, spurious_interrupt); -#endif -if (!acpi_ioapic && !of_ioapic &&nr_legacy_irqs ())setup_irq (2 , &irq2);
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Move interrupt gate initialization to IDT code
x86/idt: Move interrupt gate initialization to IDT code
Commit-ID: dc20b2d526539344d7175a2a83221337302596b8 Gitweb: http://git.kernel.org/tip/dc20b2d526539344d7175a2a83221337302596b8 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:55 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:28 +0200
x86/idt: Move interrupt gate initialization to IDT code
Move the gate intialization from interrupt init to the IDT code so all IDT related operations are at a single place.
--- arch/x86/kernel/idt.c | 18 ++++++++++++++++++ arch/x86/kernel/irqinit.c | 18 ------------------ 2 files changed, 18 insertions(+), 18 deletions(-)
arch/x86/kernel/idt.c +18 -0
@@ -286,7 +286,25 @@ void __init idt_setup_debugidt_traps(void)*/ void __init idt_setup_apic_and_irq_gates (void ) { +int i =FIRST_EXTERNAL_VECTOR ; +void *entry; +idt_setup_from_table (idt_table, apic_idts,ARRAY_SIZE (apic_idts)); + +for_each_clear_bit_from (i, used_vectors,FIRST_SYSTEM_VECTOR ) { + entry = irq_entries_start +8 * (i -FIRST_EXTERNAL_VECTOR ); +set_intr_gate (i, entry); + } + +for_each_clear_bit_from (i, used_vectors,NR_VECTORS ) { +#ifdef CONFIG_X86_LOCAL_APIC +set_bit (i, used_vectors); +set_intr_gate (i, spurious_interrupt); +#else + entry = irq_entries_start +8 * (i -FIRST_EXTERNAL_VECTOR ); +set_intr_gate (i, entry); +#endif + } }/**
arch/x86/kernel/irqinit.c +0 -18
@@ -89,29 +89,11 @@ void __init init_IRQ(void)void __init native_init_IRQ (void ) { -int i; -/* Execute any quirks before the call gates are initialised: */ x86_init.irqs.pre_vector_init ();idt_setup_apic_and_irq_gates (); -/* -* Cover the whole vector space, no vector can escape -* us. (some of these will be overridden and become -* 'special' SMP interrupts) -*/ - i =FIRST_EXTERNAL_VECTOR ; -for_each_clear_bit_from (i, used_vectors,FIRST_SYSTEM_VECTOR ) { -/* IA32_SYSCALL_VECTOR could be used in trap_init already. */ -set_intr_gate (i, irq_entries_start + -8 * (i -FIRST_EXTERNAL_VECTOR )); - } -#ifdef CONFIG_X86_LOCAL_APIC -for_each_clear_bit_from (i, used_vectors,NR_VECTORS ) -set_intr_gate (i, spurious_interrupt); -#endif -if (!acpi_ioapic && !of_ioapic &&nr_legacy_irqs ())setup_irq (2 , &irq2);
PATCH v3 41/44 x86/idt: Remove unused functions/inlines
In reply to Thomas GleixnerThe IDT related inlines are not longer used. Remove them.
--- arch/x86/include/asm/desc.h | 36 ------------------------------------ 1 file changed, 36 deletions(-)
arch/x86/include/asm/desc.h +0 -36
@@ -390,16 +390,6 @@ static inline void set_desc_limit(struct desc->limit1 = (limit >>16 ) &0xf ; } -#ifdef CONFIG_X86_64 -static inline void set_nmi_gate (int gate,void *addr) -{ -gate_desc s; - -pack_gate (&s,GATE_INTERRUPT , (unsigned long )addr,0 ,0 , __KERNEL_CS); -write_idt_entry (debug_idt_table, gate, &s); -} -#endif -static inline void _set_gate (int gate,unsigned type,const void *addr,unsigned dpl,unsigned ist,unsigned seg) {
@@ -437,32 +427,6 @@ static inline void alloc_system_vector(iset_intr_gate (n, addr); \ } while (0) -/* -* This routine sets up an interrupt gate at directory privilege level 3. -*/ -static inline void set_system_intr_gate(unsigned int n, void *addr) -{ -BUG_ON ((unsigned )n >0xFF ); -_set_gate (n,GATE_INTERRUPT , addr,0x3 ,0 , __KERNEL_CS); -} - -static inline void set_task_gate (unsigned int n,unsigned int gdt_entry) -{ -BUG_ON ((unsigned )n >0xFF ); -_set_gate (n,GATE_TASK , (void *)0 ,0 ,0 , (gdt_entry<<3 )); -} - -static inline void set_intr_gate_ist (int n,void *addr,unsigned ist) -{ -BUG_ON ((unsigned )n >0xFF ); -_set_gate (n,GATE_INTERRUPT , addr,0 , ist, __KERNEL_CS); -} - -static inline void set_system_intr_gate_ist (int n,void *addr,unsigned ist) -{ -BUG_ON ((unsigned )n >0xFF ); -_set_gate (n,GATE_INTERRUPT , addr,0x3 , ist, __KERNEL_CS); -}#ifdef CONFIG_X86_64 DECLARE_PER_CPU (u32, debug_idt_ctr);
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Remove unused functions/inlines
x86/idt: Remove unused functions/inlines
Commit-ID: 485fa57bd73a0b79987d144e15bdc582f926701d Gitweb: http://git.kernel.org/tip/485fa57bd73a0b79987d144e15bdc582f926701d Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:56 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:28 +0200
x86/idt: Remove unused functions/inlines
The IDT related inlines are not longer used. Remove them.
--- arch/x86/include/asm/desc.h | 36 ------------------------------------ 1 file changed, 36 deletions(-)
arch/x86/include/asm/desc.h +0 -36
@@ -390,16 +390,6 @@ static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit) desc->limit1 = (limit >>16 ) &0xf ; } -#ifdef CONFIG_X86_64 -static inline void set_nmi_gate (int gate,void *addr) -{ -gate_desc s; - -pack_gate (&s,GATE_INTERRUPT , (unsigned long )addr,0 ,0 , __KERNEL_CS); -write_idt_entry (debug_idt_table, gate, &s); -} -#endif -static inline void _set_gate (int gate,unsigned type,const void *addr,unsigned dpl,unsigned ist,unsigned seg) {
@@ -437,32 +427,6 @@ static inline void alloc_system_vector(int vector)set_intr_gate (n, addr); \ } while (0) -/* -* This routine sets up an interrupt gate at directory privilege level 3. -*/ -static inline void set_system_intr_gate(unsigned int n, void *addr) -{ -BUG_ON ((unsigned )n >0xFF ); -_set_gate (n,GATE_INTERRUPT , addr,0x3 ,0 , __KERNEL_CS); -} - -static inline void set_task_gate (unsigned int n,unsigned int gdt_entry) -{ -BUG_ON ((unsigned )n >0xFF ); -_set_gate (n,GATE_TASK , (void *)0 ,0 ,0 , (gdt_entry<<3 )); -} - -static inline void set_intr_gate_ist (int n,void *addr,unsigned ist) -{ -BUG_ON ((unsigned )n >0xFF ); -_set_gate (n,GATE_INTERRUPT , addr,0 , ist, __KERNEL_CS); -} - -static inline void set_system_intr_gate_ist (int n,void *addr,unsigned ist) -{ -BUG_ON ((unsigned )n >0xFF ); -_set_gate (n,GATE_INTERRUPT , addr,0x3 , ist, __KERNEL_CS); -}#ifdef CONFIG_X86_64 DECLARE_PER_CPU (u32, debug_idt_ctr);
PATCH v3 42/44 x86/idt: Deinline setup functions
In reply to Thomas Gleixner--- arch/x86/include/asm/desc.h | 37 ++----------------------------------- arch/x86/kernel/idt.c | 43 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 44 deletions(-)
arch/x86/include/asm/desc.h +2 -35
@@ -390,44 +390,11 @@ static inline void set_desc_limit(struct desc->limit1 = (limit >>16 ) &0xf ; } -static inline void _set_gate (int gate,unsigned type,const void *addr, -unsigned dpl,unsigned ist,unsigned seg) -{ -gate_desc s; - -pack_gate (&s, type, (unsigned long )addr, dpl, ist, seg); -/* -* does not need to be atomic because it is only done once at -* setup time -*/ -write_idt_entry (idt_table, gate, &s); -} - -static inline void set_intr_gate (unsigned int n,const void *addr) -{ -BUG_ON (n >0xFF ); -_set_gate (n,GATE_INTERRUPT , addr,0 ,0 , __KERNEL_CS); -} +void set_intr_gate (unsigned int n,const void *addr); +void alloc_intr_gate (unsigned int n,const void *addr);extern unsigned long used_vectors[]; -static inline void alloc_system_vector (int vector) -{ -BUG_ON (vector <FIRST_SYSTEM_VECTOR ); -if (!test_bit (vector, used_vectors)) { -set_bit (vector, used_vectors); - }else { -BUG (); - } -} - -#define alloc_intr_gate (n, addr) \ - do { \ - alloc_system_vector(n); \ - set_intr_gate(n, addr); \ - } while (0) - -#ifdef CONFIG_X86_64 DECLARE_PER_CPU (u32, debug_idt_ctr);static inline bool is_debug_idt_enabled (void )
arch/x86/kernel/idt.c +34 -9
94 lines not on this page · raw message
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Deinline setup functions
x86/idt: Deinline setup functions
Commit-ID: db18da78f9a8bbab1bdc5968ba47ace788b5061f Gitweb: http://git.kernel.org/tip/db18da78f9a8bbab1bdc5968ba47ace788b5061f Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:57 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:28 +0200
x86/idt: Deinline setup functions
None of this is performance sensitive in any way - so debloat the kernel.
--- arch/x86/include/asm/desc.h | 37 ++----------------------------------- arch/x86/kernel/idt.c | 43 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 44 deletions(-)
arch/x86/include/asm/desc.h +2 -35
@@ -390,44 +390,11 @@ static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit) desc->limit1 = (limit >>16 ) &0xf ; } -static inline void _set_gate (int gate,unsigned type,const void *addr, -unsigned dpl,unsigned ist,unsigned seg) -{ -gate_desc s; - -pack_gate (&s, type, (unsigned long )addr, dpl, ist, seg); -/* -* does not need to be atomic because it is only done once at -* setup time -*/ -write_idt_entry (idt_table, gate, &s); -} - -static inline void set_intr_gate (unsigned int n,const void *addr) -{ -BUG_ON (n >0xFF ); -_set_gate (n,GATE_INTERRUPT , addr,0 ,0 , __KERNEL_CS); -} +void set_intr_gate (unsigned int n,const void *addr); +void alloc_intr_gate (unsigned int n,const void *addr);extern unsigned long used_vectors[]; -static inline void alloc_system_vector (int vector) -{ -BUG_ON (vector <FIRST_SYSTEM_VECTOR ); -if (!test_bit (vector, used_vectors)) { -set_bit (vector, used_vectors); - }else { -BUG (); - } -} - -#define alloc_intr_gate (n, addr) \ - do { \ - alloc_system_vector(n); \ - set_intr_gate(n, addr); \ - } while (0) - -#ifdef CONFIG_X86_64 DECLARE_PER_CPU (u32, debug_idt_ctr);static inline bool is_debug_idt_enabled (void )
arch/x86/kernel/idt.c +34 -9
94 lines not on this page · raw message
PATCH v3 43/44 x86/idt: Simplify alloc_intr_gate
In reply to Thomas GleixnerThe only users of alloc_intr_gate() are hypervisors, which both check the used_vectors bitmap whether they have allocated the gate already. Move that check into alloc_intr_gate() and simplify the users.
--- arch/x86/kernel/cpu/mshyperv.c | 9 ++------- arch/x86/kernel/idt.c | 6 +++--- drivers/xen/events/events_base.c | 6 ++---- 3 files changed, 7 insertions(+), 14 deletions(-)
arch/x86/kernel/cpu/mshyperv.c +2 -7
@@ -59,13 +59,8 @@ void hyperv_vector_handler(struct pt_regvoid hv_setup_vmbus_irq (void (*handler)(void )) { vmbus_handler = handler; -/* -* Setup the IDT for hypervisor callback. Prevent reallocation -* at module reload. -*/ -if (!test_bit (HYPERVISOR_CALLBACK_VECTOR , used_vectors)) -alloc_intr_gate (HYPERVISOR_CALLBACK_VECTOR , - hyperv_callback_vector); +/* Setup the IDT for hypervisor callback */ +alloc_intr_gate (HYPERVISOR_CALLBACK_VECTOR , hyperv_callback_vector); }void hv_remove_vmbus_irq (void )
arch/x86/kernel/idt.c +3 -3
@@ -354,7 +354,7 @@ void set_intr_gate(unsigned int n, constvoid alloc_intr_gate (unsigned int n,const void *addr) { -BUG_ON (test_bit (n, used_vectors) || n <FIRST_SYSTEM_VECTOR ); -set_bit (n, used_vectors); -set_intr_gate (n, addr); +BUG_ON (n <FIRST_SYSTEM_VECTOR ); +if (!test_and_set_bit (n, used_vectors)) +set_intr_gate (n, addr); }
drivers/xen/events/events_base.c +2 -4
@@ -1653,10 +1653,8 @@ void xen_callback_vector(void) return; }pr_info ("Xen HVM callback vector for event delivery is enabled\n" ); -/* in the restore case the vector has already been allocated */ -if (!test_bit (HYPERVISOR_CALLBACK_VECTOR , used_vectors)) -alloc_intr_gate (HYPERVISOR_CALLBACK_VECTOR , - xen_hvm_callback_vector); +alloc_intr_gate (HYPERVISOR_CALLBACK_VECTOR , + xen_hvm_callback_vector); } }#else
RE: [patch V3 43/44] x86/idt: Simplify alloc_intr_gate
Quoted 14 lines
-----Original Message-----
From: Thomas Gleixner [mailto:[email protected]]
Sent: Sunday, August 27, 2017 11:48 PM
To: LKML <[email protected]>
Cc: Ingo Molnar <[email protected]>; Peter Anvin <[email protected]>; Peter Zijlstra <[email protected]>; Andy Lutomirski <[email protected]>; Borislav Petkov <[email protected]>; Steven Rostedt <[email protected]>; Juergen Gross <[email protected]>; KY Srinivasan <[email protected]>; Stephen Hemminger <[email protected]>; Boris Ostrovsky <[email protected]>
Subject: [patch V3 43/44] x86/idt: Simplifyalloc_intr_gate
Quoted 8 lines
The only users of
alloc_intr_gate()are hypervisors, which both check theused_vectorsbitmap whether they have allocated the gate already. Move that
check intoalloc_intr_gate()and simplify the users.Signed-off-by Thomas Gleixner <[email protected]>Reviewed-by Juergen Gross <[email protected]>Cc "K. Y. Srinivasan" <[email protected]>
Quoted 60 lines
Cc Stephen Hemminger <[email protected]>Cc Boris Ostrovsky <[email protected]>Cc Juergen Gross <[email protected]>--- arch/x86/kernel/cpu/mshyperv.c | 9 ++------- arch/x86/kernel/idt.c | 6 +++--- drivers/xen/events/events_base.c | 6 ++---- 3 files changed, 7 insertions(+), 14 deletions(-)arch/x86/kernel/cpu/mshyperv.c +2
-7@@ -59,13 +59,8 @@ void hyperv_vector_handler(struct pt_regvoid hv_setup_vmbus_irq (void (*handler)(void )) { vmbus_handler = handler; -/* -* Setup the IDT for hypervisor callback. Prevent reallocation -* at module reload. -*/ -if (!test_bit (HYPERVISOR_CALLBACK_VECTOR , used_vectors)) -alloc_intr_gate (HYPERVISOR_CALLBACK_VECTOR , - hyperv_callback_vector); +/* Setup the IDT for hypervisor callback */ +alloc_intr_gate (HYPERVISOR_CALLBACK_VECTOR , hyperv_callback_vector); }void
hv_remove_vmbus_irq(void)arch/x86/kernel/idt.c +3
-3@@ -354,7 +354,7 @@ void set_intr_gate(unsigned int n, constvoid alloc_intr_gate (unsigned int n,const void *addr) { -BUG_ON (test_bit (n, used_vectors) || n <FIRST_SYSTEM_VECTOR ); -set_bit (n, used_vectors); -set_intr_gate (n, addr); +BUG_ON (n <FIRST_SYSTEM_VECTOR ); +if (!test_and_set_bit (n, used_vectors)) +set_intr_gate (n, addr); }drivers/xen/events/events_base.c +2
-4@@ -1653,10 +1653,8 @@ void xen_callback_vector(void)return; } pr_info("Xen HVM callback vector for event delivery is enabled\n"); -/* in the restore case the vector has already been allocated */ -if (!test_bit (HYPERVISOR_CALLBACK_VECTOR , used_vectors)) -alloc_intr_gate (HYPERVISOR_CALLBACK_VECTOR , - xen_hvm_callback_vector); +alloc_intr_gate (HYPERVISOR_CALLBACK_VECTOR , +xen_hvm_callback_vector );}
}
#else
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Simplify alloc_intr_gate()
In reply to Thomas Gleixnerx86/idt: Simplify alloc_intr_gate()
Commit-ID: 4447ac1195a845b18f2f427686f116ab77c5b268 Gitweb: http://git.kernel.org/tip/4447ac1195a845b18f2f427686f116ab77c5b268 Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:58 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:28 +0200
x86/idt: Simplify alloc_intr_gate()
The only users of alloc_intr_gate() are hypervisors, which both check the used_vectors bitmap whether they have allocated the gate already. Move that check into alloc_intr_gate() and simplify the users.
--- arch/x86/kernel/cpu/mshyperv.c | 9 ++------- arch/x86/kernel/idt.c | 6 +++--- drivers/xen/events/events_base.c | 6 ++---- 3 files changed, 7 insertions(+), 14 deletions(-)
arch/x86/kernel/cpu/mshyperv.c +2 -7
@@ -59,13 +59,8 @@ void hyperv_vector_handler(struct pt_regs *regs)void hv_setup_vmbus_irq (void (*handler)(void )) { vmbus_handler = handler; -/* -* Setup the IDT for hypervisor callback. Prevent reallocation -* at module reload. -*/ -if (!test_bit (HYPERVISOR_CALLBACK_VECTOR , used_vectors)) -alloc_intr_gate (HYPERVISOR_CALLBACK_VECTOR , - hyperv_callback_vector); +/* Setup the IDT for hypervisor callback */ +alloc_intr_gate (HYPERVISOR_CALLBACK_VECTOR , hyperv_callback_vector); }void hv_remove_vmbus_irq (void )
arch/x86/kernel/idt.c +3 -3
@@ -354,7 +354,7 @@ void set_intr_gate(unsigned int n, const void *addr)void alloc_intr_gate (unsigned int n,const void *addr) { -BUG_ON (test_bit (n, used_vectors) || n <FIRST_SYSTEM_VECTOR ); -set_bit (n, used_vectors); -set_intr_gate (n, addr); +BUG_ON (n <FIRST_SYSTEM_VECTOR ); +if (!test_and_set_bit (n, used_vectors)) +set_intr_gate (n, addr); }
drivers/xen/events/events_base.c +2 -4
@@ -1653,10 +1653,8 @@ void xen_callback_vector(void) return; }pr_info ("Xen HVM callback vector for event delivery is enabled\n" ); -/* in the restore case the vector has already been allocated */ -if (!test_bit (HYPERVISOR_CALLBACK_VECTOR , used_vectors)) -alloc_intr_gate (HYPERVISOR_CALLBACK_VECTOR , - xen_hvm_callback_vector); +alloc_intr_gate (HYPERVISOR_CALLBACK_VECTOR , + xen_hvm_callback_vector); } }#else
PATCH v3 44/44 x86/idt: Hide set_intr_gate()
In reply to Thomas Gleixnerset_intr_gate() is an internal function of the IDT code. The only user left is the KVM code which replaces the pagefault handler eventually.
Provide an explicit update_intr_gate() function and make set_intr_gate() static. While at it replace the magic number 14 in the KVM code with the proper trap define.
--- arch/x86/include/asm/desc.h | 2 +- arch/x86/kernel/idt.c | 33 ++++++++++++++++++++------------- arch/x86/kernel/kvm.c | 2 +- 3 files changed, 22 insertions(+), 15 deletions(-)
arch/x86/include/asm/desc.h +1 -1
@@ -390,7 +390,7 @@ static inline void set_desc_limit(struct desc->limit1 = (limit >>16 ) &0xf ; } -void set_intr_gate (unsigned int n,const void *addr); +void update_intr_gate (unsigned int n,const void *addr);void alloc_intr_gate (unsigned int n,const void *addr);extern unsigned long used_vectors[];
arch/x86/kernel/idt.c +20 -13
@@ -225,6 +225,22 @@ idt_setup_from_table(gate_desc *idt, con } } +static void set_intr_gate (unsigned int n,const void *addr) +{ +struct idt_data data; + +BUG_ON (n >0xFF ); + +memset (&data,0 ,sizeof (data)); + data.vector = n; + data.addr = addr; + data.segment = __KERNEL_CS; + data.bits.type =GATE_INTERRUPT ; + data.bits.p =1 ; + +idt_setup_from_table (idt_table, &data,1 , false); +} +/** * idt_setup_early_traps - Initialize the idt table with early traps *
@@ -336,20 +352,11 @@ void idt_invalidate(void *addr)load_idt (&idt); } -void set_intr_gate (unsigned int n,const void *addr) +void __init update_intr_gate (unsigned int n,const void *addr) { -struct idt_data data; - -BUG_ON (n >0xFF ); - -memset (&data,0 ,sizeof (data)); - data.vector = n; - data.addr = addr; - data.segment = __KERNEL_CS; - data.bits.type =GATE_INTERRUPT ; - data.bits.p =1 ; - -idt_setup_from_table (idt_table, &data,1 , false); +if (WARN_ON_ONCE (!test_bit (n, used_vectors))) +return ; +set_intr_gate (n, addr); }void alloc_intr_gate (unsigned int n,const void *addr)
arch/x86/kernel/kvm.c +1 -1
@@ -455,7 +455,7 @@ static int kvm_cpu_down_prepare(unsignedstatic void __init kvm_apf_trap_init (void ) { -set_intr_gate (14 , async_page_fault); +update_intr_gate (X86_TRAP_PF , async_page_fault); }void __init kvm_guest_init (void )
tip-bot for Thomas Gleixner
merge bot[tip:x86/apic] x86/idt: Hide set_intr_gate()
x86/idt: Hide set_intr_gate()
Commit-ID: facaa3e3c813848e6b49ee37a42a3688832e63cd Gitweb: http://git.kernel.org/tip/facaa3e3c813848e6b49ee37a42a3688832e63cd Author: Thomas Gleixner <[email protected]> AuthorDate: Mon, 28 Aug 2017 08:47:59 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 29 Aug 2017 12:07:29 +0200
x86/idt: Hide set_intr_gate()
set_intr_gate() is an internal function of the IDT code. The only user left is the KVM code which replaces the pagefault handler eventually.
Provide an explicit update_intr_gate() function and make set_intr_gate() static. While at it replace the magic number 14 in the KVM code with the proper trap define.
--- arch/x86/include/asm/desc.h | 2 +- arch/x86/kernel/idt.c | 33 ++++++++++++++++++++------------- arch/x86/kernel/kvm.c | 2 +- 3 files changed, 22 insertions(+), 15 deletions(-)
arch/x86/include/asm/desc.h +1 -1
@@ -390,7 +390,7 @@ static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit) desc->limit1 = (limit >>16 ) &0xf ; } -void set_intr_gate (unsigned int n,const void *addr); +void update_intr_gate (unsigned int n,const void *addr);void alloc_intr_gate (unsigned int n,const void *addr);extern unsigned long used_vectors[];
arch/x86/kernel/idt.c +20 -13
@@ -225,6 +225,22 @@ idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size, bool sy } } +static void set_intr_gate (unsigned int n,const void *addr) +{ +struct idt_data data; + +BUG_ON (n >0xFF ); + +memset (&data,0 ,sizeof (data)); + data.vector = n; + data.addr = addr; + data.segment = __KERNEL_CS; + data.bits.type =GATE_INTERRUPT ; + data.bits.p =1 ; + +idt_setup_from_table (idt_table, &data,1 , false); +} +/** * idt_setup_early_traps - Initialize the idt table with early traps *
@@ -336,20 +352,11 @@ void idt_invalidate(void *addr)load_idt (&idt); } -void set_intr_gate (unsigned int n,const void *addr) +void __init update_intr_gate (unsigned int n,const void *addr) { -struct idt_data data; - -BUG_ON (n >0xFF ); - -memset (&data,0 ,sizeof (data)); - data.vector = n; - data.addr = addr; - data.segment = __KERNEL_CS; - data.bits.type =GATE_INTERRUPT ; - data.bits.p =1 ; - -idt_setup_from_table (idt_table, &data,1 , false); +if (WARN_ON_ONCE (!test_bit (n, used_vectors))) +return ; +set_intr_gate (n, addr); }void alloc_intr_gate (unsigned int n,const void *addr)
arch/x86/kernel/kvm.c +1 -1
@@ -455,7 +455,7 @@ static int kvm_cpu_down_prepare(unsigned int cpu)static void __init kvm_apf_trap_init (void ) { -set_intr_gate (14 , async_page_fault); +update_intr_gate (X86_TRAP_PF , async_page_fault); }void __init kvm_guest_init (void )