[tip:irq/core] x86: Hyperv: Cleanup the irq mess

2014-03-04 Thread tip-bot for Thomas Gleixner
Commit-ID:  1aec169673d7db113c37367bbc371c2ba8109f06
Gitweb: http://git.kernel.org/tip/1aec169673d7db113c37367bbc371c2ba8109f06
Author: Thomas Gleixner 
AuthorDate: Sun, 23 Feb 2014 21:40:22 +
Committer:  Thomas Gleixner 
CommitDate: Tue, 4 Mar 2014 17:37:54 +0100

x86: Hyperv: Cleanup the irq mess

The vmbus/hyperv interrupt handling is another complete trainwreck and
probably the worst of all currently in tree.

If CONFIG_HYPERV=y then the interrupt delivery to the vmbus happens
via the direct HYPERVISOR_CALLBACK_VECTOR. So far so good, but:

  The driver requests first a normal device interrupt. The only reason
  to do so is to increment the interrupt stats of that device
  interrupt. For no reason it also installs a private flow handler.

  We have proper accounting mechanisms for direct vectors, but of
  course it's too much effort to add that 5 lines of code.

  Aside of that the alloc_intr_gate() is not protected against
  reallocation which makes module reload impossible.

Solution to the problem is simple to rip out the whole mess and
implement it correctly.

First of all move all that code to arch/x86/kernel/cpu/mshyperv.c and
merily install the HYPERVISOR_CALLBACK_VECTOR with proper reallocation
protection and use the proper direct vector accounting mechanism.

Signed-off-by: Thomas Gleixner 
Acked-by: K. Y. Srinivasan 
Cc: Peter Zijlstra 
Cc: Greg Kroah-Hartman 
Cc: linuxdrivers 
Cc: x86 
Link: http://lkml.kernel.org/r/20140223212739.028307...@linutronix.de
Signed-off-by: Thomas Gleixner 

---
 arch/x86/include/asm/mshyperv.h |  4 ++-
 arch/x86/kernel/cpu/mshyperv.c  | 78 +
 drivers/hv/vmbus_drv.c  | 39 +++--
 3 files changed, 47 insertions(+), 74 deletions(-)

diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index cd9c419..e98f66f 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -2,6 +2,7 @@
 #define _ASM_X86_MSHYPER_H
 
 #include 
