All of lore.kernel.org
 help / color / mirror / Atom feed
* [Adeos-main] [RFC][PATCH 2/2] x86: Add support for ipipe_get_irq_regs
@ 2010-06-03 14:22 Jan Kiszka
  2010-06-05 17:40 ` Philippe Gerum
  0 siblings, 1 reply; 6+ messages in thread
From: Jan Kiszka @ 2010-06-03 14:22 UTC (permalink / raw)
  To: Philippe Gerum; +Cc: adeos-main

From: Jan Kiszka <jan.kiszka@domain.hid>

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 <jan.kiszka@domain.hid>
---
 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)))


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-06-05 21:09 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-03 14:22 [Adeos-main] [RFC][PATCH 2/2] x86: Add support for ipipe_get_irq_regs Jan Kiszka
2010-06-05 17:40 ` Philippe Gerum
2010-06-05 18:37   ` Jan Kiszka
2010-06-05 19:23     ` Gilles Chanteperdrix
2010-06-05 20:48       ` Jan Kiszka
2010-06-05 21:09         ` Philippe Gerum

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.