x86_64: Rework root IRQ handler invocation
PATCH 3/4 x86_64: Rework root IRQ handler invocation
The current approach to propagate root hardware interrupts from the I-pipe layer fails to set the timer IRQ register context correctly and comes with an extra function call indirection. This patch addresses both, specifically repairing Linux profiling and processing time accounting abilities.
To save the latter also when Xenomai is enabled, it takes an additional Xenomai fix that will be posted to the related list.
Jan
--- arch/x86_64/kernel/entry.S | 22 ------------------- arch/x86_64/kernel/ipipe.c | 20 ++++++++++++----- include/asm-x86_64/ipipe.h | 51 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 57 insertions(+), 36 deletions(-)
arch/x86_64/kernel/entry.S +1 -21
@@ -582,26 +582,6 @@ END(stub_rt_sigreturn) #ifdef CONFIG_IPIPE - /* %rdi=negated _vector_ number, %rsi=handler */ -ENTRY(__ipipe_root_xirq_thunk) - movq %rsp, %rax - pushq $0 - pushq %rax - pushfq - pushq $__KERNEL_CS - pushq $1f - pushq %rdi - XCPT_FRAME - SAVE_ARGS - leaq -ARGOFFSET(%rsp),%rdi # regs for handler - call *%rsi - jmp exit_intr - CFI_ENDPROC -1: - cli - ret -END(__ipipe_root_xirq_thunk) - /* %rdi=virq number, %rsi=cookie, %rdx=handler */ ENTRY(__ipipe_root_virq_thunk) movq %rsp, %rax
@@ -647,7 +627,7 @@ ret_from_intr: leaveq CFI_DEF_CFA_REGISTER rsp CFI_ADJUST_CFA_OFFSET -8 -exit_intr: +ENTRY(exit_intr) GET_THREAD_INFO(%rcx) testl $3,CS-ARGOFFSET(%rsp) je retint_kernel
arch/x86_64/kernel/ipipe.c +14 -6
@@ -750,13 +750,21 @@ int __ipipe_handle_irq(struct pt_regs *r finalize: +/* +* Given our deferred dispatching model for regular IRQs, we only +* record relevant registers for the last timer interrupt, so that the +* timer handler charges CPU times properly. It is assumed that other +* interrupt handlers don't actually care for such information. +*/ if (irq == __ipipe_tick_irq) { -__raw_get_cpu_var (__ipipe_tick_regs).rip = regs->rip; -__raw_get_cpu_var (__ipipe_tick_regs).cs = regs->cs; -__raw_get_cpu_var (__ipipe_tick_regs).eflags = regs->eflags; -__raw_get_cpu_var (__ipipe_tick_regs).rbp = regs->rbp; -__raw_get_cpu_var (__ipipe_tick_regs).rsp = regs->rsp; -__raw_get_cpu_var (__ipipe_tick_regs).ss = regs->ss; +struct pt_regs *tick_regs = + &__raw_get_cpu_var (__ipipe_tick_regs); + tick_regs->ss = regs->ss; + tick_regs->rsp = regs->rsp; + tick_regs->eflags = regs->eflags; + tick_regs->cs = regs->cs; + tick_regs->rip = regs->rip; + tick_regs->rbp = regs->rbp; }/*
include/asm-x86_64/ipipe.h +42 -9
69 lines not on this page · raw message