From: Jan Kiszka <[email protected]>

Implement the x86 arch bits for ipipe_get_irq_regs support. This allows
to drop __ipipe_tick_regs and use the new service instead.

Signed-off-by: Jan Kiszka <[email protected]>
---
 arch/x86/include/asm/ipipe.h    |   43 +++++++++++++++++++++++++++++++++++++-
 arch/x86/include/asm/ipipe_32.h |    2 +-
 arch/x86/include/asm/ipipe_64.h |    2 +-
 arch/x86/kernel/ipipe.c         |   26 +++--------------------
 4 files changed, 47 insertions(+), 26 deletions(-)

diff --git a/arch/x86/include/asm/ipipe.h b/arch/x86/include/asm/ipipe.h
index 4d711dd..971b3f3 100644
--- a/arch/x86/include/asm/ipipe.h
+++ b/arch/x86/include/asm/ipipe.h
@@ -31,8 +31,6 @@
 #define IPIPE_PATCH_NUMBER     4
 #endif
 
-DECLARE_PER_CPU(struct pt_regs, __ipipe_tick_regs);
-
 static inline unsigned __ipipe_get_irq_vector(int irq)
 {
 #ifdef CONFIG_X86_IO_APIC
@@ -153,4 +151,45 @@ int __ipipe_check_tickdev(const char *devname);
 #define __ipipe_move_root_irq(irq)     do { } while (0)
 #endif /* !(CONFIG_SMP && CONFIG_IPIPE) */
 
+static inline void
+__ipipe_setup_irq_regs(struct pt_regs **orig_regs, struct pt_regs *saved_regs)
+{
+       *orig_regs = ipipe_get_irq_regs();
+
+       if (*orig_regs)
+               saved_regs->orig_ax = (*orig_regs)->orig_ax;
+       else {
+               saved_regs->flags = X86_EFLAGS_IF;
+               saved_regs->cs = __KERNEL_CS;
+#ifdef CONFIG_X86_32
+               saved_regs->ss = __KERNEL_DS;
+               __asm__ __volatile__ ("here: movl $here, %0\n\t"
+                                     "movl %%ebp, %1\n\t"
+                                     "movl %%esp, %2\n\t"
+                                     : "=m" (saved_regs->ip),
+                                       "=m" (saved_regs->bp),
+                                       "=m" (saved_regs->sp));
+#else /* CONFIG_X86_64 */
+               saved_regs->ss = 0;
+               __asm__ __volatile__ ("here: movq $here, %0\n\t"
+                                     "movq %%rbp, %1\n\t"
+                                     "movq %%rsp, %2\n\t"
+                                     : "=m" (saved_regs->ip),
+                                       "=m" (saved_regs->bp),
+                                       "=m" (saved_regs->sp));
+#endif /* CONFIG_X86_64 */
+               __ipipe_get_cpu_var(ipipe_irq_regs) = saved_regs;
+       }
+}
+
+static inline void
+__ipipe_cleanup_irq_regs(struct pt_regs *orig_regs,
+                        struct pt_regs *saved_regs)
+{
+       if (orig_regs)
+               orig_regs->orig_ax = saved_regs->orig_ax;
+       else
+               __ipipe_get_cpu_var(ipipe_irq_regs) = NULL;
+}
+
 #endif /* !__X86_IPIPE_H */
diff --git a/arch/x86/include/asm/ipipe_32.h b/arch/x86/include/asm/ipipe_32.h
index 8d1f4b5..ce3d417 100644
--- a/arch/x86/include/asm/ipipe_32.h
+++ b/arch/x86/include/asm/ipipe_32.h
@@ -65,7 +65,7 @@ void __ipipe_end_edge_irq(unsigned irq, struct irq_desc 
*desc);
 static inline void __ipipe_call_root_xirq_handler(unsigned irq,
                                                  ipipe_irq_handler_t handler)
 {
-       struct pt_regs *regs = &__raw_get_cpu_var(__ipipe_tick_regs);
+       struct pt_regs *regs = ipipe_get_irq_regs();
 
        regs->orig_ax = ~__ipipe_get_irq_vector(irq);
 
diff --git a/arch/x86/include/asm/ipipe_64.h b/arch/x86/include/asm/ipipe_64.h
index bc427b8..4452662 100644
--- a/arch/x86/include/asm/ipipe_64.h
+++ b/arch/x86/include/asm/ipipe_64.h
@@ -63,7 +63,7 @@ void __ipipe_end_edge_irq(unsigned irq, struct irq_desc 
*desc);
 static inline void __ipipe_call_root_xirq_handler(unsigned irq,
                                                  void (*handler)(unsigned, 
void *))
 {
-       struct pt_regs *regs = &__raw_get_cpu_var(__ipipe_tick_regs);
+       struct pt_regs *regs = ipipe_get_irq_regs();
 
        regs->orig_ax = ~__ipipe_get_irq_vector(irq);
 
diff --git a/arch/x86/kernel/ipipe.c b/arch/x86/kernel/ipipe.c
index 521ec53..23b6908 100644
--- a/arch/x86/kernel/ipipe.c
+++ b/arch/x86/kernel/ipipe.c
@@ -900,11 +900,14 @@ int __ipipe_syscall_root(struct pt_regs *regs)
  */
 int __ipipe_handle_irq(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs = __ipipe_get_cpu_var(ipipe_irq_regs);
        struct ipipe_domain *this_domain, *next_domain;
        unsigned int vector = regs->orig_ax, irq;
        struct list_head *head, *pos;
        int m_ack;
 
+       __ipipe_get_cpu_var(ipipe_irq_regs) = regs;
+
        if ((long)regs->orig_ax < 0) {
                vector = ~vector;
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -976,28 +979,7 @@ int __ipipe_handle_irq(struct pt_regs *regs)
        __ipipe_walk_pipeline(head);
 
 finalize_nosync:
-
-       /*
-        * Given our deferred dispatching model for regular IRQs, we
-        * only record CPU regs 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) {
-               struct pt_regs *tick_regs = 
&__raw_get_cpu_var(__ipipe_tick_regs);
-               tick_regs->flags = regs->flags;
-               tick_regs->cs = regs->cs;
-               tick_regs->ip = regs->ip;
-               tick_regs->bp = regs->bp;
-#ifdef CONFIG_X86_64
-               tick_regs->ss = regs->ss;
-               tick_regs->sp = regs->sp;
-#endif
-               if (!ipipe_root_domain_p)
-                       tick_regs->flags &= ~X86_EFLAGS_IF;
-       }
+       __ipipe_get_cpu_var(ipipe_irq_regs) = old_regs;
 
        if (!ipipe_root_domain_p ||
            test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)))

_______________________________________________
Adeos-main mailing list
[email protected]
https://mail.gna.org/listinfo/adeos-main

Reply via email to