+#include 
 #include 
 
 struct ms_hyperv_info {
@@ -16,6 +17,7 @@ void hyperv_callback_vector(void);
 #define trace_hyperv_callback_vector hyperv_callback_vector
 #endif
 void hyperv_vector_handler(struct pt_regs *regs);
-void hv_register_vmbus_handler(int irq, irq_handler_t handler);
+int hv_setup_vmbus_irq(int irq, irq_handler_t handler, void *dev_id);
+void hv_remove_vmbus_irq(int irq, void *dev_id);
 
 #endif
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 9f7ca26..1bd316c 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -30,6 +31,45 @@
 struct ms_hyperv_info ms_hyperv;
 EXPORT_SYMBOL_GPL(ms_hyperv);
 
+#ifdef CONFIG_HYPERV
+static irq_handler_t *vmbus_handler;
+
+void hyperv_vector_handler(struct pt_regs *regs)
+{
+   struct pt_regs *old_regs = set_irq_regs(regs);
+
+   irq_enter();
+   exit_idle();
+
+   inc_irq_stat(irq_hv_callback_count);
+   if (vmbus_handler)
+   vmbus_handler();
+
+   irq_exit();
+   set_irq_regs(old_regs);
+}
+
+int hv_setup_vmbus_irq(int irq, irq_handler_t *handler, void *dev_id)
+{
+   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);
+}
+
+void hv_remove_vmbus_irq(unsigned int irq, void *dev_id)
+{
+   /* We have no way to deallocate the interrupt gate */
+   vmbus_handler = NULL;
+}
+EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq);
+EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq);
+#endif
+
 static uint32_t  __init ms_hyperv_platform(void)
 {
u32 eax;
@@ -113,41 +153,3 @@ const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv 
= {
.init_platform  = ms_hyperv_init_platform,
 };
 EXPORT_SYMBOL(x86_hyper_ms_hyperv);
-
-#if IS_ENABLED(CONFIG_HYPERV)
-static int vmbus_irq = -1;
-static irq_handler_t vmbus_isr;
-
-void hv_register_vmbus_handler(int irq, irq_handler_t handler)
-{
-   /*
-* Setup the IDT for hypervisor callback.
-*/
-   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
-
-   vmbus_irq = irq;
-   vmbus_isr = handler;
-}
-
-void hyperv_vector_handler(struct pt_regs *regs)
-{
-   struct pt_regs *old_regs = set_irq_regs(regs);
-   struct irq_desc *desc;
-
-   irq_enter();
-   exit_idle();
-
-   desc = irq_to_desc(vmbus_irq);
-
-   if (desc)
-   generic_handle_irq_desc(vmbus_irq, desc);
-
-   irq_exit();
-   set_irq_regs(old_regs);
-}
-#else
-void hv_register_vmbus_handler(int irq, irq_handler_t handler)
-{
-}
-#endif
-EXPORT_SYMBOL_GPL(hv_register_vmbus_handler);
diff --git a/drivers/hv/vmbus_drv.c

[tip:irq/core] x86: hyperv: Make it build with CONFIG_HYPERV= m again

2014-03-04 Thread tip-bot for Thomas Gleixner
Commit-ID:  3c433679ab666fb76a9399679819a303989e8ead
Gitweb: http://git.kernel.org/tip/3c433679ab666fb76a9399679819a303989e8ead
Author: Thomas Gleixner 
AuthorDate: Tue, 4 Mar 2014 23:39:58 +0100
Committer:  Thomas Gleixner 
CommitDate: Tue, 4 Mar 2014 23:41:44 +0100

x86: hyperv: Make it build with CONFIG_HYPERV=m again

Commit 1aec16967 (x86: Hyperv: Cleanup the irq mess) removed the
ability to build the hyperv stuff as a module. Bring it back.

Reported-by: fengguang...@intel.com
Signed-off-by: Thomas Gleixner 
Cc: K. Y. Srinivasan 
Cc: Peter Zijlstra 
Cc: Greg Kroah-Hartman 
Cc: linuxdrivers 
Cc: x86 
---
 arch/x86/kernel/cpu/mshyperv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 1bd316c..316e106 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -31,7 +31,7 @@
 struct ms_hyperv_info ms_hyperv;
 EXPORT_SYMBOL_GPL(ms_hyperv);
 
-#ifdef CONFIG_HYPERV
+#if IS_ENABLED(CONFIG_HYPERV)
 static irq_handler_t *vmbus_handler;
 
 void hyperv_vector_handler(struct pt_regs *regs)
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[tip:irq/core] x86: hyperv: Fix brown paperbag typos reported by Fenguangs build robot

2014-03-04 Thread tip-bot for Thomas Gleixner
Commit-ID:  13b5be56d1c5ed302df53f6dfbe19b9f4e3fd3ce
Gitweb: http://git.kernel.org/tip/13b5be56d1c5ed302df53f6dfbe19b9f4e3fd3ce
Author: Thomas Gleixner 
AuthorDate: Tue, 4 Mar 2014 23:51:34 +0100
Committer:  Thomas Gleixner 
CommitDate: Tue, 4 Mar 2014 23:53:33 +0100

x86: hyperv: Fix brown paperbag typos reported by Fenguangs build robot

Reported-by: fengguang...@intel.com
Signed-off-by: Thomas Gleixner 
Cc: K. Y. Srinivasan 
Cc: Peter Zijlstra 
Cc: Greg Kroah-Hartman 
Cc: linuxdrivers 
Cc: x86 
---
 arch/x86/kernel/cpu/mshyperv.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 316e106..a6f5f35 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -32,7 +32,7 @@ struct ms_hyperv_info ms_hyperv;
 EXPORT_SYMBOL_GPL(ms_hyperv);
 
 #if IS_ENABLED(CONFIG_HYPERV)
-static irq_handler_t *vmbus_handler;
+static irq_handler_t vmbus_handler;
 
 void hyperv_vector_handler(struct pt_regs *regs)
 {
@@ -49,7 +49,7 @@ void hyperv_vector_handler(struct pt_regs *regs)
set_irq_regs(old_regs);
 }
 
-int hv_setup_vmbus_irq(int irq, irq_handler_t *handler, void *dev_id)
+int hv_setup_vmbus_irq(int irq, irq_handler_t handler, void *dev_id)
 {
vmbus_handler = handler;
/*
@@ -61,7 +61,7 @@ int hv_setup_vmbus_irq(int irq, irq_handler_t *handler, void 
*dev_id)
hyperv_callback_vector);
 }
 
-void hv_remove_vmbus_irq(unsigned int irq, void *dev_id)
+void hv_remove_vmbus_irq(int irq, void *dev_id)
 {
/* We have no way to deallocate the interrupt gate */
vmbus_handler = NULL;
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel