[tip:x86/pti] selftests/x86/mpx: Fix incorrect bounds with old _sigfault

2018-02-14 Thread tip-bot for Rui Wang
Commit-ID:  961888b1d76d84efc66a8f5604b06ac12ac2f978
Gitweb: https://git.kernel.org/tip/961888b1d76d84efc66a8f5604b06ac12ac2f978
Author: Rui Wang <rui.y.w...@intel.com>
AuthorDate: Mon, 18 Dec 2017 16:34:10 +0800
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Thu, 15 Feb 2018 01:15:52 +0100

selftests/x86/mpx: Fix incorrect bounds with old _sigfault

For distributions with old userspace header files, the _sigfault
structure is different. mpx-mini-test fails with the following
error:

  [root@Purley]# mpx-mini-test_64 tabletest
  XSAVE is supported by HW & OS
  XSAVE processor supported state mask: 0x2ff
  XSAVE OS supported state mask: 0x2ff
   BNDREGS: size: 64 user: 1 supervisor: 0 aligned: 0
BNDCSR: size: 64 user: 1 supervisor: 0 aligned: 0
  starting mpx bounds table test
  ERROR: siginfo bounds do not match shadow bounds for register 0

Fix it by using the correct offset of _lower/_upper in _sigfault.
RHEL needs this patch to work.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: dave.han...@linux.intel.com
Fixes: e754aedc26ef ("x86/mpx, selftests: Add MPX self test")
Link: 
http://lkml.kernel.org/r/1513586050-1641-1-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 tools/testing/selftests/x86/mpx-mini-test.c | 32 +++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/x86/mpx-mini-test.c 
b/tools/testing/selftests/x86/mpx-mini-test.c
index ec0f6b4..9c0325e 100644
--- a/tools/testing/selftests/x86/mpx-mini-test.c
+++ b/tools/testing/selftests/x86/mpx-mini-test.c
@@ -315,11 +315,39 @@ static inline void *__si_bounds_upper(siginfo_t *si)
return si->si_upper;
 }
 #else
+
+/*
+ * This deals with old version of _sigfault in some distros:
+ *
+
+old _sigfault:
+struct {
+void *si_addr;
+   } _sigfault;
+
+new _sigfault:
+   struct {
+   void __user *_addr;
+   int _trapno;
+   short _addr_lsb;
+   union {
+   struct {
+   void __user *_lower;
+   void __user *_upper;
+   } _addr_bnd;
+   __u32 _pkey;
+   };
+   } _sigfault;
+ *
+ */
+
 static inline void **__si_bounds_hack(siginfo_t *si)
 {
void *sigfault = >_sifields._sigfault;
void *end_sigfault = sigfault + sizeof(si->_sifields._sigfault);
-   void **__si_lower = end_sigfault;
+   int *trapno = (int*)end_sigfault;
+   /* skip _trapno and _addr_lsb */
+   void **__si_lower = (void**)(trapno + 2);
 
return __si_lower;
 }
@@ -331,7 +359,7 @@ static inline void *__si_bounds_lower(siginfo_t *si)
 
 static inline void *__si_bounds_upper(siginfo_t *si)
 {
-   return (*__si_bounds_hack(si)) + sizeof(void *);
+   return *(__si_bounds_hack(si) + 1);
 }
 #endif
 


[tip:x86/pti] selftests/x86/mpx: Fix incorrect bounds with old _sigfault

2018-02-14 Thread tip-bot for Rui Wang
Commit-ID:  961888b1d76d84efc66a8f5604b06ac12ac2f978
Gitweb: https://git.kernel.org/tip/961888b1d76d84efc66a8f5604b06ac12ac2f978
Author: Rui Wang 
AuthorDate: Mon, 18 Dec 2017 16:34:10 +0800
Committer:  Ingo Molnar 
CommitDate: Thu, 15 Feb 2018 01:15:52 +0100

selftests/x86/mpx: Fix incorrect bounds with old _sigfault

For distributions with old userspace header files, the _sigfault
structure is different. mpx-mini-test fails with the following
error:

  [root@Purley]# mpx-mini-test_64 tabletest
  XSAVE is supported by HW & OS
  XSAVE processor supported state mask: 0x2ff
  XSAVE OS supported state mask: 0x2ff
   BNDREGS: size: 64 user: 1 supervisor: 0 aligned: 0
BNDCSR: size: 64 user: 1 supervisor: 0 aligned: 0
  starting mpx bounds table test
  ERROR: siginfo bounds do not match shadow bounds for register 0

Fix it by using the correct offset of _lower/_upper in _sigfault.
RHEL needs this patch to work.

Signed-off-by: Rui Wang 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: dave.han...@linux.intel.com
Fixes: e754aedc26ef ("x86/mpx, selftests: Add MPX self test")
Link: 
http://lkml.kernel.org/r/1513586050-1641-1-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar 
---
 tools/testing/selftests/x86/mpx-mini-test.c | 32 +++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/x86/mpx-mini-test.c 
b/tools/testing/selftests/x86/mpx-mini-test.c
index ec0f6b4..9c0325e 100644
--- a/tools/testing/selftests/x86/mpx-mini-test.c
+++ b/tools/testing/selftests/x86/mpx-mini-test.c
@@ -315,11 +315,39 @@ static inline void *__si_bounds_upper(siginfo_t *si)
return si->si_upper;
 }
 #else
+
+/*
+ * This deals with old version of _sigfault in some distros:
+ *
+
+old _sigfault:
+struct {
+void *si_addr;
+   } _sigfault;
+
+new _sigfault:
+   struct {
+   void __user *_addr;
+   int _trapno;
+   short _addr_lsb;
+   union {
+   struct {
+   void __user *_lower;
+   void __user *_upper;
+   } _addr_bnd;
+   __u32 _pkey;
+   };
+   } _sigfault;
+ *
+ */
+
 static inline void **__si_bounds_hack(siginfo_t *si)
 {
void *sigfault = >_sifields._sigfault;
void *end_sigfault = sigfault + sizeof(si->_sifields._sigfault);
-   void **__si_lower = end_sigfault;
+   int *trapno = (int*)end_sigfault;
+   /* skip _trapno and _addr_lsb */
+   void **__si_lower = (void**)(trapno + 2);
 
return __si_lower;
 }
@@ -331,7 +359,7 @@ static inline void *__si_bounds_lower(siginfo_t *si)
 
 static inline void *__si_bounds_upper(siginfo_t *si)
 {
-   return (*__si_bounds_hack(si)) + sizeof(void *);
+   return *(__si_bounds_hack(si) + 1);
 }
 #endif
 


[tip:x86/pti] selftests/x86/mpx: Fix incorrect bounds with old _sigfault

2018-02-13 Thread tip-bot for Rui Wang
Commit-ID:  d101567aec6653cc372af3b9b957299fee06cca8
Gitweb: https://git.kernel.org/tip/d101567aec6653cc372af3b9b957299fee06cca8
Author: Rui Wang <rui.y.w...@intel.com>
AuthorDate: Mon, 18 Dec 2017 16:34:10 +0800
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Tue, 13 Feb 2018 19:20:05 +0100

selftests/x86/mpx: Fix incorrect bounds with old _sigfault

For distributions with old userspace header files, the _sigfault
structure is different. mpx-mini-test fails with the following
error:

  [root@Purley]# mpx-mini-test_64 tabletest
  XSAVE is supported by HW & OS
  XSAVE processor supported state mask: 0x2ff
  XSAVE OS supported state mask: 0x2ff
   BNDREGS: size: 64 user: 1 supervisor: 0 aligned: 0
BNDCSR: size: 64 user: 1 supervisor: 0 aligned: 0
  starting mpx bounds table test
  ERROR: siginfo bounds do not match shadow bounds for register 0

Fix it by using the correct offset of _lower/_upper in _sigfault.
RHEL needs this patch to work.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: dave.han...@linux.intel.com
Fixes: e754aedc26ef ("x86/mpx, selftests: Add MPX self test")
Link: 
http://lkml.kernel.org/r/1513586050-1641-1-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 tools/testing/selftests/x86/mpx-mini-test.c | 32 +++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/x86/mpx-mini-test.c 
b/tools/testing/selftests/x86/mpx-mini-test.c
index ec0f6b4..9c0325e 100644
--- a/tools/testing/selftests/x86/mpx-mini-test.c
+++ b/tools/testing/selftests/x86/mpx-mini-test.c
@@ -315,11 +315,39 @@ static inline void *__si_bounds_upper(siginfo_t *si)
return si->si_upper;
 }
 #else
+
+/*
+ * This deals with old version of _sigfault in some distros:
+ *
+
+old _sigfault:
+struct {
+void *si_addr;
+   } _sigfault;
+
+new _sigfault:
+   struct {
+   void __user *_addr;
+   int _trapno;
+   short _addr_lsb;
+   union {
+   struct {
+   void __user *_lower;
+   void __user *_upper;
+   } _addr_bnd;
+   __u32 _pkey;
+   };
+   } _sigfault;
+ *
+ */
+
 static inline void **__si_bounds_hack(siginfo_t *si)
 {
void *sigfault = >_sifields._sigfault;
void *end_sigfault = sigfault + sizeof(si->_sifields._sigfault);
-   void **__si_lower = end_sigfault;
+   int *trapno = (int*)end_sigfault;
+   /* skip _trapno and _addr_lsb */
+   void **__si_lower = (void**)(trapno + 2);
 
return __si_lower;
 }
@@ -331,7 +359,7 @@ static inline void *__si_bounds_lower(siginfo_t *si)
 
 static inline void *__si_bounds_upper(siginfo_t *si)
 {
-   return (*__si_bounds_hack(si)) + sizeof(void *);
+   return *(__si_bounds_hack(si) + 1);
 }
 #endif
 


[tip:x86/pti] selftests/x86/mpx: Fix incorrect bounds with old _sigfault

2018-02-13 Thread tip-bot for Rui Wang
Commit-ID:  d101567aec6653cc372af3b9b957299fee06cca8
Gitweb: https://git.kernel.org/tip/d101567aec6653cc372af3b9b957299fee06cca8
Author: Rui Wang 
AuthorDate: Mon, 18 Dec 2017 16:34:10 +0800
Committer:  Ingo Molnar 
CommitDate: Tue, 13 Feb 2018 19:20:05 +0100

selftests/x86/mpx: Fix incorrect bounds with old _sigfault

For distributions with old userspace header files, the _sigfault
structure is different. mpx-mini-test fails with the following
error:

  [root@Purley]# mpx-mini-test_64 tabletest
  XSAVE is supported by HW & OS
  XSAVE processor supported state mask: 0x2ff
  XSAVE OS supported state mask: 0x2ff
   BNDREGS: size: 64 user: 1 supervisor: 0 aligned: 0
BNDCSR: size: 64 user: 1 supervisor: 0 aligned: 0
  starting mpx bounds table test
  ERROR: siginfo bounds do not match shadow bounds for register 0

Fix it by using the correct offset of _lower/_upper in _sigfault.
RHEL needs this patch to work.

Signed-off-by: Rui Wang 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: dave.han...@linux.intel.com
Fixes: e754aedc26ef ("x86/mpx, selftests: Add MPX self test")
Link: 
http://lkml.kernel.org/r/1513586050-1641-1-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar 
---
 tools/testing/selftests/x86/mpx-mini-test.c | 32 +++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/x86/mpx-mini-test.c 
b/tools/testing/selftests/x86/mpx-mini-test.c
index ec0f6b4..9c0325e 100644
--- a/tools/testing/selftests/x86/mpx-mini-test.c
+++ b/tools/testing/selftests/x86/mpx-mini-test.c
@@ -315,11 +315,39 @@ static inline void *__si_bounds_upper(siginfo_t *si)
return si->si_upper;
 }
 #else
+
+/*
+ * This deals with old version of _sigfault in some distros:
+ *
+
+old _sigfault:
+struct {
+void *si_addr;
+   } _sigfault;
+
+new _sigfault:
+   struct {
+   void __user *_addr;
+   int _trapno;
+   short _addr_lsb;
+   union {
+   struct {
+   void __user *_lower;
+   void __user *_upper;
+   } _addr_bnd;
+   __u32 _pkey;
+   };
+   } _sigfault;
+ *
+ */
+
 static inline void **__si_bounds_hack(siginfo_t *si)
 {
void *sigfault = >_sifields._sigfault;
void *end_sigfault = sigfault + sizeof(si->_sifields._sigfault);
-   void **__si_lower = end_sigfault;
+   int *trapno = (int*)end_sigfault;
+   /* skip _trapno and _addr_lsb */
+   void **__si_lower = (void**)(trapno + 2);
 
return __si_lower;
 }
@@ -331,7 +359,7 @@ static inline void *__si_bounds_lower(siginfo_t *si)
 
 static inline void *__si_bounds_upper(siginfo_t *si)
 {
-   return (*__si_bounds_hack(si)) + sizeof(void *);
+   return *(__si_bounds_hack(si) + 1);
 }
 #endif
 


[PATCH] x86/mpx/selftests: Fix wrong bounds with old _sigfault

2017-12-18 Thread Rui Wang
I fixed this on my machine and forgot to tell anyone until a
recent bug report. The patch almost get lost. Archiving it here.

For distributions with old userspace header files, the _sigfault
structure is different. mpx-mini-test fails with the following
error:

[root@Purley]# mpx-mini-test_64 tabletest
XSAVE is supported by HW & OS
XSAVE processor supported state mask: 0x2ff
XSAVE OS supported state mask: 0x2ff
 BNDREGS: size: 64 user: 1 supervisor: 0 aligned: 0
  BNDCSR: size: 64 user: 1 supervisor: 0 aligned: 0
starting mpx bounds table test
ERROR: siginfo bounds do not match shadow bounds for register 0

Fix it by using the correct offset of _lower/_upper in _sigfault.
RHEL needs this patch to work.

Fixes: e754aedc26ef ("x86/mpx, selftests: Add MPX self test")
Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 tools/testing/selftests/x86/mpx-mini-test.c |   27 +--
 1 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/x86/mpx-mini-test.c 
b/tools/testing/selftests/x86/mpx-mini-test.c
index ec0f6b4..45035c3 100644
--- a/tools/testing/selftests/x86/mpx-mini-test.c
+++ b/tools/testing/selftests/x86/mpx-mini-test.c
@@ -315,11 +315,34 @@ static uint64_t read_mpx_status_sig(ucontext_t *uctxt)
return si->si_upper;
 }
 #else
+
+/* This deals with old version of _sigfault in some distros
+old _sigfault:
+struct {
+void *si_addr;
+   } _sigfault;
+
+new _sigfault:
+   struct {
+   void __user *_addr;
+   int _trapno;
+   short _addr_lsb;
+   union {
+   struct {
+   void __user *_lower;
+   void __user *_upper;
+   } _addr_bnd;
+   __u32 _pkey;
+   };
+   } _sigfault;
+*/
 static inline void **__si_bounds_hack(siginfo_t *si)
 {
void *sigfault = >_sifields._sigfault;
void *end_sigfault = sigfault + sizeof(si->_sifields._sigfault);
-   void **__si_lower = end_sigfault;
+   int *trapno = (int*)end_sigfault;
+   /* skip _trapno and _addr_lsb */
+   void **__si_lower = (void**)(trapno + 2);
 
return __si_lower;
 }
@@ -331,7 +354,7 @@ static uint64_t read_mpx_status_sig(ucontext_t *uctxt)
 
 static inline void *__si_bounds_upper(siginfo_t *si)
 {
-   return (*__si_bounds_hack(si)) + sizeof(void *);
+   return *(__si_bounds_hack(si) + 1);
 }
 #endif
 
-- 
1.7.5.4



[PATCH] x86/mpx/selftests: Fix wrong bounds with old _sigfault

2017-12-18 Thread Rui Wang
I fixed this on my machine and forgot to tell anyone until a
recent bug report. The patch almost get lost. Archiving it here.

For distributions with old userspace header files, the _sigfault
structure is different. mpx-mini-test fails with the following
error:

[root@Purley]# mpx-mini-test_64 tabletest
XSAVE is supported by HW & OS
XSAVE processor supported state mask: 0x2ff
XSAVE OS supported state mask: 0x2ff
 BNDREGS: size: 64 user: 1 supervisor: 0 aligned: 0
  BNDCSR: size: 64 user: 1 supervisor: 0 aligned: 0
starting mpx bounds table test
ERROR: siginfo bounds do not match shadow bounds for register 0

Fix it by using the correct offset of _lower/_upper in _sigfault.
RHEL needs this patch to work.

Fixes: e754aedc26ef ("x86/mpx, selftests: Add MPX self test")
Signed-off-by: Rui Wang 
---
 tools/testing/selftests/x86/mpx-mini-test.c |   27 +--
 1 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/x86/mpx-mini-test.c 
b/tools/testing/selftests/x86/mpx-mini-test.c
index ec0f6b4..45035c3 100644
--- a/tools/testing/selftests/x86/mpx-mini-test.c
+++ b/tools/testing/selftests/x86/mpx-mini-test.c
@@ -315,11 +315,34 @@ static uint64_t read_mpx_status_sig(ucontext_t *uctxt)
return si->si_upper;
 }
 #else
+
+/* This deals with old version of _sigfault in some distros
+old _sigfault:
+struct {
+void *si_addr;
+   } _sigfault;
+
+new _sigfault:
+   struct {
+   void __user *_addr;
+   int _trapno;
+   short _addr_lsb;
+   union {
+   struct {
+   void __user *_lower;
+   void __user *_upper;
+   } _addr_bnd;
+   __u32 _pkey;
+   };
+   } _sigfault;
+*/
 static inline void **__si_bounds_hack(siginfo_t *si)
 {
void *sigfault = >_sifields._sigfault;
void *end_sigfault = sigfault + sizeof(si->_sifields._sigfault);
-   void **__si_lower = end_sigfault;
+   int *trapno = (int*)end_sigfault;
+   /* skip _trapno and _addr_lsb */
+   void **__si_lower = (void**)(trapno + 2);
 
return __si_lower;
 }
@@ -331,7 +354,7 @@ static uint64_t read_mpx_status_sig(ucontext_t *uctxt)
 
 static inline void *__si_bounds_upper(siginfo_t *si)
 {
-   return (*__si_bounds_hack(si)) + sizeof(void *);
+   return *(__si_bounds_hack(si) + 1);
 }
 #endif
 
-- 
1.7.5.4



[tip:x86/urgent] x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC

2017-03-01 Thread tip-bot for Rui Wang
Commit-ID:  153654dbe595a68845ba14d5b0bfe299fa6a7e99
Gitweb: http://git.kernel.org/tip/153654dbe595a68845ba14d5b0bfe299fa6a7e99
Author: Rui Wang <rui.y.w...@intel.com>
AuthorDate: Tue, 28 Feb 2017 21:34:28 +0800
Committer:  Thomas Gleixner <t...@linutronix.de>
CommitDate: Wed, 1 Mar 2017 10:51:41 +0100

x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC

The revert of 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq()
and pcibios_free_irq()") causes a problem for IOAPIC hotplug. The
problem is that IRQs are allocated and freed in pci_enable_device()
and pci_disable_device(). But there are some drivers which don't call
pci_disable_device(), and they have good reasons not calling it, so
if they're using IOAPIC their IRQs won't have a chance to be released
from the IOAPIC. When this happens IOAPIC hot-removal fails with a
kernel stack dump and an error message like this:

  [149335.697989] pin16 on IOAPIC2 is still in use.

It turns out that we can fix it in a different way without moving IRQ
allocation into pcibios_alloc_irq(), thus avoiding the regression of
991de2e59090. We can keep the allocation and freeing of IRQs as is
within pci_enable_device()/pci_disable_device(), without breaking any
previous assumption of the rest of the system, keeping compatibility
with both the legacy and the modern drivers. We can accomplish this by
implementing the existing __weak hook of pcibios_release_device() thus
when a pci device is about to be deleted we get notified in the hook
and take the chance to release its IRQ, if any, from the IOAPIC.

Implement pcibios_release_device() for x86 to release any IRQ not released
by the driver.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
Cc: tony.l...@intel.com
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: linux-a...@vger.kernel.org
Cc: fengguang...@intel.com
Cc: helg...@kernel.org
Cc: kbuild-...@01.org
Cc: bhelg...@google.com
Link: 
http://lkml.kernel.org/r/1488288869-31290-2-git-send-email-rui.y.w...@intel.com
Signed-off-by: Thomas Gleixner <t...@linutronix.de>

---
 arch/x86/pci/common.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 0cb52ae..190e718 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -735,6 +735,15 @@ void pcibios_disable_device (struct pci_dev *dev)
pcibios_disable_irq(dev);
 }
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pcibios_release_device(struct pci_dev *dev)
+{
+   if (atomic_dec_return(>enable_cnt) >= 0)
+   pcibios_disable_device(dev);
+
+}
+#endif
+
 int pci_ext_cfg_avail(void)
 {
if (raw_pci_ext_ops)


[tip:x86/urgent] x86/ioapic: Split IOAPIC hot-removal into two steps

2017-03-01 Thread tip-bot for Rui Wang
Commit-ID:  f2ae5da726172fcf82f7be801489dd585f6a38eb
Gitweb: http://git.kernel.org/tip/f2ae5da726172fcf82f7be801489dd585f6a38eb
Author: Rui Wang <rui.y.w...@intel.com>
AuthorDate: Tue, 28 Feb 2017 21:34:29 +0800
Committer:  Thomas Gleixner <t...@linutronix.de>
CommitDate: Wed, 1 Mar 2017 10:51:41 +0100

x86/ioapic: Split IOAPIC hot-removal into two steps

The hot removal of IOAPIC is handling PCI and ACPI removal in one go. That
only works when the PCI drivers released the interrupt resources, but
breaks when a IOAPIC interrupt is still associated to a PCI device.

The new pcibios_release_device() callback allows to solve that problem by
splitting the removal into two steps:

1) PCI removal:

   Release all PCI resources including eventually not yet released IOAPIC
   interrupts via the new pcibios_release_device() callback.

2) ACPI removal:

   After release of all PCI resources the ACPI resources can be released
   without issue.

[ tglx: Rewrote changelog ]

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
Cc: tony.l...@intel.com
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: linux-a...@vger.kernel.org
Cc: fengguang...@intel.com
Cc: helg...@kernel.org
Cc: kbuild-...@01.org
Cc: bhelg...@google.com
Link: 
http://lkml.kernel.org/r/1488288869-31290-3-git-send-email-rui.y.w...@intel.com
Signed-off-by: Thomas Gleixner <t...@linutronix.de>

---
 drivers/acpi/internal.h |  2 ++
 drivers/acpi/ioapic.c   | 22 --
 drivers/acpi/pci_root.c |  4 ++--
 3 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 219b90b..f159001 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -41,8 +41,10 @@ void acpi_gpe_apply_masked_gpes(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pci_ioapic_remove(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
+static inline void pci_ioapic_remove(struct acpi_pci_root *root) { return; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 6d7ce6e..1120dfd6 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -206,24 +206,34 @@ int acpi_ioapic_add(acpi_handle root_handle)
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
 
-int acpi_ioapic_remove(struct acpi_pci_root *root)
+void pci_ioapic_remove(struct acpi_pci_root *root)
 {
-   int retval = 0;
struct acpi_pci_ioapic *ioapic, *tmp;
 
mutex_lock(_list_lock);
list_for_each_entry_safe(ioapic, tmp, _list, list) {
if (root->device->handle != ioapic->root_handle)
continue;
-
-   if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
-   retval = -EBUSY;
-
if (ioapic->pdev) {
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
}
+   }
+   mutex_unlock(_list_lock);
+}
+
+int acpi_ioapic_remove(struct acpi_pci_root *root)
+{
+   int retval = 0;
+   struct acpi_pci_ioapic *ioapic, *tmp;
+
+   mutex_lock(_list_lock);
+   list_for_each_entry_safe(ioapic, tmp, _list, list) {
+   if (root->device->handle != ioapic->root_handle)
+   continue;
+   if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
+   retval = -EBUSY;
if (ioapic->res.flags && ioapic->res.parent)
release_resource(>res);
list_del(>list);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index bf601d4..919be0a 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -648,12 +648,12 @@ static void acpi_pci_root_remove(struct acpi_device 
*device)
 
pci_stop_root_bus(root->bus);
 
-   WARN_ON(acpi_ioapic_remove(root));
-
+   pci_ioapic_remove(root);
device_set_run_wake(root->bus->bridge, false);
pci_acpi_remove_bus_pm_notifier(device);
 
pci_remove_root_bus(root->bus);
+   WARN_ON(acpi_ioapic_remove(root));
 
dmar_device_remove(device->handle);
 


[tip:x86/urgent] x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC

2017-03-01 Thread tip-bot for Rui Wang
Commit-ID:  153654dbe595a68845ba14d5b0bfe299fa6a7e99
Gitweb: http://git.kernel.org/tip/153654dbe595a68845ba14d5b0bfe299fa6a7e99
Author: Rui Wang 
AuthorDate: Tue, 28 Feb 2017 21:34:28 +0800
Committer:  Thomas Gleixner 
CommitDate: Wed, 1 Mar 2017 10:51:41 +0100

x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC

The revert of 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq()
and pcibios_free_irq()") causes a problem for IOAPIC hotplug. The
problem is that IRQs are allocated and freed in pci_enable_device()
and pci_disable_device(). But there are some drivers which don't call
pci_disable_device(), and they have good reasons not calling it, so
if they're using IOAPIC their IRQs won't have a chance to be released
from the IOAPIC. When this happens IOAPIC hot-removal fails with a
kernel stack dump and an error message like this:

  [149335.697989] pin16 on IOAPIC2 is still in use.

It turns out that we can fix it in a different way without moving IRQ
allocation into pcibios_alloc_irq(), thus avoiding the regression of
991de2e59090. We can keep the allocation and freeing of IRQs as is
within pci_enable_device()/pci_disable_device(), without breaking any
previous assumption of the rest of the system, keeping compatibility
with both the legacy and the modern drivers. We can accomplish this by
implementing the existing __weak hook of pcibios_release_device() thus
when a pci device is about to be deleted we get notified in the hook
and take the chance to release its IRQ, if any, from the IOAPIC.

Implement pcibios_release_device() for x86 to release any IRQ not released
by the driver.

Signed-off-by: Rui Wang 
Cc: tony.l...@intel.com
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: linux-a...@vger.kernel.org
Cc: fengguang...@intel.com
Cc: helg...@kernel.org
Cc: kbuild-...@01.org
Cc: bhelg...@google.com
Link: 
http://lkml.kernel.org/r/1488288869-31290-2-git-send-email-rui.y.w...@intel.com
Signed-off-by: Thomas Gleixner 

---
 arch/x86/pci/common.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 0cb52ae..190e718 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -735,6 +735,15 @@ void pcibios_disable_device (struct pci_dev *dev)
pcibios_disable_irq(dev);
 }
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pcibios_release_device(struct pci_dev *dev)
+{
+   if (atomic_dec_return(>enable_cnt) >= 0)
+   pcibios_disable_device(dev);
+
+}
+#endif
+
 int pci_ext_cfg_avail(void)
 {
if (raw_pci_ext_ops)


[tip:x86/urgent] x86/ioapic: Split IOAPIC hot-removal into two steps

2017-03-01 Thread tip-bot for Rui Wang
Commit-ID:  f2ae5da726172fcf82f7be801489dd585f6a38eb
Gitweb: http://git.kernel.org/tip/f2ae5da726172fcf82f7be801489dd585f6a38eb
Author: Rui Wang 
AuthorDate: Tue, 28 Feb 2017 21:34:29 +0800
Committer:  Thomas Gleixner 
CommitDate: Wed, 1 Mar 2017 10:51:41 +0100

x86/ioapic: Split IOAPIC hot-removal into two steps

The hot removal of IOAPIC is handling PCI and ACPI removal in one go. That
only works when the PCI drivers released the interrupt resources, but
breaks when a IOAPIC interrupt is still associated to a PCI device.

The new pcibios_release_device() callback allows to solve that problem by
splitting the removal into two steps:

1) PCI removal:

   Release all PCI resources including eventually not yet released IOAPIC
   interrupts via the new pcibios_release_device() callback.

2) ACPI removal:

   After release of all PCI resources the ACPI resources can be released
   without issue.

[ tglx: Rewrote changelog ]

Signed-off-by: Rui Wang 
Cc: tony.l...@intel.com
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: linux-a...@vger.kernel.org
Cc: fengguang...@intel.com
Cc: helg...@kernel.org
Cc: kbuild-...@01.org
Cc: bhelg...@google.com
Link: 
http://lkml.kernel.org/r/1488288869-31290-3-git-send-email-rui.y.w...@intel.com
Signed-off-by: Thomas Gleixner 

---
 drivers/acpi/internal.h |  2 ++
 drivers/acpi/ioapic.c   | 22 --
 drivers/acpi/pci_root.c |  4 ++--
 3 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 219b90b..f159001 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -41,8 +41,10 @@ void acpi_gpe_apply_masked_gpes(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pci_ioapic_remove(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
+static inline void pci_ioapic_remove(struct acpi_pci_root *root) { return; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 6d7ce6e..1120dfd6 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -206,24 +206,34 @@ int acpi_ioapic_add(acpi_handle root_handle)
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
 
-int acpi_ioapic_remove(struct acpi_pci_root *root)
+void pci_ioapic_remove(struct acpi_pci_root *root)
 {
-   int retval = 0;
struct acpi_pci_ioapic *ioapic, *tmp;
 
mutex_lock(_list_lock);
list_for_each_entry_safe(ioapic, tmp, _list, list) {
if (root->device->handle != ioapic->root_handle)
continue;
-
-   if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
-   retval = -EBUSY;
-
if (ioapic->pdev) {
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
}
+   }
+   mutex_unlock(_list_lock);
+}
+
+int acpi_ioapic_remove(struct acpi_pci_root *root)
+{
+   int retval = 0;
+   struct acpi_pci_ioapic *ioapic, *tmp;
+
+   mutex_lock(_list_lock);
+   list_for_each_entry_safe(ioapic, tmp, _list, list) {
+   if (root->device->handle != ioapic->root_handle)
+   continue;
+   if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
+   retval = -EBUSY;
if (ioapic->res.flags && ioapic->res.parent)
release_resource(>res);
list_del(>list);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index bf601d4..919be0a 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -648,12 +648,12 @@ static void acpi_pci_root_remove(struct acpi_device 
*device)
 
pci_stop_root_bus(root->bus);
 
-   WARN_ON(acpi_ioapic_remove(root));
-
+   pci_ioapic_remove(root);
device_set_run_wake(root->bus->bridge, false);
pci_acpi_remove_bus_pm_notifier(device);
 
pci_remove_root_bus(root->bus);
+   WARN_ON(acpi_ioapic_remove(root));
 
dmar_device_remove(device->handle);
 


[PATCH v2 2/2] x86/ioapic: Split IOAPIC hot-removal into two steps

2017-02-28 Thread Rui Wang
The hot-removal of IOAPIC is broken into two parts: the PCI part and
the ACPI part. The PCI part releases PCI resources before the PCI bus
is gone, and the ACPI part is moved to a stage later than the hot-removal
of the PCI root bus, so that the IOAPIC driver is able to hook the
pcibios_release_device() of every PCI device under the same parent root
bus, before the IOAPIC is hot-removed. This makes it possible for the
IOAPIC to free any IRQ resource previously unable to get freed.

v2: Fixed compiling error on i386 (missing stub of pci_ioapic_remove())

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/internal.h |  2 ++
 drivers/acpi/ioapic.c   | 22 --
 drivers/acpi/pci_root.c |  4 ++--
 3 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 219b90b..f159001 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -41,8 +41,10 @@ static inline void acpi_amba_init(void) {}
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pci_ioapic_remove(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
+static inline void pci_ioapic_remove(struct acpi_pci_root *root) { return; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 6d7ce6e..1120dfd6 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -206,24 +206,34 @@ int acpi_ioapic_add(acpi_handle root_handle)
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
 
-int acpi_ioapic_remove(struct acpi_pci_root *root)
+void pci_ioapic_remove(struct acpi_pci_root *root)
 {
-   int retval = 0;
struct acpi_pci_ioapic *ioapic, *tmp;
 
mutex_lock(_list_lock);
list_for_each_entry_safe(ioapic, tmp, _list, list) {
if (root->device->handle != ioapic->root_handle)
continue;
-
-   if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
-   retval = -EBUSY;
-
if (ioapic->pdev) {
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
}
+   }
+   mutex_unlock(_list_lock);
+}
+
+int acpi_ioapic_remove(struct acpi_pci_root *root)
+{
+   int retval = 0;
+   struct acpi_pci_ioapic *ioapic, *tmp;
+
+   mutex_lock(_list_lock);
+   list_for_each_entry_safe(ioapic, tmp, _list, list) {
+   if (root->device->handle != ioapic->root_handle)
+   continue;
+   if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
+   retval = -EBUSY;
if (ioapic->res.flags && ioapic->res.parent)
release_resource(>res);
list_del(>list);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index bf601d4..919be0a 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -648,12 +648,12 @@ static void acpi_pci_root_remove(struct acpi_device 
*device)
 
pci_stop_root_bus(root->bus);
 
-   WARN_ON(acpi_ioapic_remove(root));
-
+   pci_ioapic_remove(root);
device_set_run_wake(root->bus->bridge, false);
pci_acpi_remove_bus_pm_notifier(device);
 
pci_remove_root_bus(root->bus);
+   WARN_ON(acpi_ioapic_remove(root));
 
dmar_device_remove(device->handle);
 
-- 
1.8.3.1



[PATCH v2 1/2] x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC

2017-02-28 Thread Rui Wang
The revert of 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq()
and pcibios_free_irq()") causes a problem for IOAPIC hotplug. The
problem is that IRQs are allocated and freed in pci_enable_device()
and pci_disable_device(). But there are some drivers which don't call
pci_disable_device(), and they have good reasons not calling it, so
if they're using IOAPIC their IRQs won't have a chance to be released
from the IOAPIC. When this happens IOAPIC hot-removal fails with a
kernel stack dump and an error message like this:

[149335.697989] pin16 on IOAPIC2 is still in use.

It turns out that we can fix it in a different way without moving IRQ
allocation into pcibios_alloc_irq(), thus avoiding the regression of
991de2e59090. We can keep the allocation and freeing of IRQs as is
within pci_enable_device()/pci_disable_device(), without breaking any
previous assumption of the rest of the system, keeping compatibility
with both the legacy and the modern drivers. We can accomplish this by
implementing the existing __weak hook of pcibios_release_device() thus
when a pci device is about to be deleted we get notified in the hook
and take the chance to release its IRQ, if any, from the IOAPIC.

Besides implementing pcibios_release_device(), the hot-removal of
IOAPIC needs to be broken into two parts: the PCI part and the ACPI
part. The PCI part releases PCI resources before the PCI bus is gone,
and the ACPI part is moved to a stage later than the hot-removal of
the PCI root bus, so we have the chance to hook every PCI device's
pcibios_release_device(), before we remove the IOAPIC.

This patch implements pcibios_release_device() on x86 to release any
IRQ not released by the driver, so that the IOAPIC can then be safely
hot-removed.

v2: Fixed a typo (pcibios_release_device)

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 arch/x86/pci/common.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 0cb52ae..190e718 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -735,6 +735,15 @@ void pcibios_disable_device (struct pci_dev *dev)
pcibios_disable_irq(dev);
 }
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pcibios_release_device(struct pci_dev *dev)
+{
+   if (atomic_dec_return(>enable_cnt) >= 0)
+   pcibios_disable_device(dev);
+
+}
+#endif
+
 int pci_ext_cfg_avail(void)
 {
if (raw_pci_ext_ops)
-- 
1.8.3.1



[PATCH v2 0/2] Improvement on ioapic hotplug

2017-02-28 Thread Rui Wang
The revert of 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq()
and pcibios_free_irq()") causes a problem for IOAPIC hotplug. If
a device under the IOAPIC doesn't call pci_disable_device(), then
the hot-removal of the IOAPIC causes kernel stack dump.

This patchset can fix the problem. IOAPIC hot-removal works correctly
after applying this patchset.

v2: 0001 Fixed a missing stub function causing compiling error on i386 
0002 Fixed a typo on the subject line.

Rui Wang (2):
  x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC
  x86/ioapic: Split IOAPIC hot-removal into two steps

 arch/x86/pci/common.c   |  9 +
 drivers/acpi/internal.h |  2 ++
 drivers/acpi/ioapic.c   | 22 --
 drivers/acpi/pci_root.c |  4 ++--
 4 files changed, 29 insertions(+), 8 deletions(-)

-- 
1.8.3.1



[PATCH v2 0/2] Improvement on ioapic hotplug

2017-02-28 Thread Rui Wang
The revert of 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq()
and pcibios_free_irq()") causes a problem for IOAPIC hotplug. If
a device under the IOAPIC doesn't call pci_disable_device(), then
the hot-removal of the IOAPIC causes kernel stack dump.

This patchset can fix the problem. IOAPIC hot-removal works correctly
after applying this patchset.

v2: 0001 Fixed a missing stub function causing compiling error on i386 
0002 Fixed a typo on the subject line.

Rui Wang (2):
  x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC
  x86/ioapic: Split IOAPIC hot-removal into two steps

 arch/x86/pci/common.c   |  9 +
 drivers/acpi/internal.h |  2 ++
 drivers/acpi/ioapic.c   | 22 --
 drivers/acpi/pci_root.c |  4 ++--
 4 files changed, 29 insertions(+), 8 deletions(-)

-- 
1.8.3.1



[PATCH v2 2/2] x86/ioapic: Split IOAPIC hot-removal into two steps

2017-02-28 Thread Rui Wang
The hot-removal of IOAPIC is broken into two parts: the PCI part and
the ACPI part. The PCI part releases PCI resources before the PCI bus
is gone, and the ACPI part is moved to a stage later than the hot-removal
of the PCI root bus, so that the IOAPIC driver is able to hook the
pcibios_release_device() of every PCI device under the same parent root
bus, before the IOAPIC is hot-removed. This makes it possible for the
IOAPIC to free any IRQ resource previously unable to get freed.

v2: Fixed compiling error on i386 (missing stub of pci_ioapic_remove())

Signed-off-by: Rui Wang 
---
 drivers/acpi/internal.h |  2 ++
 drivers/acpi/ioapic.c   | 22 --
 drivers/acpi/pci_root.c |  4 ++--
 3 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 219b90b..f159001 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -41,8 +41,10 @@ static inline void acpi_amba_init(void) {}
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pci_ioapic_remove(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
+static inline void pci_ioapic_remove(struct acpi_pci_root *root) { return; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 6d7ce6e..1120dfd6 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -206,24 +206,34 @@ int acpi_ioapic_add(acpi_handle root_handle)
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
 
-int acpi_ioapic_remove(struct acpi_pci_root *root)
+void pci_ioapic_remove(struct acpi_pci_root *root)
 {
-   int retval = 0;
struct acpi_pci_ioapic *ioapic, *tmp;
 
mutex_lock(_list_lock);
list_for_each_entry_safe(ioapic, tmp, _list, list) {
if (root->device->handle != ioapic->root_handle)
continue;
-
-   if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
-   retval = -EBUSY;
-
if (ioapic->pdev) {
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
}
+   }
+   mutex_unlock(_list_lock);
+}
+
+int acpi_ioapic_remove(struct acpi_pci_root *root)
+{
+   int retval = 0;
+   struct acpi_pci_ioapic *ioapic, *tmp;
+
+   mutex_lock(_list_lock);
+   list_for_each_entry_safe(ioapic, tmp, _list, list) {
+   if (root->device->handle != ioapic->root_handle)
+   continue;
+   if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
+   retval = -EBUSY;
if (ioapic->res.flags && ioapic->res.parent)
release_resource(>res);
list_del(>list);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index bf601d4..919be0a 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -648,12 +648,12 @@ static void acpi_pci_root_remove(struct acpi_device 
*device)
 
pci_stop_root_bus(root->bus);
 
-   WARN_ON(acpi_ioapic_remove(root));
-
+   pci_ioapic_remove(root);
device_set_run_wake(root->bus->bridge, false);
pci_acpi_remove_bus_pm_notifier(device);
 
pci_remove_root_bus(root->bus);
+   WARN_ON(acpi_ioapic_remove(root));
 
dmar_device_remove(device->handle);
 
-- 
1.8.3.1



[PATCH v2 1/2] x86/PCI: Implement pcibios_release_device to release IRQ from IOAPIC

2017-02-28 Thread Rui Wang
The revert of 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq()
and pcibios_free_irq()") causes a problem for IOAPIC hotplug. The
problem is that IRQs are allocated and freed in pci_enable_device()
and pci_disable_device(). But there are some drivers which don't call
pci_disable_device(), and they have good reasons not calling it, so
if they're using IOAPIC their IRQs won't have a chance to be released
from the IOAPIC. When this happens IOAPIC hot-removal fails with a
kernel stack dump and an error message like this:

[149335.697989] pin16 on IOAPIC2 is still in use.

It turns out that we can fix it in a different way without moving IRQ
allocation into pcibios_alloc_irq(), thus avoiding the regression of
991de2e59090. We can keep the allocation and freeing of IRQs as is
within pci_enable_device()/pci_disable_device(), without breaking any
previous assumption of the rest of the system, keeping compatibility
with both the legacy and the modern drivers. We can accomplish this by
implementing the existing __weak hook of pcibios_release_device() thus
when a pci device is about to be deleted we get notified in the hook
and take the chance to release its IRQ, if any, from the IOAPIC.

Besides implementing pcibios_release_device(), the hot-removal of
IOAPIC needs to be broken into two parts: the PCI part and the ACPI
part. The PCI part releases PCI resources before the PCI bus is gone,
and the ACPI part is moved to a stage later than the hot-removal of
the PCI root bus, so we have the chance to hook every PCI device's
pcibios_release_device(), before we remove the IOAPIC.

This patch implements pcibios_release_device() on x86 to release any
IRQ not released by the driver, so that the IOAPIC can then be safely
hot-removed.

v2: Fixed a typo (pcibios_release_device)

Signed-off-by: Rui Wang 
---
 arch/x86/pci/common.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 0cb52ae..190e718 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -735,6 +735,15 @@ void pcibios_disable_device (struct pci_dev *dev)
pcibios_disable_irq(dev);
 }
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pcibios_release_device(struct pci_dev *dev)
+{
+   if (atomic_dec_return(>enable_cnt) >= 0)
+   pcibios_disable_device(dev);
+
+}
+#endif
+
 int pci_ext_cfg_avail(void)
 {
if (raw_pci_ext_ops)
-- 
1.8.3.1



[PATCH 1/2] x86/PCI: Implement pci_release_device to release IRQ from IOAPIC

2017-02-27 Thread Rui Wang
The revert of 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq()
and pcibios_free_irq()") causes a problem for IOAPIC hotplug. The
problem is that IRQs are allocated and freed in pci_enable_device()
and pci_disable_device(). But there are some drivers which don't call
pci_disable_device(), and they have good reasons not calling it, so
if they're using IOAPIC their IRQs won't have a chance to be released
from the IOAPIC. When this happens IOAPIC hot-removal fails with a
kernel stack dump and an error message like this:

[149335.697989] pin16 on IOAPIC2 is still in use.

It turns out that we can fix it in a different way without moving IRQ
allocation into pcibios_alloc_irq(), thus avoiding the regression of
991de2e59090. We can keep the allocation and freeing of IRQs as is
within pci_enable_device()/pci_disable_device(), without breaking any
previous assumption of the rest of the system, keeping compatibility
with both the legacy and the modern drivers. We can accomplish this by
implementing the existing __weak hook of pcibios_release_device() thus
when a pci device is about to be deleted we get notified in the hook
and take the chance to release its IRQ, if any, from the IOAPIC.

Besides implementing pcibios_release_device(), the hot-removal of
IOAPIC needs to be broken into two parts: the PCI part and the ACPI
part. The PCI part releases PCI resources before the PCI bus is gone,
and the ACPI part is moved to a stage later than the hot-removal of
the PCI root bus, so we have the chance to hook every PCI device's
pcibios_release_device(), before we remove the IOAPIC.

This patch implements pcibios_release_device() on x86 to release any
IRQ not released by the driver, so that the IOAPIC can then be safely
hot-removed.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 arch/x86/pci/common.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 0cb52ae..4eba071 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -735,6 +735,15 @@ void pcibios_disable_device (struct pci_dev *dev)
pcibios_disable_irq(dev);
 }
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pcibios_release_device(struct pci_dev *dev)
+{
+   if (atomic_dec_return(>enable_cnt) >=0)
+   pcibios_disable_device(dev);
+
+}
+#endif
+
 int pci_ext_cfg_avail(void)
 {
if (raw_pci_ext_ops)
-- 
1.8.3.1



[PATCH 1/2] x86/PCI: Implement pci_release_device to release IRQ from IOAPIC

2017-02-27 Thread Rui Wang
The revert of 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq()
and pcibios_free_irq()") causes a problem for IOAPIC hotplug. The
problem is that IRQs are allocated and freed in pci_enable_device()
and pci_disable_device(). But there are some drivers which don't call
pci_disable_device(), and they have good reasons not calling it, so
if they're using IOAPIC their IRQs won't have a chance to be released
from the IOAPIC. When this happens IOAPIC hot-removal fails with a
kernel stack dump and an error message like this:

[149335.697989] pin16 on IOAPIC2 is still in use.

It turns out that we can fix it in a different way without moving IRQ
allocation into pcibios_alloc_irq(), thus avoiding the regression of
991de2e59090. We can keep the allocation and freeing of IRQs as is
within pci_enable_device()/pci_disable_device(), without breaking any
previous assumption of the rest of the system, keeping compatibility
with both the legacy and the modern drivers. We can accomplish this by
implementing the existing __weak hook of pcibios_release_device() thus
when a pci device is about to be deleted we get notified in the hook
and take the chance to release its IRQ, if any, from the IOAPIC.

Besides implementing pcibios_release_device(), the hot-removal of
IOAPIC needs to be broken into two parts: the PCI part and the ACPI
part. The PCI part releases PCI resources before the PCI bus is gone,
and the ACPI part is moved to a stage later than the hot-removal of
the PCI root bus, so we have the chance to hook every PCI device's
pcibios_release_device(), before we remove the IOAPIC.

This patch implements pcibios_release_device() on x86 to release any
IRQ not released by the driver, so that the IOAPIC can then be safely
hot-removed.

Signed-off-by: Rui Wang 
---
 arch/x86/pci/common.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 0cb52ae..4eba071 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -735,6 +735,15 @@ void pcibios_disable_device (struct pci_dev *dev)
pcibios_disable_irq(dev);
 }
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pcibios_release_device(struct pci_dev *dev)
+{
+   if (atomic_dec_return(>enable_cnt) >=0)
+   pcibios_disable_device(dev);
+
+}
+#endif
+
 int pci_ext_cfg_avail(void)
 {
if (raw_pci_ext_ops)
-- 
1.8.3.1



[PATCH 0/2] Improvement on ioapic hotplug

2017-02-27 Thread Rui Wang
The revert of 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq()
and pcibios_free_irq()") causes a problem for IOAPIC hotplug. If
a device under the IOAPIC doesn't call pci_disable_device(), then
the hot-removal of the IOAPIC causes kernel stack dump.

This patchset can fix the problem. IOAPIC hot-removal works correctly
after applying this patchset.

Rui Wang (2):
  x86/PCI: Implement pci_release_device to release IRQ from IOAPIC
  x86/ioapic: Split IOAPIC hot-removal into two steps

 arch/x86/pci/common.c   |  9 +
 drivers/acpi/internal.h |  1 +
 drivers/acpi/ioapic.c   | 22 --
 drivers/acpi/pci_root.c |  4 ++--
 4 files changed, 28 insertions(+), 8 deletions(-)

-- 
1.8.3.1



[PATCH 0/2] Improvement on ioapic hotplug

2017-02-27 Thread Rui Wang
The revert of 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq()
and pcibios_free_irq()") causes a problem for IOAPIC hotplug. If
a device under the IOAPIC doesn't call pci_disable_device(), then
the hot-removal of the IOAPIC causes kernel stack dump.

This patchset can fix the problem. IOAPIC hot-removal works correctly
after applying this patchset.

Rui Wang (2):
  x86/PCI: Implement pci_release_device to release IRQ from IOAPIC
  x86/ioapic: Split IOAPIC hot-removal into two steps

 arch/x86/pci/common.c   |  9 +
 drivers/acpi/internal.h |  1 +
 drivers/acpi/ioapic.c   | 22 --
 drivers/acpi/pci_root.c |  4 ++--
 4 files changed, 28 insertions(+), 8 deletions(-)

-- 
1.8.3.1



[PATCH 2/2] x86/ioapic: Split IOAPIC hot-removal into two steps

2017-02-27 Thread Rui Wang
The hot-removal of IOAPIC is broken into two parts: the PCI part and
the ACPI part. The PCI part releases PCI resources before the PCI bus
is gone, and the ACPI part is moved to a stage later than the hot-removal
of the PCI root bus, so that the IOAPIC driver is able to hook the
pcibios_release_device() of every PCI device under the same parent root
bus, before the IOAPIC is hot-removed. This makes it possible for the
IOAPIC to free any IRQ resource previously unable to get freed.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/internal.h |  1 +
 drivers/acpi/ioapic.c   | 22 --
 drivers/acpi/pci_root.c |  4 ++--
 3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 219b90b..b2e3416 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -41,6 +41,7 @@ static inline void acpi_amba_init(void) {}
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pci_ioapic_remove(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 6d7ce6e..1120dfd6 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -206,24 +206,34 @@ int acpi_ioapic_add(acpi_handle root_handle)
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
 
-int acpi_ioapic_remove(struct acpi_pci_root *root)
+void pci_ioapic_remove(struct acpi_pci_root *root)
 {
-   int retval = 0;
struct acpi_pci_ioapic *ioapic, *tmp;
 
mutex_lock(_list_lock);
list_for_each_entry_safe(ioapic, tmp, _list, list) {
if (root->device->handle != ioapic->root_handle)
continue;
-
-   if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
-   retval = -EBUSY;
-
if (ioapic->pdev) {
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
}
+   }
+   mutex_unlock(_list_lock);
+}
+
+int acpi_ioapic_remove(struct acpi_pci_root *root)
+{
+   int retval = 0;
+   struct acpi_pci_ioapic *ioapic, *tmp;
+
+   mutex_lock(_list_lock);
+   list_for_each_entry_safe(ioapic, tmp, _list, list) {
+   if (root->device->handle != ioapic->root_handle)
+   continue;
+   if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
+   retval = -EBUSY;
if (ioapic->res.flags && ioapic->res.parent)
release_resource(>res);
list_del(>list);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index bf601d4..919be0a 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -648,12 +648,12 @@ static void acpi_pci_root_remove(struct acpi_device 
*device)
 
pci_stop_root_bus(root->bus);
 
-   WARN_ON(acpi_ioapic_remove(root));
-
+   pci_ioapic_remove(root);
device_set_run_wake(root->bus->bridge, false);
pci_acpi_remove_bus_pm_notifier(device);
 
pci_remove_root_bus(root->bus);
+   WARN_ON(acpi_ioapic_remove(root));
 
dmar_device_remove(device->handle);
 
-- 
1.8.3.1



[PATCH 2/2] x86/ioapic: Split IOAPIC hot-removal into two steps

2017-02-27 Thread Rui Wang
The hot-removal of IOAPIC is broken into two parts: the PCI part and
the ACPI part. The PCI part releases PCI resources before the PCI bus
is gone, and the ACPI part is moved to a stage later than the hot-removal
of the PCI root bus, so that the IOAPIC driver is able to hook the
pcibios_release_device() of every PCI device under the same parent root
bus, before the IOAPIC is hot-removed. This makes it possible for the
IOAPIC to free any IRQ resource previously unable to get freed.

Signed-off-by: Rui Wang 
---
 drivers/acpi/internal.h |  1 +
 drivers/acpi/ioapic.c   | 22 --
 drivers/acpi/pci_root.c |  4 ++--
 3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 219b90b..b2e3416 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -41,6 +41,7 @@ static inline void acpi_amba_init(void) {}
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+void pci_ioapic_remove(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 6d7ce6e..1120dfd6 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -206,24 +206,34 @@ int acpi_ioapic_add(acpi_handle root_handle)
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
 
-int acpi_ioapic_remove(struct acpi_pci_root *root)
+void pci_ioapic_remove(struct acpi_pci_root *root)
 {
-   int retval = 0;
struct acpi_pci_ioapic *ioapic, *tmp;
 
mutex_lock(_list_lock);
list_for_each_entry_safe(ioapic, tmp, _list, list) {
if (root->device->handle != ioapic->root_handle)
continue;
-
-   if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
-   retval = -EBUSY;
-
if (ioapic->pdev) {
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
}
+   }
+   mutex_unlock(_list_lock);
+}
+
+int acpi_ioapic_remove(struct acpi_pci_root *root)
+{
+   int retval = 0;
+   struct acpi_pci_ioapic *ioapic, *tmp;
+
+   mutex_lock(_list_lock);
+   list_for_each_entry_safe(ioapic, tmp, _list, list) {
+   if (root->device->handle != ioapic->root_handle)
+   continue;
+   if (acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base))
+   retval = -EBUSY;
if (ioapic->res.flags && ioapic->res.parent)
release_resource(>res);
list_del(>list);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index bf601d4..919be0a 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -648,12 +648,12 @@ static void acpi_pci_root_remove(struct acpi_device 
*device)
 
pci_stop_root_bus(root->bus);
 
-   WARN_ON(acpi_ioapic_remove(root));
-
+   pci_ioapic_remove(root);
device_set_run_wake(root->bus->bridge, false);
pci_acpi_remove_bus_pm_notifier(device);
 
pci_remove_root_bus(root->bus);
+   WARN_ON(acpi_ioapic_remove(root));
 
dmar_device_remove(device->handle);
 
-- 
1.8.3.1



[tip:x86/apic] x86/ioapic: Ignore root bridges without a companion ACPI device

2016-09-10 Thread tip-bot for Rui Wang
Commit-ID:  d9c149d6ce1a94de578a4e323f6881fcb6b986ab
Gitweb: http://git.kernel.org/tip/d9c149d6ce1a94de578a4e323f6881fcb6b986ab
Author: Rui Wang <rui.y.w...@intel.com>
AuthorDate: Sat, 10 Sep 2016 23:40:45 +0800
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Sat, 10 Sep 2016 20:30:31 +0200

x86/ioapic: Ignore root bridges without a companion ACPI device

Some PCI root bridges don't have a corresponding ACPI device.
This can be the case on some old platforms. Don't call acpi_ioapic_add()
on these bridges because they can't support ioapic hotplug.

Reported-and-tested-by: Borislav Petkov <b...@suse.de>
Signed-off-by: Rui Wang <rui.y.w...@intel.com>
Reviewed-by: Borislav Petkov <b...@alien8.de>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: bhelg...@google.com
Cc: helg...@kernel.org
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: tony.l...@intel.com
Link: 
http://lkml.kernel.org/r/1473522046-31329-1-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 drivers/pci/setup-bus.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index ec538d3..f30ca75 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1855,7 +1855,10 @@ void __init pci_assign_unassigned_resources(void)
 
list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
-   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+
+   /* Make sure the root bridge has a companion ACPI device: */
+   if (ACPI_HANDLE(root_bus->bridge))
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
}
 }
 


[tip:x86/apic] x86/ioapic: Ignore root bridges without a companion ACPI device

2016-09-10 Thread tip-bot for Rui Wang
Commit-ID:  d9c149d6ce1a94de578a4e323f6881fcb6b986ab
Gitweb: http://git.kernel.org/tip/d9c149d6ce1a94de578a4e323f6881fcb6b986ab
Author: Rui Wang 
AuthorDate: Sat, 10 Sep 2016 23:40:45 +0800
Committer:  Ingo Molnar 
CommitDate: Sat, 10 Sep 2016 20:30:31 +0200

x86/ioapic: Ignore root bridges without a companion ACPI device

Some PCI root bridges don't have a corresponding ACPI device.
This can be the case on some old platforms. Don't call acpi_ioapic_add()
on these bridges because they can't support ioapic hotplug.

Reported-and-tested-by: Borislav Petkov 
Signed-off-by: Rui Wang 
Reviewed-by: Borislav Petkov 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: bhelg...@google.com
Cc: helg...@kernel.org
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: tony.l...@intel.com
Link: 
http://lkml.kernel.org/r/1473522046-31329-1-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar 
---
 drivers/pci/setup-bus.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index ec538d3..f30ca75 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1855,7 +1855,10 @@ void __init pci_assign_unassigned_resources(void)
 
list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
-   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+
+   /* Make sure the root bridge has a companion ACPI device: */
+   if (ACPI_HANDLE(root_bus->bridge))
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
}
 }
 


[PATCH] x86/ioapic: Ignore root bridges without a companion ACPI device

2016-09-10 Thread Rui Wang
Some PCI root bridges don't have a corresponding ACPI device.
This can be the case on some old platforms. Don't call acpi_ioapic_add()
on these bridges because they can't support ioapic hotplug.

v2: Per Boris's review, removed the unnecessary local var; refined comment

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
Reviewed-by: Borislav Petkov <b...@alien8.de>
---
 drivers/pci/setup-bus.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index ec538d3..8b4e231 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1855,7 +1855,10 @@ void __init pci_assign_unassigned_resources(void)
 
list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
-   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+
+   /* make sure the root bridge has a companion ACPI device */
+   if (ACPI_HANDLE(root_bus->bridge))
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
}
 }
 
-- 
1.8.3.1



[PATCH] x86/ioapic: Ignore root bridges without a companion ACPI device

2016-09-10 Thread Rui Wang
Some PCI root bridges don't have a corresponding ACPI device.
This can be the case on some old platforms. Don't call acpi_ioapic_add()
on these bridges because they can't support ioapic hotplug.

v2: Per Boris's review, removed the unnecessary local var; refined comment

Signed-off-by: Rui Wang 
Reviewed-by: Borislav Petkov 
---
 drivers/pci/setup-bus.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index ec538d3..8b4e231 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1855,7 +1855,10 @@ void __init pci_assign_unassigned_resources(void)
 
list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
-   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+
+   /* make sure the root bridge has a companion ACPI device */
+   if (ACPI_HANDLE(root_bus->bridge))
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
}
 }
 
-- 
1.8.3.1



Re: 584c5c422f6c ("x86/ioapic: Support hot-removal of IOAPICs present during boot")

2016-09-10 Thread Rui Wang
On Sat, Sep 10, 2016 10:31 PM, Borislav Petkov wrote:
> 
> On Sat, Sep 10, 2016 at 09:11:30PM +0800, Rui Wang wrote:
> > Thanks for the analysis. Looks like acpi_gbl_root_node == 0. It is
> 
> Is ACPI_HANDLE(root_bus->bridge) == ACPI_ROOT_OBJECT?
> 
> Because this is what the code does but I can't see it from the code that the
> handle is of type ACPI_ROOT_OBJECT...
> 

I seem to have the clue. It is because ACPI_HANDLE(root_bus->bridge) == NULL.
Then this root bridge doesn't have a corresponding ACPI device. In this case
we shouldn't call acpi_ioapic_add(). This can be true for some old platforms.

If that's the case then the patch below can fix it.

Thanks
Rui

>From b37d806c78e5eea70dbb890c1e3dbb8b7e5038e6 Mon Sep 17 00:00:00 2001
From: Rui Wang <rui.y.w...@intel.com>
Date: Sat, 10 Sep 2016 10:56:34 -0400
Subject: [PATCH] x86/ioapic: Ignore root bridges without a companion ACPI device

Some PCI root bridges don't have a corresponding ACPI device.
Don't call acpi_ioapic_add() on these bridges because they can't
support ioapic hotplug.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/pci/setup-bus.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index ec538d3..2b05ac6 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1852,10 +1852,15 @@ dump:
 void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
+   acpi_handle root_handle;
 
list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
-   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   root_handle = ACPI_HANDLE(root_bus->bridge);
+
+   /* make sure the root bridge has a companion ACPI device */
+   if (root_handle)
+   acpi_ioapic_add(root_handle);
}
 }
 
-- 
1.8.3.1



Re: 584c5c422f6c ("x86/ioapic: Support hot-removal of IOAPICs present during boot")

2016-09-10 Thread Rui Wang
On Sat, Sep 10, 2016 10:31 PM, Borislav Petkov wrote:
> 
> On Sat, Sep 10, 2016 at 09:11:30PM +0800, Rui Wang wrote:
> > Thanks for the analysis. Looks like acpi_gbl_root_node == 0. It is
> 
> Is ACPI_HANDLE(root_bus->bridge) == ACPI_ROOT_OBJECT?
> 
> Because this is what the code does but I can't see it from the code that the
> handle is of type ACPI_ROOT_OBJECT...
> 

I seem to have the clue. It is because ACPI_HANDLE(root_bus->bridge) == NULL.
Then this root bridge doesn't have a corresponding ACPI device. In this case
we shouldn't call acpi_ioapic_add(). This can be true for some old platforms.

If that's the case then the patch below can fix it.

Thanks
Rui

>From b37d806c78e5eea70dbb890c1e3dbb8b7e5038e6 Mon Sep 17 00:00:00 2001
From: Rui Wang 
Date: Sat, 10 Sep 2016 10:56:34 -0400
Subject: [PATCH] x86/ioapic: Ignore root bridges without a companion ACPI device

Some PCI root bridges don't have a corresponding ACPI device.
Don't call acpi_ioapic_add() on these bridges because they can't
support ioapic hotplug.

Signed-off-by: Rui Wang 
---
 drivers/pci/setup-bus.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index ec538d3..2b05ac6 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1852,10 +1852,15 @@ dump:
 void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
+   acpi_handle root_handle;
 
list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
-   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   root_handle = ACPI_HANDLE(root_bus->bridge);
+
+   /* make sure the root bridge has a companion ACPI device */
+   if (root_handle)
+   acpi_ioapic_add(root_handle);
}
 }
 
-- 
1.8.3.1



Re: 584c5c422f6c ("x86/ioapic: Support hot-removal of IOAPICs present during boot")

2016-09-10 Thread Rui Wang
On Sat, Sep 10, 2016 7:28 PM, Borislav Petkov wrote:
> 
> 8143ef50 :
> 8143ef50:   e8 6b 16 42 00  callq  818605c0 
> <__fentry__>
> 8143ef55:   55  push   %rbp
> 8143ef56:   48 89 e5mov%rsp,%rbp
> 8143ef59:   41 57   push   %r15
> 8143ef5b:   41 56   push   %r14
> 8143ef5d:   49 89 f6mov%rsi,%r14
> 8143ef60:   41 55   push   %r13
> 8143ef62:   41 54   push   %r12
> 8143ef64:   41 89 ccmov%ecx,%r12d
> 8143ef67:   53  push   %rbx
> 8143ef68:   bb 01 00 00 00  mov$0x1,%ebx
> 8143ef6d:   48 83 ec 28 sub$0x28,%rsp
> 8143ef71:   48 83 fe ff cmp
> $0x,%rsi
> 8143ef75:   89 7d d0mov%edi,-0x30(%rbp)
> 8143ef78:   4c 0f 44 35 58 7b 99cmove  0x1997b58(%rip),%r14  
> # 82dd6ad8 
> 8143ef7f:   01
> 8143ef80:   89 55 c8mov%edx,-0x38(%rbp)
> 8143ef83:   45 31 ffxor%r15d,%r15d
> 8143ef86:   41 83 e4 01 and$0x1,%r12d
> 8143ef8a:   89 4d ccmov%ecx,-0x34(%rbp)
> 8143ef8d:   4d 8b 6e 18 mov0x18(%r14),%r13
> <--- > faulting insn.
> 8143ef91:   4c 89 45 c0 mov%r8,-0x40(%rbp)
> 8143ef95:   4c 89 4d b8 mov%r9,-0x48(%rbp)
> 8143ef99:   c7 45 d4 00 00 00 00movl   $0x0,-0x2c(%rbp)
> 8143efa0:   4d 85 edtest   %r13,%r13

Thanks for the analysis. Looks like acpi_gbl_root_node == 0. It is
initialized earlier than where we call acpi_ioapic_add().
start_kernel()
->acpi_early_init()
->acpi_initialize_subsystem()
 ->acpi_ns_root_initialize()
-> acpi_gbl_root_node = ...


But acpi_gbl_root_node can be 0 if acpi_disabled == 1.
Do you somehow have acpi turned off (!CONFIG_ACPI or booting with acpi=off)?

Thanks
Rui


Re: 584c5c422f6c ("x86/ioapic: Support hot-removal of IOAPICs present during boot")

2016-09-10 Thread Rui Wang
On Sat, Sep 10, 2016 7:28 PM, Borislav Petkov wrote:
> 
> 8143ef50 :
> 8143ef50:   e8 6b 16 42 00  callq  818605c0 
> <__fentry__>
> 8143ef55:   55  push   %rbp
> 8143ef56:   48 89 e5mov%rsp,%rbp
> 8143ef59:   41 57   push   %r15
> 8143ef5b:   41 56   push   %r14
> 8143ef5d:   49 89 f6mov%rsi,%r14
> 8143ef60:   41 55   push   %r13
> 8143ef62:   41 54   push   %r12
> 8143ef64:   41 89 ccmov%ecx,%r12d
> 8143ef67:   53  push   %rbx
> 8143ef68:   bb 01 00 00 00  mov$0x1,%ebx
> 8143ef6d:   48 83 ec 28 sub$0x28,%rsp
> 8143ef71:   48 83 fe ff cmp
> $0x,%rsi
> 8143ef75:   89 7d d0mov%edi,-0x30(%rbp)
> 8143ef78:   4c 0f 44 35 58 7b 99cmove  0x1997b58(%rip),%r14  
> # 82dd6ad8 
> 8143ef7f:   01
> 8143ef80:   89 55 c8mov%edx,-0x38(%rbp)
> 8143ef83:   45 31 ffxor%r15d,%r15d
> 8143ef86:   41 83 e4 01 and$0x1,%r12d
> 8143ef8a:   89 4d ccmov%ecx,-0x34(%rbp)
> 8143ef8d:   4d 8b 6e 18 mov0x18(%r14),%r13
> <--- > faulting insn.
> 8143ef91:   4c 89 45 c0 mov%r8,-0x40(%rbp)
> 8143ef95:   4c 89 4d b8 mov%r9,-0x48(%rbp)
> 8143ef99:   c7 45 d4 00 00 00 00movl   $0x0,-0x2c(%rbp)
> 8143efa0:   4d 85 edtest   %r13,%r13

Thanks for the analysis. Looks like acpi_gbl_root_node == 0. It is
initialized earlier than where we call acpi_ioapic_add().
start_kernel()
->acpi_early_init()
->acpi_initialize_subsystem()
 ->acpi_ns_root_initialize()
-> acpi_gbl_root_node = ...


But acpi_gbl_root_node can be 0 if acpi_disabled == 1.
Do you somehow have acpi turned off (!CONFIG_ACPI or booting with acpi=off)?

Thanks
Rui


584c5c422f6c ("x86/ioapic: Support hot-removal of IOAPICs present during boot")

2016-09-09 Thread Rui Wang
On Saturday, September 10, 2016 6:07 AM, Borislav Petkov wrote:
> 
> Hi,
> 
> commit in $Subject from tip breaks booting on my SNB test box, it freezes
> somewhere very early during boot. When I revert the aforementioned
> commit ontop of Linus' master + tip/master from today, it boots fine.
> 
> Additional info is available upon request.
> 

Hi Boris,

Is it a Romley-EP ? What kind of SNB box is it? I'll try to find one
to reproduce the problem.

Thanks
Rui


584c5c422f6c ("x86/ioapic: Support hot-removal of IOAPICs present during boot")

2016-09-09 Thread Rui Wang
On Saturday, September 10, 2016 6:07 AM, Borislav Petkov wrote:
> 
> Hi,
> 
> commit in $Subject from tip breaks booting on my SNB test box, it freezes
> somewhere very early during boot. When I revert the aforementioned
> commit ontop of Linus' master + tip/master from today, it boots fine.
> 
> Additional info is available upon request.
> 

Hi Boris,

Is it a Romley-EP ? What kind of SNB box is it? I'll try to find one
to reproduce the problem.

Thanks
Rui


[tip:x86/apic] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-08-18 Thread tip-bot for Rui Wang
Commit-ID:  584c5c422f6c749ced1e0bc3c6837f650f64e1e1
Gitweb: http://git.kernel.org/tip/584c5c422f6c749ced1e0bc3c6837f650f64e1e1
Author: Rui Wang <rui.y.w...@intel.com>
AuthorDate: Wed, 17 Aug 2016 16:00:34 +0800
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Thu, 18 Aug 2016 11:45:18 +0200

x86/ioapic: Support hot-removal of IOAPICs present during boot

IOAPICs present during system boot aren't added to ioapic_list,
thus are unable to be hot-removed. Fix it by calling
acpi_ioapic_add() during root bus enumeration.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
Acked-by: Bjorn Helgaas <bhelg...@google.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: helg...@kernel.org
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: tony.l...@intel.com
Link: 
http://lkml.kernel.org/r/1471420837-31003-3-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 drivers/acpi/pci_root.c | 10 ++
 drivers/pci/setup-bus.c |  5 -
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index b07eda1..bf601d4 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,6 +614,16 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
+   /*
+* This is only called for the hotadd case. For the boot-time
+* case, we need to wait until after PCI initialization in
+* order to deal with IOAPICs mapped in on a PCI BAR.
+*
+* This is currently x86-specific, because acpi_ioapic_add()
+* is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC.
+* And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC
+* (see drivers/acpi/Kconfig).
+*/
acpi_ioapic_add(root->device->handle);
}
 
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index c74059e..ec538d3 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pci.h"
 
 unsigned int pci_flags;
@@ -1852,8 +1853,10 @@ void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
 
-   list_for_each_entry(root_bus, _root_buses, node)
+   list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   }
 }
 
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)


[tip:x86/apic] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-08-18 Thread tip-bot for Rui Wang
Commit-ID:  584c5c422f6c749ced1e0bc3c6837f650f64e1e1
Gitweb: http://git.kernel.org/tip/584c5c422f6c749ced1e0bc3c6837f650f64e1e1
Author: Rui Wang 
AuthorDate: Wed, 17 Aug 2016 16:00:34 +0800
Committer:  Ingo Molnar 
CommitDate: Thu, 18 Aug 2016 11:45:18 +0200

x86/ioapic: Support hot-removal of IOAPICs present during boot

IOAPICs present during system boot aren't added to ioapic_list,
thus are unable to be hot-removed. Fix it by calling
acpi_ioapic_add() during root bus enumeration.

Signed-off-by: Rui Wang 
Acked-by: Bjorn Helgaas 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: helg...@kernel.org
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: tony.l...@intel.com
Link: 
http://lkml.kernel.org/r/1471420837-31003-3-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar 
---
 drivers/acpi/pci_root.c | 10 ++
 drivers/pci/setup-bus.c |  5 -
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index b07eda1..bf601d4 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,6 +614,16 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
+   /*
+* This is only called for the hotadd case. For the boot-time
+* case, we need to wait until after PCI initialization in
+* order to deal with IOAPICs mapped in on a PCI BAR.
+*
+* This is currently x86-specific, because acpi_ioapic_add()
+* is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC.
+* And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC
+* (see drivers/acpi/Kconfig).
+*/
acpi_ioapic_add(root->device->handle);
}
 
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index c74059e..ec538d3 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pci.h"
 
 unsigned int pci_flags;
@@ -1852,8 +1853,10 @@ void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
 
-   list_for_each_entry(root_bus, _root_buses, node)
+   list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   }
 }
 
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)


[tip:x86/apic] x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd

2016-08-18 Thread tip-bot for Rui Wang
Commit-ID:  162b83bd5f1d7124e21da78bcf2685b9824d9ef0
Gitweb: http://git.kernel.org/tip/162b83bd5f1d7124e21da78bcf2685b9824d9ef0
Author: Rui Wang <rui.y.w...@intel.com>
AuthorDate: Wed, 17 Aug 2016 16:00:36 +0800
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Thu, 18 Aug 2016 11:45:18 +0200

x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd

IOAPIC resource at 0xfecx gets lost from /proc/iomem after
hot-removing and then hot-adding the IOAPIC device.

After system boot, in /proc/iomem:

 fec0-fecf : PNP0003:00
   fec0-fec003ff : IOAPIC 0
   fec01000-fec013ff : IOAPIC 1
   fec4-fec403ff : IOAPIC 2
   fec8-fec803ff : IOAPIC 3
   fecc-fecc03ff : IOAPIC 4

Then hot-remove IOAPIC 2 and hot-add it again:

 fec0-fecf : PNP0003:00
   fec0-fec003ff : IOAPIC 0
   fec01000-fec013ff : IOAPIC 1
   fec8-fec803ff : IOAPIC 3
   fecc-fecc03ff : IOAPIC 4

The range at 0xfec4 is lost from /proc/iomem - which is a bug.

This bug happens because handle_ioapic_add() requests resources from
either PCI config BAR or ACPI "_CRS", not both. But Intel platforms
map the IOxAPIC registers both at the PCI config BAR (called MBAR, dynamic),
and at the ACPI "_CRS" (called ABAR, static). The 0xfecX_YZ00 to 0xfecX_YZFF
range appears in "_CRS" of each IOAPIC device.

Both ranges should be claimed from /proc/iomem for exclusive use.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: bhelg...@google.com
Cc: helg...@kernel.org
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: tony.l...@intel.com
Link: 
http://lkml.kernel.org/r/1471420837-31003-5-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 drivers/acpi/ioapic.c | 36 
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 8ab6d42..ee20111 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -97,7 +97,7 @@ static acpi_status handle_ioapic_add(acpi_handle handle, u32 
lvl,
unsigned long long gsi_base;
struct acpi_pci_ioapic *ioapic;
struct pci_dev *dev = NULL;
-   struct resource *res = NULL;
+   struct resource *res = NULL, *pci_res = NULL, *crs_res;
char *type = NULL;
 
if (!acpi_is_ioapic(handle, ))
@@ -137,23 +137,28 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
pci_set_master(dev);
if (pci_request_region(dev, 0, type))
goto exit_disable;
-   res = >resource[0];
+   pci_res = >resource[0];
ioapic->pdev = dev;
} else {
pci_dev_put(dev);
dev = NULL;
+   }
 
-   res = >res;
-   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, res);
-   if (res->flags == 0) {
-   acpi_handle_warn(handle, "failed to get resource\n");
-   goto exit_free;
-   } else if (request_resource(_resource, res)) {
-   acpi_handle_warn(handle, "failed to insert resource\n");
-   goto exit_free;
-   }
+   crs_res = >res;
+   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   if (crs_res->flags == 0) {
+   acpi_handle_warn(handle, "failed to get resource\n");
+   goto exit_release;
+   } else if (request_resource(_resource, crs_res)) {
+   acpi_handle_warn(handle, "failed to insert resource\n");
+   goto exit_release;
}
 
+   /* try pci resource first, then "_CRS" resource */
+   res = pci_res;
+   if (!res || !res->flags)
+   res = crs_res;
+
if (acpi_register_ioapic(handle, res->start, (u32)gsi_base)) {
acpi_handle_warn(handle, "failed to register IOAPIC\n");
goto exit_release;
@@ -174,14 +179,13 @@ done:
 exit_release:
if (dev)
pci_release_region(dev, 0);
-   else
-   release_resource(res);
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
 exit_disable:
if (dev)
pci_disable_device(dev);
 exit_put:
pci_dev_put(dev);
-exit_free:
kfree(ioapic);
 exit:
mutex_unlock(_list_lock);
@@ -217,9 +221,9 @@ int acpi_ioapic_remove(struct acpi_pci_root *root)
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic

[tip:x86/apic] x86/ioapic: Fix setup_res() failing to get resource

2016-08-18 Thread tip-bot for Rui Wang
Commit-ID:  6ab7eba5db93c11d61f6f7fbe21edbc875b26c1a
Gitweb: http://git.kernel.org/tip/6ab7eba5db93c11d61f6f7fbe21edbc875b26c1a
Author: Rui Wang <rui.y.w...@intel.com>
AuthorDate: Wed, 17 Aug 2016 16:00:35 +0800
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Thu, 18 Aug 2016 11:45:18 +0200

x86/ioapic: Fix setup_res() failing to get resource

acpi_dev_filter_resource_type() returns 0 on success, and 1 on failure.
A return value of zero means there's a matching resource, so we should
continue within setup_res() to get the resource.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: bhelg...@google.com
Cc: helg...@kernel.org
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: tony.l...@intel.com
Link: 
http://lkml.kernel.org/r/1471420837-31003-4-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 drivers/acpi/ioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 2449377..8ab6d42 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -46,7 +46,7 @@ static acpi_status setup_res(struct acpi_resource *acpi_res, 
void *data)
struct resource_win win;
 
res->flags = 0;
-   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM) == 0)
+   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
return AE_OK;
 
if (!acpi_dev_resource_memory(acpi_res, res)) {


[tip:x86/apic] x86/ioapic: Fix IOAPIC failing to request resource

2016-08-18 Thread tip-bot for Rui Wang
Commit-ID:  624cad9d2907a0788b56e3ca664c5d7d02645ed4
Gitweb: http://git.kernel.org/tip/624cad9d2907a0788b56e3ca664c5d7d02645ed4
Author: Rui Wang <rui.y.w...@intel.com>
AuthorDate: Wed, 17 Aug 2016 16:00:37 +0800
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Thu, 18 Aug 2016 11:45:19 +0200

x86/ioapic: Fix IOAPIC failing to request resource

handle_ioapic_add() uses request_resource() to request ACPI "_CRS"
resources. This can fail with the following error message:

  [  247.325693] ACPI: \_SB_.IIO1.AID1: failed to insert resource

This happens when there are multiple IOAPICs and DSDT groups their
"_CRS" resources as the children of a parent resource, as seen from
/proc/iomem:

  fec0-fecf : PNP0003:00
fec0-fec003ff : IOAPIC 0
fec01000-fec013ff : IOAPIC 1
fec4-fec403ff : IOAPIC 2

In this case request_resource() fails because there's a conflicting
resource which is the parent (fec-fecf). Fix it by using
insert_resource() which can request resources by taking the conflicting
resource as the parent.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: bhelg...@google.com
Cc: helg...@kernel.org
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: tony.l...@intel.com
Link: 
http://lkml.kernel.org/r/1471420837-31003-6-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 drivers/acpi/ioapic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ee20111..6d7ce6e 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -146,10 +146,12 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
 
crs_res = >res;
acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   crs_res->name = type;
+   crs_res->flags |= IORESOURCE_BUSY;
if (crs_res->flags == 0) {
acpi_handle_warn(handle, "failed to get resource\n");
goto exit_release;
-   } else if (request_resource(_resource, crs_res)) {
+   } else if (insert_resource(_resource, crs_res)) {
acpi_handle_warn(handle, "failed to insert resource\n");
goto exit_release;
}


[tip:x86/apic] x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd

2016-08-18 Thread tip-bot for Rui Wang
Commit-ID:  162b83bd5f1d7124e21da78bcf2685b9824d9ef0
Gitweb: http://git.kernel.org/tip/162b83bd5f1d7124e21da78bcf2685b9824d9ef0
Author: Rui Wang 
AuthorDate: Wed, 17 Aug 2016 16:00:36 +0800
Committer:  Ingo Molnar 
CommitDate: Thu, 18 Aug 2016 11:45:18 +0200

x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd

IOAPIC resource at 0xfecx gets lost from /proc/iomem after
hot-removing and then hot-adding the IOAPIC device.

After system boot, in /proc/iomem:

 fec0-fecf : PNP0003:00
   fec0-fec003ff : IOAPIC 0
   fec01000-fec013ff : IOAPIC 1
   fec4-fec403ff : IOAPIC 2
   fec8-fec803ff : IOAPIC 3
   fecc-fecc03ff : IOAPIC 4

Then hot-remove IOAPIC 2 and hot-add it again:

 fec0-fecf : PNP0003:00
   fec0-fec003ff : IOAPIC 0
   fec01000-fec013ff : IOAPIC 1
   fec8-fec803ff : IOAPIC 3
   fecc-fecc03ff : IOAPIC 4

The range at 0xfec4 is lost from /proc/iomem - which is a bug.

This bug happens because handle_ioapic_add() requests resources from
either PCI config BAR or ACPI "_CRS", not both. But Intel platforms
map the IOxAPIC registers both at the PCI config BAR (called MBAR, dynamic),
and at the ACPI "_CRS" (called ABAR, static). The 0xfecX_YZ00 to 0xfecX_YZFF
range appears in "_CRS" of each IOAPIC device.

Both ranges should be claimed from /proc/iomem for exclusive use.

Signed-off-by: Rui Wang 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: bhelg...@google.com
Cc: helg...@kernel.org
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: tony.l...@intel.com
Link: 
http://lkml.kernel.org/r/1471420837-31003-5-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar 
---
 drivers/acpi/ioapic.c | 36 
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 8ab6d42..ee20111 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -97,7 +97,7 @@ static acpi_status handle_ioapic_add(acpi_handle handle, u32 
lvl,
unsigned long long gsi_base;
struct acpi_pci_ioapic *ioapic;
struct pci_dev *dev = NULL;
-   struct resource *res = NULL;
+   struct resource *res = NULL, *pci_res = NULL, *crs_res;
char *type = NULL;
 
if (!acpi_is_ioapic(handle, ))
@@ -137,23 +137,28 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
pci_set_master(dev);
if (pci_request_region(dev, 0, type))
goto exit_disable;
-   res = >resource[0];
+   pci_res = >resource[0];
ioapic->pdev = dev;
} else {
pci_dev_put(dev);
dev = NULL;
+   }
 
-   res = >res;
-   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, res);
-   if (res->flags == 0) {
-   acpi_handle_warn(handle, "failed to get resource\n");
-   goto exit_free;
-   } else if (request_resource(_resource, res)) {
-   acpi_handle_warn(handle, "failed to insert resource\n");
-   goto exit_free;
-   }
+   crs_res = >res;
+   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   if (crs_res->flags == 0) {
+   acpi_handle_warn(handle, "failed to get resource\n");
+   goto exit_release;
+   } else if (request_resource(_resource, crs_res)) {
+   acpi_handle_warn(handle, "failed to insert resource\n");
+   goto exit_release;
}
 
+   /* try pci resource first, then "_CRS" resource */
+   res = pci_res;
+   if (!res || !res->flags)
+   res = crs_res;
+
if (acpi_register_ioapic(handle, res->start, (u32)gsi_base)) {
acpi_handle_warn(handle, "failed to register IOAPIC\n");
goto exit_release;
@@ -174,14 +179,13 @@ done:
 exit_release:
if (dev)
pci_release_region(dev, 0);
-   else
-   release_resource(res);
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
 exit_disable:
if (dev)
pci_disable_device(dev);
 exit_put:
pci_dev_put(dev);
-exit_free:
kfree(ioapic);
 exit:
mutex_unlock(_list_lock);
@@ -217,9 +221,9 @@ int acpi_ioapic_remove(struct acpi_pci_root *root)
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
-   } else if (ioapic->res.flags && ioapic->res.parent) {
-   release_resource(>res);
}
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
list_del(>list);
kfree(ioapic);
}


[tip:x86/apic] x86/ioapic: Fix setup_res() failing to get resource

2016-08-18 Thread tip-bot for Rui Wang
Commit-ID:  6ab7eba5db93c11d61f6f7fbe21edbc875b26c1a
Gitweb: http://git.kernel.org/tip/6ab7eba5db93c11d61f6f7fbe21edbc875b26c1a
Author: Rui Wang 
AuthorDate: Wed, 17 Aug 2016 16:00:35 +0800
Committer:  Ingo Molnar 
CommitDate: Thu, 18 Aug 2016 11:45:18 +0200

x86/ioapic: Fix setup_res() failing to get resource

acpi_dev_filter_resource_type() returns 0 on success, and 1 on failure.
A return value of zero means there's a matching resource, so we should
continue within setup_res() to get the resource.

Signed-off-by: Rui Wang 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: bhelg...@google.com
Cc: helg...@kernel.org
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: tony.l...@intel.com
Link: 
http://lkml.kernel.org/r/1471420837-31003-4-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar 
---
 drivers/acpi/ioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 2449377..8ab6d42 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -46,7 +46,7 @@ static acpi_status setup_res(struct acpi_resource *acpi_res, 
void *data)
struct resource_win win;
 
res->flags = 0;
-   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM) == 0)
+   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
return AE_OK;
 
if (!acpi_dev_resource_memory(acpi_res, res)) {


[tip:x86/apic] x86/ioapic: Fix IOAPIC failing to request resource

2016-08-18 Thread tip-bot for Rui Wang
Commit-ID:  624cad9d2907a0788b56e3ca664c5d7d02645ed4
Gitweb: http://git.kernel.org/tip/624cad9d2907a0788b56e3ca664c5d7d02645ed4
Author: Rui Wang 
AuthorDate: Wed, 17 Aug 2016 16:00:37 +0800
Committer:  Ingo Molnar 
CommitDate: Thu, 18 Aug 2016 11:45:19 +0200

x86/ioapic: Fix IOAPIC failing to request resource

handle_ioapic_add() uses request_resource() to request ACPI "_CRS"
resources. This can fail with the following error message:

  [  247.325693] ACPI: \_SB_.IIO1.AID1: failed to insert resource

This happens when there are multiple IOAPICs and DSDT groups their
"_CRS" resources as the children of a parent resource, as seen from
/proc/iomem:

  fec0-fecf : PNP0003:00
fec0-fec003ff : IOAPIC 0
fec01000-fec013ff : IOAPIC 1
fec4-fec403ff : IOAPIC 2

In this case request_resource() fails because there's a conflicting
resource which is the parent (fec-fecf). Fix it by using
insert_resource() which can request resources by taking the conflicting
resource as the parent.

Signed-off-by: Rui Wang 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: bhelg...@google.com
Cc: helg...@kernel.org
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: tony.l...@intel.com
Link: 
http://lkml.kernel.org/r/1471420837-31003-6-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar 
---
 drivers/acpi/ioapic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ee20111..6d7ce6e 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -146,10 +146,12 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
 
crs_res = >res;
acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   crs_res->name = type;
+   crs_res->flags |= IORESOURCE_BUSY;
if (crs_res->flags == 0) {
acpi_handle_warn(handle, "failed to get resource\n");
goto exit_release;
-   } else if (request_resource(_resource, crs_res)) {
+   } else if (insert_resource(_resource, crs_res)) {
acpi_handle_warn(handle, "failed to insert resource\n");
goto exit_release;
}


[tip:x86/apic] x86/ioapic: Change prototype of acpi_ioapic_add()

2016-08-18 Thread tip-bot for Rui Wang
Commit-ID:  fe7bd58f5d25d5d655b1da4a084cc4ef6f085fee
Gitweb: http://git.kernel.org/tip/fe7bd58f5d25d5d655b1da4a084cc4ef6f085fee
Author: Rui Wang <rui.y.w...@intel.com>
AuthorDate: Wed, 17 Aug 2016 16:00:33 +0800
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Thu, 18 Aug 2016 11:45:18 +0200

x86/ioapic: Change prototype of acpi_ioapic_add()

Change the argument of acpi_ioapic_add() to a generic ACPI handle, and
move its prototype from drivers/acpi/internal.h to include/linux/acpi.h
so that it can be called from outside the pci_root driver.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: bhelg...@google.com
Cc: helg...@kernel.org
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: tony.l...@intel.com
Link: 
http://lkml.kernel.org/r/1471420837-31003-2-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 drivers/acpi/internal.h | 2 --
 drivers/acpi/ioapic.c   | 6 +++---
 drivers/acpi/pci_root.c | 2 +-
 include/linux/acpi.h| 6 ++
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 940218f..f26fc1d 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -40,10 +40,8 @@ int acpi_sysfs_init(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
-int acpi_ioapic_add(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
-static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ccdc8db..2449377 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -189,13 +189,13 @@ exit:
return AE_OK;
 }
 
-int acpi_ioapic_add(struct acpi_pci_root *root)
+int acpi_ioapic_add(acpi_handle root_handle)
 {
acpi_status status, retval = AE_OK;
 
-   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle,
+   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
 UINT_MAX, handle_ioapic_add, NULL,
-root->device->handle, (void **));
+root_handle, (void **));
 
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d144168..b07eda1 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,7 +614,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
-   acpi_ioapic_add(root);
+   acpi_ioapic_add(root->device->handle);
}
 
pci_lock_rescan_remove();
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 4d8452c..c9a596b 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -751,6 +751,12 @@ static inline int acpi_reconfig_notifier_unregister(struct 
notifier_block *nb)
 
 #endif /* !CONFIG_ACPI */
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+int acpi_ioapic_add(acpi_handle root);
+#else
+static inline int acpi_ioapic_add(acpi_handle root) { return 0; }
+#endif
+
 #ifdef CONFIG_ACPI
 void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
   u32 pm1a_ctrl,  u32 pm1b_ctrl));


[tip:x86/apic] x86/ioapic: Change prototype of acpi_ioapic_add()

2016-08-18 Thread tip-bot for Rui Wang
Commit-ID:  fe7bd58f5d25d5d655b1da4a084cc4ef6f085fee
Gitweb: http://git.kernel.org/tip/fe7bd58f5d25d5d655b1da4a084cc4ef6f085fee
Author: Rui Wang 
AuthorDate: Wed, 17 Aug 2016 16:00:33 +0800
Committer:  Ingo Molnar 
CommitDate: Thu, 18 Aug 2016 11:45:18 +0200

x86/ioapic: Change prototype of acpi_ioapic_add()

Change the argument of acpi_ioapic_add() to a generic ACPI handle, and
move its prototype from drivers/acpi/internal.h to include/linux/acpi.h
so that it can be called from outside the pci_root driver.

Signed-off-by: Rui Wang 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: bhelg...@google.com
Cc: helg...@kernel.org
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: r...@rjwysocki.net
Cc: tony.l...@intel.com
Link: 
http://lkml.kernel.org/r/1471420837-31003-2-git-send-email-rui.y.w...@intel.com
Signed-off-by: Ingo Molnar 
---
 drivers/acpi/internal.h | 2 --
 drivers/acpi/ioapic.c   | 6 +++---
 drivers/acpi/pci_root.c | 2 +-
 include/linux/acpi.h| 6 ++
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 940218f..f26fc1d 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -40,10 +40,8 @@ int acpi_sysfs_init(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
-int acpi_ioapic_add(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
-static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ccdc8db..2449377 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -189,13 +189,13 @@ exit:
return AE_OK;
 }
 
-int acpi_ioapic_add(struct acpi_pci_root *root)
+int acpi_ioapic_add(acpi_handle root_handle)
 {
acpi_status status, retval = AE_OK;
 
-   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle,
+   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
 UINT_MAX, handle_ioapic_add, NULL,
-root->device->handle, (void **));
+root_handle, (void **));
 
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d144168..b07eda1 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,7 +614,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
-   acpi_ioapic_add(root);
+   acpi_ioapic_add(root->device->handle);
}
 
pci_lock_rescan_remove();
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 4d8452c..c9a596b 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -751,6 +751,12 @@ static inline int acpi_reconfig_notifier_unregister(struct 
notifier_block *nb)
 
 #endif /* !CONFIG_ACPI */
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+int acpi_ioapic_add(acpi_handle root);
+#else
+static inline int acpi_ioapic_add(acpi_handle root) { return 0; }
+#endif
+
 #ifdef CONFIG_ACPI
 void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
   u32 pm1a_ctrl,  u32 pm1b_ctrl));


[PATCH v4 4/5] x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd

2016-08-17 Thread Rui Wang
IOAPIC resource at 0xfecx gets lost from /proc/iomem after
hot-removing and then hot-adding the IOAPIC device.

After system boot, in /proc/iomem:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

Then hot-remove IOAPIC 2 and hot-add it again:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

The range at 0xfec4 is lost from /proc/iomem. It is because
handle_ioapic_add() requests resource from either PCI config BAR or
ACPI "_CRS", not both. But Intel platforms map the IOxAPIC registers
both at the PCI config BAR (called MBAR, dynamic), and at the ACPI
"_CRS" (called ABAR, static). The 0xfecX_YZ00 to 0xfecX_YZFF range
appears in "_CRS" of each IOAPIC device. Both ranges should be claimed
from /proc/iomem for exclusive use.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/ioapic.c | 36 
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 8ab6d42..ee20111 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -97,7 +97,7 @@ static acpi_status handle_ioapic_add(acpi_handle handle, u32 
lvl,
unsigned long long gsi_base;
struct acpi_pci_ioapic *ioapic;
struct pci_dev *dev = NULL;
-   struct resource *res = NULL;
+   struct resource *res = NULL, *pci_res = NULL, *crs_res;
char *type = NULL;
 
if (!acpi_is_ioapic(handle, ))
@@ -137,23 +137,28 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
pci_set_master(dev);
if (pci_request_region(dev, 0, type))
goto exit_disable;
-   res = >resource[0];
+   pci_res = >resource[0];
ioapic->pdev = dev;
} else {
pci_dev_put(dev);
dev = NULL;
+   }
 
-   res = >res;
-   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, res);
-   if (res->flags == 0) {
-   acpi_handle_warn(handle, "failed to get resource\n");
-   goto exit_free;
-   } else if (request_resource(_resource, res)) {
-   acpi_handle_warn(handle, "failed to insert resource\n");
-   goto exit_free;
-   }
+   crs_res = >res;
+   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   if (crs_res->flags == 0) {
+   acpi_handle_warn(handle, "failed to get resource\n");
+   goto exit_release;
+   } else if (request_resource(_resource, crs_res)) {
+   acpi_handle_warn(handle, "failed to insert resource\n");
+   goto exit_release;
}
 
+   /* try pci resource first, then "_CRS" resource */
+   res = pci_res;
+   if (!res || !res->flags)
+   res = crs_res;
+
if (acpi_register_ioapic(handle, res->start, (u32)gsi_base)) {
acpi_handle_warn(handle, "failed to register IOAPIC\n");
goto exit_release;
@@ -174,14 +179,13 @@ done:
 exit_release:
if (dev)
pci_release_region(dev, 0);
-   else
-   release_resource(res);
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
 exit_disable:
if (dev)
pci_disable_device(dev);
 exit_put:
pci_dev_put(dev);
-exit_free:
kfree(ioapic);
 exit:
mutex_unlock(_list_lock);
@@ -217,9 +221,9 @@ int acpi_ioapic_remove(struct acpi_pci_root *root)
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
-   } else if (ioapic->res.flags && ioapic->res.parent) {
-   release_resource(>res);
}
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
list_del(>list);
kfree(ioapic);
}
-- 
1.8.3.1



[PATCH v4 4/5] x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd

2016-08-17 Thread Rui Wang
IOAPIC resource at 0xfecx gets lost from /proc/iomem after
hot-removing and then hot-adding the IOAPIC device.

After system boot, in /proc/iomem:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

Then hot-remove IOAPIC 2 and hot-add it again:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

The range at 0xfec4 is lost from /proc/iomem. It is because
handle_ioapic_add() requests resource from either PCI config BAR or
ACPI "_CRS", not both. But Intel platforms map the IOxAPIC registers
both at the PCI config BAR (called MBAR, dynamic), and at the ACPI
"_CRS" (called ABAR, static). The 0xfecX_YZ00 to 0xfecX_YZFF range
appears in "_CRS" of each IOAPIC device. Both ranges should be claimed
from /proc/iomem for exclusive use.

Signed-off-by: Rui Wang 
---
 drivers/acpi/ioapic.c | 36 
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 8ab6d42..ee20111 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -97,7 +97,7 @@ static acpi_status handle_ioapic_add(acpi_handle handle, u32 
lvl,
unsigned long long gsi_base;
struct acpi_pci_ioapic *ioapic;
struct pci_dev *dev = NULL;
-   struct resource *res = NULL;
+   struct resource *res = NULL, *pci_res = NULL, *crs_res;
char *type = NULL;
 
if (!acpi_is_ioapic(handle, ))
@@ -137,23 +137,28 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
pci_set_master(dev);
if (pci_request_region(dev, 0, type))
goto exit_disable;
-   res = >resource[0];
+   pci_res = >resource[0];
ioapic->pdev = dev;
} else {
pci_dev_put(dev);
dev = NULL;
+   }
 
-   res = >res;
-   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, res);
-   if (res->flags == 0) {
-   acpi_handle_warn(handle, "failed to get resource\n");
-   goto exit_free;
-   } else if (request_resource(_resource, res)) {
-   acpi_handle_warn(handle, "failed to insert resource\n");
-   goto exit_free;
-   }
+   crs_res = >res;
+   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   if (crs_res->flags == 0) {
+   acpi_handle_warn(handle, "failed to get resource\n");
+   goto exit_release;
+   } else if (request_resource(_resource, crs_res)) {
+   acpi_handle_warn(handle, "failed to insert resource\n");
+   goto exit_release;
}
 
+   /* try pci resource first, then "_CRS" resource */
+   res = pci_res;
+   if (!res || !res->flags)
+   res = crs_res;
+
if (acpi_register_ioapic(handle, res->start, (u32)gsi_base)) {
acpi_handle_warn(handle, "failed to register IOAPIC\n");
goto exit_release;
@@ -174,14 +179,13 @@ done:
 exit_release:
if (dev)
pci_release_region(dev, 0);
-   else
-   release_resource(res);
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
 exit_disable:
if (dev)
pci_disable_device(dev);
 exit_put:
pci_dev_put(dev);
-exit_free:
kfree(ioapic);
 exit:
mutex_unlock(_list_lock);
@@ -217,9 +221,9 @@ int acpi_ioapic_remove(struct acpi_pci_root *root)
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
-   } else if (ioapic->res.flags && ioapic->res.parent) {
-   release_resource(>res);
}
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
list_del(>list);
kfree(ioapic);
}
-- 
1.8.3.1



[PATCH v4 1/5] x86/ioapic: Change prototype of acpi_ioapic_add()

2016-08-17 Thread Rui Wang
Change the argument of acpi_ioapic_add() to a generic ACPI handle, and
move its prototype from drivers/acpi/internal.h to include/linux/acpi.h
so that it can be called from outside the pci_root driver.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/internal.h | 2 --
 drivers/acpi/ioapic.c   | 6 +++---
 drivers/acpi/pci_root.c | 2 +-
 include/linux/acpi.h| 6 ++
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 940218f..f26fc1d 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -40,10 +40,8 @@ int acpi_sysfs_init(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
-int acpi_ioapic_add(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
-static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ccdc8db..2449377 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -189,13 +189,13 @@ exit:
return AE_OK;
 }
 
-int acpi_ioapic_add(struct acpi_pci_root *root)
+int acpi_ioapic_add(acpi_handle root_handle)
 {
acpi_status status, retval = AE_OK;
 
-   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle,
+   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
 UINT_MAX, handle_ioapic_add, NULL,
-root->device->handle, (void **));
+root_handle, (void **));
 
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d144168..b07eda1 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,7 +614,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
-   acpi_ioapic_add(root);
+   acpi_ioapic_add(root->device->handle);
}
 
pci_lock_rescan_remove();
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 4d8452c..c9a596b 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -751,6 +751,12 @@ static inline int acpi_reconfig_notifier_unregister(struct 
notifier_block *nb)
 
 #endif /* !CONFIG_ACPI */
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+int acpi_ioapic_add(acpi_handle root);
+#else
+static inline int acpi_ioapic_add(acpi_handle root) { return 0; }
+#endif
+
 #ifdef CONFIG_ACPI
 void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
   u32 pm1a_ctrl,  u32 pm1b_ctrl));
-- 
1.8.3.1



[PATCH v4 2/5] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-08-17 Thread Rui Wang
IOAPICs present during system boot aren't added to ioapic_list,
thus are unable to be hot-removed. Fix it by calling
acpi_ioapic_add() during root bus enumeration.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
Acked-by: Bjorn Helgaas <bhelg...@google.com>
---
 drivers/acpi/pci_root.c | 10 ++
 drivers/pci/setup-bus.c |  5 -
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index b07eda1..bf601d4 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,6 +614,16 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
+   /*
+* This is only called for the hotadd case. For the boot-time
+* case, we need to wait until after PCI initialization in
+* order to deal with IOAPICs mapped in on a PCI BAR.
+*
+* This is currently x86-specific, because acpi_ioapic_add()
+* is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC.
+* And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC
+* (see drivers/acpi/Kconfig).
+*/
acpi_ioapic_add(root->device->handle);
}
 
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index c74059e..ec538d3 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pci.h"
 
 unsigned int pci_flags;
@@ -1852,8 +1853,10 @@ void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
 
-   list_for_each_entry(root_bus, _root_buses, node)
+   list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   }
 }
 
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
-- 
1.8.3.1



[PATCH v4 1/5] x86/ioapic: Change prototype of acpi_ioapic_add()

2016-08-17 Thread Rui Wang
Change the argument of acpi_ioapic_add() to a generic ACPI handle, and
move its prototype from drivers/acpi/internal.h to include/linux/acpi.h
so that it can be called from outside the pci_root driver.

Signed-off-by: Rui Wang 
---
 drivers/acpi/internal.h | 2 --
 drivers/acpi/ioapic.c   | 6 +++---
 drivers/acpi/pci_root.c | 2 +-
 include/linux/acpi.h| 6 ++
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 940218f..f26fc1d 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -40,10 +40,8 @@ int acpi_sysfs_init(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
-int acpi_ioapic_add(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
-static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ccdc8db..2449377 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -189,13 +189,13 @@ exit:
return AE_OK;
 }
 
-int acpi_ioapic_add(struct acpi_pci_root *root)
+int acpi_ioapic_add(acpi_handle root_handle)
 {
acpi_status status, retval = AE_OK;
 
-   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle,
+   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
 UINT_MAX, handle_ioapic_add, NULL,
-root->device->handle, (void **));
+root_handle, (void **));
 
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d144168..b07eda1 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,7 +614,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
-   acpi_ioapic_add(root);
+   acpi_ioapic_add(root->device->handle);
}
 
pci_lock_rescan_remove();
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 4d8452c..c9a596b 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -751,6 +751,12 @@ static inline int acpi_reconfig_notifier_unregister(struct 
notifier_block *nb)
 
 #endif /* !CONFIG_ACPI */
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+int acpi_ioapic_add(acpi_handle root);
+#else
+static inline int acpi_ioapic_add(acpi_handle root) { return 0; }
+#endif
+
 #ifdef CONFIG_ACPI
 void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
   u32 pm1a_ctrl,  u32 pm1b_ctrl));
-- 
1.8.3.1



[PATCH v4 2/5] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-08-17 Thread Rui Wang
IOAPICs present during system boot aren't added to ioapic_list,
thus are unable to be hot-removed. Fix it by calling
acpi_ioapic_add() during root bus enumeration.

Signed-off-by: Rui Wang 
Acked-by: Bjorn Helgaas 
---
 drivers/acpi/pci_root.c | 10 ++
 drivers/pci/setup-bus.c |  5 -
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index b07eda1..bf601d4 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,6 +614,16 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
+   /*
+* This is only called for the hotadd case. For the boot-time
+* case, we need to wait until after PCI initialization in
+* order to deal with IOAPICs mapped in on a PCI BAR.
+*
+* This is currently x86-specific, because acpi_ioapic_add()
+* is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC.
+* And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC
+* (see drivers/acpi/Kconfig).
+*/
acpi_ioapic_add(root->device->handle);
}
 
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index c74059e..ec538d3 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pci.h"
 
 unsigned int pci_flags;
@@ -1852,8 +1853,10 @@ void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
 
-   list_for_each_entry(root_bus, _root_buses, node)
+   list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   }
 }
 
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
-- 
1.8.3.1



[PATCH v4 5/5] x86/ioapic: Fix ioapic failing to request resource

2016-08-17 Thread Rui Wang
handle_ioapic_add() uses request_resource() to request ACPI "_CRS"
resources. This can fail with the following error message:

[  247.325693] ACPI: \_SB_.IIO1.AID1: failed to insert resource

This happens when there are multiple IOAPICs and DSDT groups their
"_CRS" resources as the children of a parent resource, as seen from
/proc/iomem:

fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2

In this case request_resource() fails because there's a conflicting
resource which is the parent (fec-fecf). Fix it by using
insert_resource() which can request resources by taking the conflicting
resource as the parent.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/ioapic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ee20111..6d7ce6e 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -146,10 +146,12 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
 
crs_res = >res;
acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   crs_res->name = type;
+   crs_res->flags |= IORESOURCE_BUSY;
if (crs_res->flags == 0) {
acpi_handle_warn(handle, "failed to get resource\n");
goto exit_release;
-   } else if (request_resource(_resource, crs_res)) {
+   } else if (insert_resource(_resource, crs_res)) {
acpi_handle_warn(handle, "failed to insert resource\n");
goto exit_release;
}
-- 
1.8.3.1



[PATCH v4 5/5] x86/ioapic: Fix ioapic failing to request resource

2016-08-17 Thread Rui Wang
handle_ioapic_add() uses request_resource() to request ACPI "_CRS"
resources. This can fail with the following error message:

[  247.325693] ACPI: \_SB_.IIO1.AID1: failed to insert resource

This happens when there are multiple IOAPICs and DSDT groups their
"_CRS" resources as the children of a parent resource, as seen from
/proc/iomem:

fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2

In this case request_resource() fails because there's a conflicting
resource which is the parent (fec-fecf). Fix it by using
insert_resource() which can request resources by taking the conflicting
resource as the parent.

Signed-off-by: Rui Wang 
---
 drivers/acpi/ioapic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ee20111..6d7ce6e 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -146,10 +146,12 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
 
crs_res = >res;
acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   crs_res->name = type;
+   crs_res->flags |= IORESOURCE_BUSY;
if (crs_res->flags == 0) {
acpi_handle_warn(handle, "failed to get resource\n");
goto exit_release;
-   } else if (request_resource(_resource, crs_res)) {
+   } else if (insert_resource(_resource, crs_res)) {
acpi_handle_warn(handle, "failed to insert resource\n");
goto exit_release;
}
-- 
1.8.3.1



[PATCH v4 0/5] Fixing a set of bugs for ioapic hotplug

2016-08-17 Thread Rui Wang
A set of patches fixing bugs found while testing IOAPIC hotplug.

Regards,
Rui

Changelog:

Changes from v3 to v4:
* Rebased on top of 4.8-rc2 and re-tested it.
* Added the missing 'Acked-by: Bjorn Helgaas <bhelg...@google.com>' in 0002.
* Sent to x...@kernel.org for review as suggested by Rafael.

Changes from v2 to v3:
* Rebased on top of 4.8-rc1 per Bjorn & Rafael.
* Improved the commit message of 0003, w/ clearer explanation.

Changes from v1 to v2:
* Split the first patch into two as advised by Bjorn: "would be nicer if
the interface change and header file munging were in a separate patch so
they wouldn't obscure the meat of the change, i.e., the addition of calls
to acpi_ioapic_add()."
* Removed acpi_ioapic_add() as an exported symbol.
* Fixed some typos, and s/acpi/ACPI/, s/ioapic/IOAPIC/ throughout.
* Fixed a warning from 0-day testing.

Rui Wang (5):
  x86/ioapic: Change prototype of acpi_ioapic_add()
  x86/ioapic: Support hot-removal of IOAPICs present during boot
  x86/ioapic: Fix setup_res() failing to get resource
  x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd
  x86/ioapic: Fix ioapic failing to request resource

 drivers/acpi/internal.h |  2 --
 drivers/acpi/ioapic.c   | 46 ++
 drivers/acpi/pci_root.c | 12 +++-
 drivers/pci/setup-bus.c |  5 -
 include/linux/acpi.h|  6 ++
 5 files changed, 47 insertions(+), 24 deletions(-)

-- 
1.8.3.1



[PATCH v4 0/5] Fixing a set of bugs for ioapic hotplug

2016-08-17 Thread Rui Wang
A set of patches fixing bugs found while testing IOAPIC hotplug.

Regards,
Rui

Changelog:

Changes from v3 to v4:
* Rebased on top of 4.8-rc2 and re-tested it.
* Added the missing 'Acked-by: Bjorn Helgaas ' in 0002.
* Sent to x...@kernel.org for review as suggested by Rafael.

Changes from v2 to v3:
* Rebased on top of 4.8-rc1 per Bjorn & Rafael.
* Improved the commit message of 0003, w/ clearer explanation.

Changes from v1 to v2:
* Split the first patch into two as advised by Bjorn: "would be nicer if
the interface change and header file munging were in a separate patch so
they wouldn't obscure the meat of the change, i.e., the addition of calls
to acpi_ioapic_add()."
* Removed acpi_ioapic_add() as an exported symbol.
* Fixed some typos, and s/acpi/ACPI/, s/ioapic/IOAPIC/ throughout.
* Fixed a warning from 0-day testing.

Rui Wang (5):
  x86/ioapic: Change prototype of acpi_ioapic_add()
  x86/ioapic: Support hot-removal of IOAPICs present during boot
  x86/ioapic: Fix setup_res() failing to get resource
  x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd
  x86/ioapic: Fix ioapic failing to request resource

 drivers/acpi/internal.h |  2 --
 drivers/acpi/ioapic.c   | 46 ++
 drivers/acpi/pci_root.c | 12 +++-
 drivers/pci/setup-bus.c |  5 -
 include/linux/acpi.h|  6 ++
 5 files changed, 47 insertions(+), 24 deletions(-)

-- 
1.8.3.1



[PATCH v4 3/5] x86/ioapic: Fix setup_res() failing to get resource

2016-08-17 Thread Rui Wang
acpi_dev_filter_resource_type() returns 0 on success, and 1 on failure.
A return value of zero means there's a matching resource, so we should
continue within setup_res() to get the resource.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/ioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 2449377..8ab6d42 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -46,7 +46,7 @@ static acpi_status setup_res(struct acpi_resource *acpi_res, 
void *data)
struct resource_win win;
 
res->flags = 0;
-   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM) == 0)
+   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
return AE_OK;
 
if (!acpi_dev_resource_memory(acpi_res, res)) {
-- 
1.8.3.1



[PATCH v4 3/5] x86/ioapic: Fix setup_res() failing to get resource

2016-08-17 Thread Rui Wang
acpi_dev_filter_resource_type() returns 0 on success, and 1 on failure.
A return value of zero means there's a matching resource, so we should
continue within setup_res() to get the resource.

Signed-off-by: Rui Wang 
---
 drivers/acpi/ioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 2449377..8ab6d42 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -46,7 +46,7 @@ static acpi_status setup_res(struct acpi_resource *acpi_res, 
void *data)
struct resource_win win;
 
res->flags = 0;
-   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM) == 0)
+   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
return AE_OK;
 
if (!acpi_dev_resource_memory(acpi_res, res)) {
-- 
1.8.3.1



[PATCH v3 0/5] Fixing a set of bugs for ioapic hotplug

2016-08-16 Thread Rui Wang
On Wed, Aug 17, 2016 8:36 AM Rafael J. Wysocki wrote:
> On Wednesday, August 10, 2016 12:01:53 PM Rui Wang wrote:
> > A set of patches fixing bugs found while testing IOAPIC hotplug.
> 
> This should have been posted to the x...@kernel.org list too for the benefit
> of the maintainers.
> 
> Can you please resend it with a CC to that one (and the Bjorn's ACK on the
> second patch)?
> 

Thanks for the advice.
Will do.

Regards,
Rui

> Thanks,
> Rafael
> 
> 
> > Changelog:
> >
> > Changes from v2 to v3:
> > * Rebased on top of 4.8-rc1 per Bjorn & Rafael.
> > * Improved the commit message of 0003, w/ clearer explanation.
> >
> > Changes from v1 to v2:
> > * Split the first patch into two as advised by Bjorn: "would be nicer
> > if the interface change and header file munging were in a separate
> > patch so they wouldn't obscure the meat of the change, i.e., the
> > addition of calls to acpi_ioapic_add()."
> > * Removed acpi_ioapic_add() as an exported symbol.
> > * Fixed some typos, and s/acpi/ACPI/, s/ioapic/IOAPIC/ throughout.
> > * Fixed a warning from 0-day testing.
> >
> > Rui Wang (5):
> >   x86/ioapic: Change prototype of acpi_ioapic_add()
> >   x86/ioapic: Support hot-removal of IOAPICs present during boot
> >   x86/ioapic: Fix setup_res() failing to get resource
> >   x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd
> >   x86/ioapic: Fix ioapic failing to request resource
> >
> >  drivers/acpi/internal.h |  2 --
> >  drivers/acpi/ioapic.c   | 46 ++-
> ---
> >  drivers/acpi/pci_root.c | 12 +++-  drivers/pci/setup-bus.c |
> > 5 -
> >  include/linux/acpi.h|  6 ++
> >  5 files changed, 47 insertions(+), 24 deletions(-)




[PATCH v3 0/5] Fixing a set of bugs for ioapic hotplug

2016-08-16 Thread Rui Wang
On Wed, Aug 17, 2016 8:36 AM Rafael J. Wysocki wrote:
> On Wednesday, August 10, 2016 12:01:53 PM Rui Wang wrote:
> > A set of patches fixing bugs found while testing IOAPIC hotplug.
> 
> This should have been posted to the x...@kernel.org list too for the benefit
> of the maintainers.
> 
> Can you please resend it with a CC to that one (and the Bjorn's ACK on the
> second patch)?
> 

Thanks for the advice.
Will do.

Regards,
Rui

> Thanks,
> Rafael
> 
> 
> > Changelog:
> >
> > Changes from v2 to v3:
> > * Rebased on top of 4.8-rc1 per Bjorn & Rafael.
> > * Improved the commit message of 0003, w/ clearer explanation.
> >
> > Changes from v1 to v2:
> > * Split the first patch into two as advised by Bjorn: "would be nicer
> > if the interface change and header file munging were in a separate
> > patch so they wouldn't obscure the meat of the change, i.e., the
> > addition of calls to acpi_ioapic_add()."
> > * Removed acpi_ioapic_add() as an exported symbol.
> > * Fixed some typos, and s/acpi/ACPI/, s/ioapic/IOAPIC/ throughout.
> > * Fixed a warning from 0-day testing.
> >
> > Rui Wang (5):
> >   x86/ioapic: Change prototype of acpi_ioapic_add()
> >   x86/ioapic: Support hot-removal of IOAPICs present during boot
> >   x86/ioapic: Fix setup_res() failing to get resource
> >   x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd
> >   x86/ioapic: Fix ioapic failing to request resource
> >
> >  drivers/acpi/internal.h |  2 --
> >  drivers/acpi/ioapic.c   | 46 ++-
> ---
> >  drivers/acpi/pci_root.c | 12 +++-  drivers/pci/setup-bus.c |
> > 5 -
> >  include/linux/acpi.h|  6 ++
> >  5 files changed, 47 insertions(+), 24 deletions(-)




[PATCH v3 4/5] x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd

2016-08-09 Thread Rui Wang
IOAPIC resource at 0xfecx gets lost from /proc/iomem after
hot-removing and then hot-adding the IOAPIC device.

After system boot, in /proc/iomem:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

Then hot-remove IOAPIC 2 and hot-add it again:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

The range at 0xfec4 is lost from /proc/iomem. It is because
handle_ioapic_add() requests resource from either PCI config BAR or
ACPI "_CRS", not both. But Intel platforms map the IOxAPIC registers
both at the PCI config BAR (called MBAR, dynamic), and at the ACPI
"_CRS" (called ABAR, static). The 0xfecX_YZ00 to 0xfecX_YZFF range
appears in "_CRS" of each IOAPIC device. Both ranges should be claimed
from /proc/iomem for exclusive use.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/ioapic.c | 36 
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 8ab6d42..ee20111 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -97,7 +97,7 @@ static acpi_status handle_ioapic_add(acpi_handle handle, u32 
lvl,
unsigned long long gsi_base;
struct acpi_pci_ioapic *ioapic;
struct pci_dev *dev = NULL;
-   struct resource *res = NULL;
+   struct resource *res = NULL, *pci_res = NULL, *crs_res;
char *type = NULL;
 
if (!acpi_is_ioapic(handle, ))
@@ -137,23 +137,28 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
pci_set_master(dev);
if (pci_request_region(dev, 0, type))
goto exit_disable;
-   res = >resource[0];
+   pci_res = >resource[0];
ioapic->pdev = dev;
} else {
pci_dev_put(dev);
dev = NULL;
+   }
 
-   res = >res;
-   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, res);
-   if (res->flags == 0) {
-   acpi_handle_warn(handle, "failed to get resource\n");
-   goto exit_free;
-   } else if (request_resource(_resource, res)) {
-   acpi_handle_warn(handle, "failed to insert resource\n");
-   goto exit_free;
-   }
+   crs_res = >res;
+   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   if (crs_res->flags == 0) {
+   acpi_handle_warn(handle, "failed to get resource\n");
+   goto exit_release;
+   } else if (request_resource(_resource, crs_res)) {
+   acpi_handle_warn(handle, "failed to insert resource\n");
+   goto exit_release;
}
 
+   /* try pci resource first, then "_CRS" resource */
+   res = pci_res;
+   if (!res || !res->flags)
+   res = crs_res;
+
if (acpi_register_ioapic(handle, res->start, (u32)gsi_base)) {
acpi_handle_warn(handle, "failed to register IOAPIC\n");
goto exit_release;
@@ -174,14 +179,13 @@ done:
 exit_release:
if (dev)
pci_release_region(dev, 0);
-   else
-   release_resource(res);
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
 exit_disable:
if (dev)
pci_disable_device(dev);
 exit_put:
pci_dev_put(dev);
-exit_free:
kfree(ioapic);
 exit:
mutex_unlock(_list_lock);
@@ -217,9 +221,9 @@ int acpi_ioapic_remove(struct acpi_pci_root *root)
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
-   } else if (ioapic->res.flags && ioapic->res.parent) {
-   release_resource(>res);
}
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
list_del(>list);
kfree(ioapic);
}
-- 
1.8.3.1



[PATCH v3 2/5] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-08-09 Thread Rui Wang
IOAPICs present during system boot aren't added to ioapic_list,
thus are unable to be hot-removed. Fix it by calling
acpi_ioapic_add() during root bus enumeration.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/pci_root.c | 10 ++
 drivers/pci/setup-bus.c |  5 -
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index b07eda1..bf601d4 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,6 +614,16 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
+   /*
+* This is only called for the hotadd case. For the boot-time
+* case, we need to wait until after PCI initialization in
+* order to deal with IOAPICs mapped in on a PCI BAR.
+*
+* This is currently x86-specific, because acpi_ioapic_add()
+* is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC.
+* And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC
+* (see drivers/acpi/Kconfig).
+*/
acpi_ioapic_add(root->device->handle);
}
 
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index c74059e..ec538d3 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pci.h"
 
 unsigned int pci_flags;
@@ -1852,8 +1853,10 @@ void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
 
-   list_for_each_entry(root_bus, _root_buses, node)
+   list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   }
 }
 
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
-- 
1.8.3.1



[PATCH v3 1/5] x86/ioapic: Change prototype of acpi_ioapic_add()

2016-08-09 Thread Rui Wang
Change the argument of acpi_ioapic_add() to a generic ACPI handle, and
move its prototype from drivers/acpi/internal.h to include/linux/acpi.h
so that it can be called from outside the pci_root driver.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/internal.h | 2 --
 drivers/acpi/ioapic.c   | 6 +++---
 drivers/acpi/pci_root.c | 2 +-
 include/linux/acpi.h| 6 ++
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 940218f..f26fc1d 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -40,10 +40,8 @@ int acpi_sysfs_init(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
-int acpi_ioapic_add(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
-static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ccdc8db..2449377 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -189,13 +189,13 @@ exit:
return AE_OK;
 }
 
-int acpi_ioapic_add(struct acpi_pci_root *root)
+int acpi_ioapic_add(acpi_handle root_handle)
 {
acpi_status status, retval = AE_OK;
 
-   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle,
+   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
 UINT_MAX, handle_ioapic_add, NULL,
-root->device->handle, (void **));
+root_handle, (void **));
 
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d144168..b07eda1 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,7 +614,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
-   acpi_ioapic_add(root);
+   acpi_ioapic_add(root->device->handle);
}
 
pci_lock_rescan_remove();
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 4d8452c..c9a596b 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -751,6 +751,12 @@ static inline int acpi_reconfig_notifier_unregister(struct 
notifier_block *nb)
 
 #endif /* !CONFIG_ACPI */
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+int acpi_ioapic_add(acpi_handle root);
+#else
+static inline int acpi_ioapic_add(acpi_handle root) { return 0; }
+#endif
+
 #ifdef CONFIG_ACPI
 void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
   u32 pm1a_ctrl,  u32 pm1b_ctrl));
-- 
1.8.3.1



[PATCH v3 4/5] x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd

2016-08-09 Thread Rui Wang
IOAPIC resource at 0xfecx gets lost from /proc/iomem after
hot-removing and then hot-adding the IOAPIC device.

After system boot, in /proc/iomem:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

Then hot-remove IOAPIC 2 and hot-add it again:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

The range at 0xfec4 is lost from /proc/iomem. It is because
handle_ioapic_add() requests resource from either PCI config BAR or
ACPI "_CRS", not both. But Intel platforms map the IOxAPIC registers
both at the PCI config BAR (called MBAR, dynamic), and at the ACPI
"_CRS" (called ABAR, static). The 0xfecX_YZ00 to 0xfecX_YZFF range
appears in "_CRS" of each IOAPIC device. Both ranges should be claimed
from /proc/iomem for exclusive use.

Signed-off-by: Rui Wang 
---
 drivers/acpi/ioapic.c | 36 
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 8ab6d42..ee20111 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -97,7 +97,7 @@ static acpi_status handle_ioapic_add(acpi_handle handle, u32 
lvl,
unsigned long long gsi_base;
struct acpi_pci_ioapic *ioapic;
struct pci_dev *dev = NULL;
-   struct resource *res = NULL;
+   struct resource *res = NULL, *pci_res = NULL, *crs_res;
char *type = NULL;
 
if (!acpi_is_ioapic(handle, ))
@@ -137,23 +137,28 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
pci_set_master(dev);
if (pci_request_region(dev, 0, type))
goto exit_disable;
-   res = >resource[0];
+   pci_res = >resource[0];
ioapic->pdev = dev;
} else {
pci_dev_put(dev);
dev = NULL;
+   }
 
-   res = >res;
-   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, res);
-   if (res->flags == 0) {
-   acpi_handle_warn(handle, "failed to get resource\n");
-   goto exit_free;
-   } else if (request_resource(_resource, res)) {
-   acpi_handle_warn(handle, "failed to insert resource\n");
-   goto exit_free;
-   }
+   crs_res = >res;
+   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   if (crs_res->flags == 0) {
+   acpi_handle_warn(handle, "failed to get resource\n");
+   goto exit_release;
+   } else if (request_resource(_resource, crs_res)) {
+   acpi_handle_warn(handle, "failed to insert resource\n");
+   goto exit_release;
}
 
+   /* try pci resource first, then "_CRS" resource */
+   res = pci_res;
+   if (!res || !res->flags)
+   res = crs_res;
+
if (acpi_register_ioapic(handle, res->start, (u32)gsi_base)) {
acpi_handle_warn(handle, "failed to register IOAPIC\n");
goto exit_release;
@@ -174,14 +179,13 @@ done:
 exit_release:
if (dev)
pci_release_region(dev, 0);
-   else
-   release_resource(res);
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
 exit_disable:
if (dev)
pci_disable_device(dev);
 exit_put:
pci_dev_put(dev);
-exit_free:
kfree(ioapic);
 exit:
mutex_unlock(_list_lock);
@@ -217,9 +221,9 @@ int acpi_ioapic_remove(struct acpi_pci_root *root)
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
-   } else if (ioapic->res.flags && ioapic->res.parent) {
-   release_resource(>res);
}
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
list_del(>list);
kfree(ioapic);
}
-- 
1.8.3.1



[PATCH v3 2/5] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-08-09 Thread Rui Wang
IOAPICs present during system boot aren't added to ioapic_list,
thus are unable to be hot-removed. Fix it by calling
acpi_ioapic_add() during root bus enumeration.

Signed-off-by: Rui Wang 
---
 drivers/acpi/pci_root.c | 10 ++
 drivers/pci/setup-bus.c |  5 -
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index b07eda1..bf601d4 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,6 +614,16 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
+   /*
+* This is only called for the hotadd case. For the boot-time
+* case, we need to wait until after PCI initialization in
+* order to deal with IOAPICs mapped in on a PCI BAR.
+*
+* This is currently x86-specific, because acpi_ioapic_add()
+* is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC.
+* And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC
+* (see drivers/acpi/Kconfig).
+*/
acpi_ioapic_add(root->device->handle);
}
 
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index c74059e..ec538d3 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pci.h"
 
 unsigned int pci_flags;
@@ -1852,8 +1853,10 @@ void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
 
-   list_for_each_entry(root_bus, _root_buses, node)
+   list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   }
 }
 
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
-- 
1.8.3.1



[PATCH v3 1/5] x86/ioapic: Change prototype of acpi_ioapic_add()

2016-08-09 Thread Rui Wang
Change the argument of acpi_ioapic_add() to a generic ACPI handle, and
move its prototype from drivers/acpi/internal.h to include/linux/acpi.h
so that it can be called from outside the pci_root driver.

Signed-off-by: Rui Wang 
---
 drivers/acpi/internal.h | 2 --
 drivers/acpi/ioapic.c   | 6 +++---
 drivers/acpi/pci_root.c | 2 +-
 include/linux/acpi.h| 6 ++
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 940218f..f26fc1d 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -40,10 +40,8 @@ int acpi_sysfs_init(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
-int acpi_ioapic_add(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
-static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ccdc8db..2449377 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -189,13 +189,13 @@ exit:
return AE_OK;
 }
 
-int acpi_ioapic_add(struct acpi_pci_root *root)
+int acpi_ioapic_add(acpi_handle root_handle)
 {
acpi_status status, retval = AE_OK;
 
-   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle,
+   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
 UINT_MAX, handle_ioapic_add, NULL,
-root->device->handle, (void **));
+root_handle, (void **));
 
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d144168..b07eda1 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,7 +614,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
-   acpi_ioapic_add(root);
+   acpi_ioapic_add(root->device->handle);
}
 
pci_lock_rescan_remove();
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 4d8452c..c9a596b 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -751,6 +751,12 @@ static inline int acpi_reconfig_notifier_unregister(struct 
notifier_block *nb)
 
 #endif /* !CONFIG_ACPI */
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+int acpi_ioapic_add(acpi_handle root);
+#else
+static inline int acpi_ioapic_add(acpi_handle root) { return 0; }
+#endif
+
 #ifdef CONFIG_ACPI
 void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
   u32 pm1a_ctrl,  u32 pm1b_ctrl));
-- 
1.8.3.1



[PATCH v3 0/5] Fixing a set of bugs for ioapic hotplug

2016-08-09 Thread Rui Wang
A set of patches fixing bugs found while testing IOAPIC hotplug.

Regards,
Rui

Changelog:

Changes from v2 to v3:
* Rebased on top of 4.8-rc1 per Bjorn & Rafael.
* Improved the commit message of 0003, w/ clearer explanation.

Changes from v1 to v2:
* Split the first patch into two as advised by Bjorn: "would be nicer if
the interface change and header file munging were in a separate patch so
they wouldn't obscure the meat of the change, i.e., the addition of calls
to acpi_ioapic_add()."
* Removed acpi_ioapic_add() as an exported symbol.
* Fixed some typos, and s/acpi/ACPI/, s/ioapic/IOAPIC/ throughout.
* Fixed a warning from 0-day testing.

Rui Wang (5):
  x86/ioapic: Change prototype of acpi_ioapic_add()
  x86/ioapic: Support hot-removal of IOAPICs present during boot
  x86/ioapic: Fix setup_res() failing to get resource
  x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd
  x86/ioapic: Fix ioapic failing to request resource

 drivers/acpi/internal.h |  2 --
 drivers/acpi/ioapic.c   | 46 ++
 drivers/acpi/pci_root.c | 12 +++-
 drivers/pci/setup-bus.c |  5 -
 include/linux/acpi.h|  6 ++
 5 files changed, 47 insertions(+), 24 deletions(-)

-- 
1.8.3.1



[PATCH v3 0/5] Fixing a set of bugs for ioapic hotplug

2016-08-09 Thread Rui Wang
A set of patches fixing bugs found while testing IOAPIC hotplug.

Regards,
Rui

Changelog:

Changes from v2 to v3:
* Rebased on top of 4.8-rc1 per Bjorn & Rafael.
* Improved the commit message of 0003, w/ clearer explanation.

Changes from v1 to v2:
* Split the first patch into two as advised by Bjorn: "would be nicer if
the interface change and header file munging were in a separate patch so
they wouldn't obscure the meat of the change, i.e., the addition of calls
to acpi_ioapic_add()."
* Removed acpi_ioapic_add() as an exported symbol.
* Fixed some typos, and s/acpi/ACPI/, s/ioapic/IOAPIC/ throughout.
* Fixed a warning from 0-day testing.

Rui Wang (5):
  x86/ioapic: Change prototype of acpi_ioapic_add()
  x86/ioapic: Support hot-removal of IOAPICs present during boot
  x86/ioapic: Fix setup_res() failing to get resource
  x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd
  x86/ioapic: Fix ioapic failing to request resource

 drivers/acpi/internal.h |  2 --
 drivers/acpi/ioapic.c   | 46 ++
 drivers/acpi/pci_root.c | 12 +++-
 drivers/pci/setup-bus.c |  5 -
 include/linux/acpi.h|  6 ++
 5 files changed, 47 insertions(+), 24 deletions(-)

-- 
1.8.3.1



[PATCH v3 3/5] x86/ioapic: Fix setup_res() failing to get resource

2016-08-09 Thread Rui Wang
acpi_dev_filter_resource_type() returns 0 on success, and 1 on failure.
A return value of zero means there's a matching resource, so we should
continue within setup_res() to get the resource.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/ioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 2449377..8ab6d42 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -46,7 +46,7 @@ static acpi_status setup_res(struct acpi_resource *acpi_res, 
void *data)
struct resource_win win;
 
res->flags = 0;
-   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM) == 0)
+   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
return AE_OK;
 
if (!acpi_dev_resource_memory(acpi_res, res)) {
-- 
1.8.3.1



[PATCH v3 5/5] x86/ioapic: Fix ioapic failing to request resource

2016-08-09 Thread Rui Wang
handle_ioapic_add() uses request_resource() to request ACPI "_CRS"
resources. This can fail with the following error message:

[  247.325693] ACPI: \_SB_.IIO1.AID1: failed to insert resource

This happens when there are multiple IOAPICs and DSDT groups their
"_CRS" resources as the children of a parent resource, as seen from
/proc/iomem:

fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2

In this case request_resource() fails because there's a conflicting
resource which is the parent (fec-fecf). Fix it by using
insert_resource() which can request resources by taking the conflicting
resource as the parent.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/ioapic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ee20111..6d7ce6e 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -146,10 +146,12 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
 
crs_res = >res;
acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   crs_res->name = type;
+   crs_res->flags |= IORESOURCE_BUSY;
if (crs_res->flags == 0) {
acpi_handle_warn(handle, "failed to get resource\n");
goto exit_release;
-   } else if (request_resource(_resource, crs_res)) {
+   } else if (insert_resource(_resource, crs_res)) {
acpi_handle_warn(handle, "failed to insert resource\n");
goto exit_release;
}
-- 
1.8.3.1



[PATCH v3 3/5] x86/ioapic: Fix setup_res() failing to get resource

2016-08-09 Thread Rui Wang
acpi_dev_filter_resource_type() returns 0 on success, and 1 on failure.
A return value of zero means there's a matching resource, so we should
continue within setup_res() to get the resource.

Signed-off-by: Rui Wang 
---
 drivers/acpi/ioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 2449377..8ab6d42 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -46,7 +46,7 @@ static acpi_status setup_res(struct acpi_resource *acpi_res, 
void *data)
struct resource_win win;
 
res->flags = 0;
-   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM) == 0)
+   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
return AE_OK;
 
if (!acpi_dev_resource_memory(acpi_res, res)) {
-- 
1.8.3.1



[PATCH v3 5/5] x86/ioapic: Fix ioapic failing to request resource

2016-08-09 Thread Rui Wang
handle_ioapic_add() uses request_resource() to request ACPI "_CRS"
resources. This can fail with the following error message:

[  247.325693] ACPI: \_SB_.IIO1.AID1: failed to insert resource

This happens when there are multiple IOAPICs and DSDT groups their
"_CRS" resources as the children of a parent resource, as seen from
/proc/iomem:

fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2

In this case request_resource() fails because there's a conflicting
resource which is the parent (fec-fecf). Fix it by using
insert_resource() which can request resources by taking the conflicting
resource as the parent.

Signed-off-by: Rui Wang 
---
 drivers/acpi/ioapic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ee20111..6d7ce6e 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -146,10 +146,12 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
 
crs_res = >res;
acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   crs_res->name = type;
+   crs_res->flags |= IORESOURCE_BUSY;
if (crs_res->flags == 0) {
acpi_handle_warn(handle, "failed to get resource\n");
goto exit_release;
-   } else if (request_resource(_resource, crs_res)) {
+   } else if (insert_resource(_resource, crs_res)) {
acpi_handle_warn(handle, "failed to insert resource\n");
goto exit_release;
}
-- 
1.8.3.1



Re: [PATCH V5 1/3] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-08-08 Thread Rui Wang
On Tuesday, Aug 9, 2016 4:23 AM, Bjorn Helgaas wrote:
> On Sun, Jun 26, 2016 at 11:44:57AM +0800, Rui Wang wrote:
> > v5: Remove #ifdef CONFIG_X86 from setup-bus.c, making it neutral to
> archs.
> > v4: Add comments explaining when to call acpi_ioapic_add().
> > v3: Previous versions break mips. This version fixes it.
> >
> > IOAPICs present during system boot aren't added to ioapic_list, thus
> > are unable to be hot-removed. Fix it by calling
> > acpi_ioapic_add() during root bus enumeration.
> >
> > Signed-off-by: Rui Wang <rui.y.w...@intel.com>
> 
> Hi Rui,
> 
> Where are we at with this?  If there's anything that still needs to be merged,
> can you rebase it to v4.8-rc1 and post a new, complete, series?
> 
Hi Bjorn,

Yes. These patches are needed for IOAPIC hotplug to work.

So Thomas & Rafael, any advice?

Thanks
Rui



Re: [PATCH V5 1/3] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-08-08 Thread Rui Wang
On Tuesday, Aug 9, 2016 4:23 AM, Bjorn Helgaas wrote:
> On Sun, Jun 26, 2016 at 11:44:57AM +0800, Rui Wang wrote:
> > v5: Remove #ifdef CONFIG_X86 from setup-bus.c, making it neutral to
> archs.
> > v4: Add comments explaining when to call acpi_ioapic_add().
> > v3: Previous versions break mips. This version fixes it.
> >
> > IOAPICs present during system boot aren't added to ioapic_list, thus
> > are unable to be hot-removed. Fix it by calling
> > acpi_ioapic_add() during root bus enumeration.
> >
> > Signed-off-by: Rui Wang 
> 
> Hi Rui,
> 
> Where are we at with this?  If there's anything that still needs to be merged,
> can you rebase it to v4.8-rc1 and post a new, complete, series?
> 
Hi Bjorn,

Yes. These patches are needed for IOAPIC hotplug to work.

So Thomas & Rafael, any advice?

Thanks
Rui



[PATCH v2 0/5] Fixing a set of bugs for ioapic hotplug

2016-07-27 Thread Rui Wang
A set of patches fixing bugs found while testing IOAPIC hotplug.

Regards,
Rui

Changelog:

Changes from v1 to v2:
* Split the first patch into two as advised by Bjorn: "would be nicer if
the interface change and header file munging were in a separate patch so
they wouldn't obscure the meat of the change, i.e., the addition of calls
to acpi_ioapic_add()."
* Removed acpi_ioapic_add() as an exported symbol.
* Fixed some typos, and s/acpi/ACPI/, s/ioapic/IOAPIC/ throughout.
* Fixed a warning from 0-day testing.

Rui Wang (5):
  x86/ioapic: Change prototype of acpi_ioapic_add()
  x86/ioapic: Support hot-removal of IOAPICs present during boot
  x86/ioapic: Fix setup_res() failing to get resource
  x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd
  x86/ioapic: Fix ioapic failing to request resource

 drivers/acpi/internal.h |  2 --
 drivers/acpi/ioapic.c   | 46 ++
 drivers/acpi/pci_root.c | 12 +++-
 drivers/pci/setup-bus.c |  5 -
 include/linux/acpi.h|  6 ++
 5 files changed, 47 insertions(+), 24 deletions(-)

-- 
1.8.3.1



[PATCH v2 2/5] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-07-27 Thread Rui Wang
IOAPICs present during system boot aren't added to ioapic_list,
thus are unable to be hot-removed. Fix it by calling
acpi_ioapic_add() during root bus enumeration.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/pci_root.c | 10 ++
 drivers/pci/setup-bus.c |  5 -
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 53f5965..fa9c83a 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,6 +614,16 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
+   /*
+* This is only called for the hotadd case. For the boot-time
+* case, we need to wait until after PCI initialization in
+* order to deal with IOAPICs mapped in on a PCI BAR.
+*
+* This is currently x86-specific, because acpi_ioapic_add()
+* is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC.
+* And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC
+* (see drivers/acpi/Kconfig).
+*/
acpi_ioapic_add(root->device->handle);
}
 
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 55641a3..e32c356 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pci.h"
 
 unsigned int pci_flags;
@@ -1779,8 +1780,10 @@ void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
 
-   list_for_each_entry(root_bus, _root_buses, node)
+   list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   }
 }
 
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
-- 
1.8.3.1



[PATCH v2 1/5] x86/ioapic: Change prototype of acpi_ioapic_add()

2016-07-27 Thread Rui Wang
Change the argument of acpi_ioapic_add() to a generic ACPI handle, and
move its prototype from drivers/acpi/internal.h to include/linux/acpi.h
so that it can be called from outside the pci_root driver.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/internal.h | 2 --
 drivers/acpi/ioapic.c   | 6 +++---
 drivers/acpi/pci_root.c | 2 +-
 include/linux/acpi.h| 6 ++
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 27cc7fe..6d8e67e 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -40,10 +40,8 @@ int acpi_sysfs_init(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
-int acpi_ioapic_add(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
-static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ccdc8db..2449377 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -189,13 +189,13 @@ exit:
return AE_OK;
 }
 
-int acpi_ioapic_add(struct acpi_pci_root *root)
+int acpi_ioapic_add(acpi_handle root_handle)
 {
acpi_status status, retval = AE_OK;
 
-   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle,
+   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
 UINT_MAX, handle_ioapic_add, NULL,
-root->device->handle, (void **));
+root_handle, (void **));
 
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index ae3fe4e..53f5965 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,7 +614,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
-   acpi_ioapic_add(root);
+   acpi_ioapic_add(root->device->handle);
}
 
pci_lock_rescan_remove();
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 288fac5..f5114dc 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -680,6 +680,12 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct 
acpi_device *adev)
 
 #endif /* !CONFIG_ACPI */
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+int acpi_ioapic_add(acpi_handle root);
+#else
+static inline int acpi_ioapic_add(acpi_handle root) { return 0; }
+#endif
+
 #ifdef CONFIG_ACPI
 void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
   u32 pm1a_ctrl,  u32 pm1b_ctrl));
-- 
1.8.3.1



[PATCH v2 0/5] Fixing a set of bugs for ioapic hotplug

2016-07-27 Thread Rui Wang
A set of patches fixing bugs found while testing IOAPIC hotplug.

Regards,
Rui

Changelog:

Changes from v1 to v2:
* Split the first patch into two as advised by Bjorn: "would be nicer if
the interface change and header file munging were in a separate patch so
they wouldn't obscure the meat of the change, i.e., the addition of calls
to acpi_ioapic_add()."
* Removed acpi_ioapic_add() as an exported symbol.
* Fixed some typos, and s/acpi/ACPI/, s/ioapic/IOAPIC/ throughout.
* Fixed a warning from 0-day testing.

Rui Wang (5):
  x86/ioapic: Change prototype of acpi_ioapic_add()
  x86/ioapic: Support hot-removal of IOAPICs present during boot
  x86/ioapic: Fix setup_res() failing to get resource
  x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd
  x86/ioapic: Fix ioapic failing to request resource

 drivers/acpi/internal.h |  2 --
 drivers/acpi/ioapic.c   | 46 ++
 drivers/acpi/pci_root.c | 12 +++-
 drivers/pci/setup-bus.c |  5 -
 include/linux/acpi.h|  6 ++
 5 files changed, 47 insertions(+), 24 deletions(-)

-- 
1.8.3.1



[PATCH v2 2/5] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-07-27 Thread Rui Wang
IOAPICs present during system boot aren't added to ioapic_list,
thus are unable to be hot-removed. Fix it by calling
acpi_ioapic_add() during root bus enumeration.

Signed-off-by: Rui Wang 
---
 drivers/acpi/pci_root.c | 10 ++
 drivers/pci/setup-bus.c |  5 -
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 53f5965..fa9c83a 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,6 +614,16 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
+   /*
+* This is only called for the hotadd case. For the boot-time
+* case, we need to wait until after PCI initialization in
+* order to deal with IOAPICs mapped in on a PCI BAR.
+*
+* This is currently x86-specific, because acpi_ioapic_add()
+* is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC.
+* And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC
+* (see drivers/acpi/Kconfig).
+*/
acpi_ioapic_add(root->device->handle);
}
 
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 55641a3..e32c356 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pci.h"
 
 unsigned int pci_flags;
@@ -1779,8 +1780,10 @@ void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
 
-   list_for_each_entry(root_bus, _root_buses, node)
+   list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   }
 }
 
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
-- 
1.8.3.1



[PATCH v2 1/5] x86/ioapic: Change prototype of acpi_ioapic_add()

2016-07-27 Thread Rui Wang
Change the argument of acpi_ioapic_add() to a generic ACPI handle, and
move its prototype from drivers/acpi/internal.h to include/linux/acpi.h
so that it can be called from outside the pci_root driver.

Signed-off-by: Rui Wang 
---
 drivers/acpi/internal.h | 2 --
 drivers/acpi/ioapic.c   | 6 +++---
 drivers/acpi/pci_root.c | 2 +-
 include/linux/acpi.h| 6 ++
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 27cc7fe..6d8e67e 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -40,10 +40,8 @@ int acpi_sysfs_init(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
-int acpi_ioapic_add(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
-static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ccdc8db..2449377 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -189,13 +189,13 @@ exit:
return AE_OK;
 }
 
-int acpi_ioapic_add(struct acpi_pci_root *root)
+int acpi_ioapic_add(acpi_handle root_handle)
 {
acpi_status status, retval = AE_OK;
 
-   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle,
+   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
 UINT_MAX, handle_ioapic_add, NULL,
-root->device->handle, (void **));
+root_handle, (void **));
 
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index ae3fe4e..53f5965 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,7 +614,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
-   acpi_ioapic_add(root);
+   acpi_ioapic_add(root->device->handle);
}
 
pci_lock_rescan_remove();
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 288fac5..f5114dc 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -680,6 +680,12 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct 
acpi_device *adev)
 
 #endif /* !CONFIG_ACPI */
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+int acpi_ioapic_add(acpi_handle root);
+#else
+static inline int acpi_ioapic_add(acpi_handle root) { return 0; }
+#endif
+
 #ifdef CONFIG_ACPI
 void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
   u32 pm1a_ctrl,  u32 pm1b_ctrl));
-- 
1.8.3.1



[PATCH v2 4/5] x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd

2016-07-27 Thread Rui Wang
IOAPIC resource at 0xfecx gets lost from /proc/iomem after
hot-removing and then hot-adding the IOAPIC device.

After system boot, in /proc/iomem:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

Then hot-remove IOAPIC 2 and hot-add it again:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

The range at 0xfec4 is lost from /proc/iomem. It is because
handle_ioapic_add() requests resource from either PCI config BAR or
ACPI "_CRS", not both. But Intel platforms map the IOxAPIC registers
both at the PCI config BAR (called MBAR, dynamic), and at the ACPI
"_CRS" (called ABAR, static). The 0xfecX_YZ00 to 0xfecX_YZFF range
appears in "_CRS" of each IOAPIC device. Both ranges should be claimed
from /proc/iomem for exclusive use.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/ioapic.c | 36 
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 8ab6d42..ee20111 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -97,7 +97,7 @@ static acpi_status handle_ioapic_add(acpi_handle handle, u32 
lvl,
unsigned long long gsi_base;
struct acpi_pci_ioapic *ioapic;
struct pci_dev *dev = NULL;
-   struct resource *res = NULL;
+   struct resource *res = NULL, *pci_res = NULL, *crs_res;
char *type = NULL;
 
if (!acpi_is_ioapic(handle, ))
@@ -137,23 +137,28 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
pci_set_master(dev);
if (pci_request_region(dev, 0, type))
goto exit_disable;
-   res = >resource[0];
+   pci_res = >resource[0];
ioapic->pdev = dev;
} else {
pci_dev_put(dev);
dev = NULL;
+   }
 
-   res = >res;
-   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, res);
-   if (res->flags == 0) {
-   acpi_handle_warn(handle, "failed to get resource\n");
-   goto exit_free;
-   } else if (request_resource(_resource, res)) {
-   acpi_handle_warn(handle, "failed to insert resource\n");
-   goto exit_free;
-   }
+   crs_res = >res;
+   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   if (crs_res->flags == 0) {
+   acpi_handle_warn(handle, "failed to get resource\n");
+   goto exit_release;
+   } else if (request_resource(_resource, crs_res)) {
+   acpi_handle_warn(handle, "failed to insert resource\n");
+   goto exit_release;
}
 
+   /* try pci resource first, then "_CRS" resource */
+   res = pci_res;
+   if (!res || !res->flags)
+   res = crs_res;
+
if (acpi_register_ioapic(handle, res->start, (u32)gsi_base)) {
acpi_handle_warn(handle, "failed to register IOAPIC\n");
goto exit_release;
@@ -174,14 +179,13 @@ done:
 exit_release:
if (dev)
pci_release_region(dev, 0);
-   else
-   release_resource(res);
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
 exit_disable:
if (dev)
pci_disable_device(dev);
 exit_put:
pci_dev_put(dev);
-exit_free:
kfree(ioapic);
 exit:
mutex_unlock(_list_lock);
@@ -217,9 +221,9 @@ int acpi_ioapic_remove(struct acpi_pci_root *root)
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
-   } else if (ioapic->res.flags && ioapic->res.parent) {
-   release_resource(>res);
}
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
list_del(>list);
kfree(ioapic);
}
-- 
1.8.3.1



[PATCH v2 5/5] x86/ioapic: Fix ioapic failing to request resource

2016-07-27 Thread Rui Wang
handle_ioapic_add() uses request_resource() to request ACPI "_CRS"
resources. This can fail with the following error message:

[  247.325693] ACPI: \_SB_.IIO1.AID1: failed to insert resource

This happens when there are multiple IOAPICs and DSDT groups their
"_CRS" resources as the children of a parent resource, as seen from
/proc/iomem:

fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2

In this case request_resource() fails because there's a conflicting
resource which is the parent (fec-fecf). Fix it by using
insert_resource() which can request resources by taking the conflicting
resource as the parent.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/ioapic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ee20111..6d7ce6e 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -146,10 +146,12 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
 
crs_res = >res;
acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   crs_res->name = type;
+   crs_res->flags |= IORESOURCE_BUSY;
if (crs_res->flags == 0) {
acpi_handle_warn(handle, "failed to get resource\n");
goto exit_release;
-   } else if (request_resource(_resource, crs_res)) {
+   } else if (insert_resource(_resource, crs_res)) {
acpi_handle_warn(handle, "failed to insert resource\n");
goto exit_release;
}
-- 
1.8.3.1



[PATCH v2 5/5] x86/ioapic: Fix ioapic failing to request resource

2016-07-27 Thread Rui Wang
handle_ioapic_add() uses request_resource() to request ACPI "_CRS"
resources. This can fail with the following error message:

[  247.325693] ACPI: \_SB_.IIO1.AID1: failed to insert resource

This happens when there are multiple IOAPICs and DSDT groups their
"_CRS" resources as the children of a parent resource, as seen from
/proc/iomem:

fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2

In this case request_resource() fails because there's a conflicting
resource which is the parent (fec-fecf). Fix it by using
insert_resource() which can request resources by taking the conflicting
resource as the parent.

Signed-off-by: Rui Wang 
---
 drivers/acpi/ioapic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ee20111..6d7ce6e 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -146,10 +146,12 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
 
crs_res = >res;
acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   crs_res->name = type;
+   crs_res->flags |= IORESOURCE_BUSY;
if (crs_res->flags == 0) {
acpi_handle_warn(handle, "failed to get resource\n");
goto exit_release;
-   } else if (request_resource(_resource, crs_res)) {
+   } else if (insert_resource(_resource, crs_res)) {
acpi_handle_warn(handle, "failed to insert resource\n");
goto exit_release;
}
-- 
1.8.3.1



[PATCH v2 4/5] x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd

2016-07-27 Thread Rui Wang
IOAPIC resource at 0xfecx gets lost from /proc/iomem after
hot-removing and then hot-adding the IOAPIC device.

After system boot, in /proc/iomem:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

Then hot-remove IOAPIC 2 and hot-add it again:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

The range at 0xfec4 is lost from /proc/iomem. It is because
handle_ioapic_add() requests resource from either PCI config BAR or
ACPI "_CRS", not both. But Intel platforms map the IOxAPIC registers
both at the PCI config BAR (called MBAR, dynamic), and at the ACPI
"_CRS" (called ABAR, static). The 0xfecX_YZ00 to 0xfecX_YZFF range
appears in "_CRS" of each IOAPIC device. Both ranges should be claimed
from /proc/iomem for exclusive use.

Signed-off-by: Rui Wang 
---
 drivers/acpi/ioapic.c | 36 
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 8ab6d42..ee20111 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -97,7 +97,7 @@ static acpi_status handle_ioapic_add(acpi_handle handle, u32 
lvl,
unsigned long long gsi_base;
struct acpi_pci_ioapic *ioapic;
struct pci_dev *dev = NULL;
-   struct resource *res = NULL;
+   struct resource *res = NULL, *pci_res = NULL, *crs_res;
char *type = NULL;
 
if (!acpi_is_ioapic(handle, ))
@@ -137,23 +137,28 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
pci_set_master(dev);
if (pci_request_region(dev, 0, type))
goto exit_disable;
-   res = >resource[0];
+   pci_res = >resource[0];
ioapic->pdev = dev;
} else {
pci_dev_put(dev);
dev = NULL;
+   }
 
-   res = >res;
-   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, res);
-   if (res->flags == 0) {
-   acpi_handle_warn(handle, "failed to get resource\n");
-   goto exit_free;
-   } else if (request_resource(_resource, res)) {
-   acpi_handle_warn(handle, "failed to insert resource\n");
-   goto exit_free;
-   }
+   crs_res = >res;
+   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   if (crs_res->flags == 0) {
+   acpi_handle_warn(handle, "failed to get resource\n");
+   goto exit_release;
+   } else if (request_resource(_resource, crs_res)) {
+   acpi_handle_warn(handle, "failed to insert resource\n");
+   goto exit_release;
}
 
+   /* try pci resource first, then "_CRS" resource */
+   res = pci_res;
+   if (!res || !res->flags)
+   res = crs_res;
+
if (acpi_register_ioapic(handle, res->start, (u32)gsi_base)) {
acpi_handle_warn(handle, "failed to register IOAPIC\n");
goto exit_release;
@@ -174,14 +179,13 @@ done:
 exit_release:
if (dev)
pci_release_region(dev, 0);
-   else
-   release_resource(res);
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
 exit_disable:
if (dev)
pci_disable_device(dev);
 exit_put:
pci_dev_put(dev);
-exit_free:
kfree(ioapic);
 exit:
mutex_unlock(_list_lock);
@@ -217,9 +221,9 @@ int acpi_ioapic_remove(struct acpi_pci_root *root)
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
-   } else if (ioapic->res.flags && ioapic->res.parent) {
-   release_resource(>res);
}
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
list_del(>list);
kfree(ioapic);
}
-- 
1.8.3.1



[PATCH v2 3/5] x86/ioapic: Fix setup_res() failing to get resource

2016-07-27 Thread Rui Wang
setup_res() doesn't actually get any resource because it mistakenly
checks the return value of acpi_dev_filter_resource_type(), which
returns 0 on success, and 1 on failure. Fix it by taking the return
value of non-zero as failing to match the specified resource type.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/ioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 2449377..8ab6d42 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -46,7 +46,7 @@ static acpi_status setup_res(struct acpi_resource *acpi_res, 
void *data)
struct resource_win win;
 
res->flags = 0;
-   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM) == 0)
+   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
return AE_OK;
 
if (!acpi_dev_resource_memory(acpi_res, res)) {
-- 
1.8.3.1



[PATCH v2 3/5] x86/ioapic: Fix setup_res() failing to get resource

2016-07-27 Thread Rui Wang
setup_res() doesn't actually get any resource because it mistakenly
checks the return value of acpi_dev_filter_resource_type(), which
returns 0 on success, and 1 on failure. Fix it by taking the return
value of non-zero as failing to match the specified resource type.

Signed-off-by: Rui Wang 
---
 drivers/acpi/ioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 2449377..8ab6d42 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -46,7 +46,7 @@ static acpi_status setup_res(struct acpi_resource *acpi_res, 
void *data)
struct resource_win win;
 
res->flags = 0;
-   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM) == 0)
+   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
return AE_OK;
 
if (!acpi_dev_resource_memory(acpi_res, res)) {
-- 
1.8.3.1



Re: [PATCH 3/4] x86/ioapic: Fix lost ioapic resource after hot-removal and hotadd

2016-07-26 Thread Rui Wang
On Wed, July 27, 2016 4:24 AM, Bjorn Helgaas wrote:
> On Wed, Jul 27, 2016 at 12:13:16AM +0800, Rui Wang wrote:
> > ioapic resource at 0xfecx gets lost from /proc/iomem after
> > hot-removing and then hot-adding the ioapic devices.
> >
> > After system boot, in /proc/iomem:
> > fec0-fecf : PNP0003:00
> >   fec0-fec003ff : IOAPIC 0
> >   fec01000-fec013ff : IOAPIC 1
> >   fec4-fec403ff : IOAPIC 2
> >   fec8-fec803ff : IOAPIC 3
> >   fecc-fecc03ff : IOAPIC 4
> >
> > Then hot-remove IOAPIC 2 and hot-add it again:
> > fec0-fecf : PNP0003:00
> >   fec0-fec003ff : IOAPIC 0
> >   fec01000-fec013ff : IOAPIC 1
> >   fec8-fec803ff : IOAPIC 3
> >   fecc-fecc03ff : IOAPIC 4
> >
> > The range at 0xfec4 is lost from /proc/iomem. It is because
> > handle_ioapic_add() requests resource from either PCI config BAR or
> > acpi _CRS, not both. But Intel platforms map the IOxAPIC registers
> 
> s/acpi/ACPI/
> s/ioapic/IOAPIC/ throughout
> 
> > at both the PCI config BAR (called MBAR) and the 0xfecX_YZ00 to
> > 0xfecX_Y2FF range (called ABAR). Both of the ranges should be claimed
> 
> I guess you mean the 0xfecX_YZ00-0xfecX_Y2FF range appears in _CRS?

Yes. That range appears in _CRS for each IOAPIC. I'll make it cleaner in
the commit message.

Thanks
Rui


Re: [PATCH 3/4] x86/ioapic: Fix lost ioapic resource after hot-removal and hotadd

2016-07-26 Thread Rui Wang
On Wed, July 27, 2016 4:24 AM, Bjorn Helgaas wrote:
> On Wed, Jul 27, 2016 at 12:13:16AM +0800, Rui Wang wrote:
> > ioapic resource at 0xfecx gets lost from /proc/iomem after
> > hot-removing and then hot-adding the ioapic devices.
> >
> > After system boot, in /proc/iomem:
> > fec0-fecf : PNP0003:00
> >   fec0-fec003ff : IOAPIC 0
> >   fec01000-fec013ff : IOAPIC 1
> >   fec4-fec403ff : IOAPIC 2
> >   fec8-fec803ff : IOAPIC 3
> >   fecc-fecc03ff : IOAPIC 4
> >
> > Then hot-remove IOAPIC 2 and hot-add it again:
> > fec0-fecf : PNP0003:00
> >   fec0-fec003ff : IOAPIC 0
> >   fec01000-fec013ff : IOAPIC 1
> >   fec8-fec803ff : IOAPIC 3
> >   fecc-fecc03ff : IOAPIC 4
> >
> > The range at 0xfec4 is lost from /proc/iomem. It is because
> > handle_ioapic_add() requests resource from either PCI config BAR or
> > acpi _CRS, not both. But Intel platforms map the IOxAPIC registers
> 
> s/acpi/ACPI/
> s/ioapic/IOAPIC/ throughout
> 
> > at both the PCI config BAR (called MBAR) and the 0xfecX_YZ00 to
> > 0xfecX_Y2FF range (called ABAR). Both of the ranges should be claimed
> 
> I guess you mean the 0xfecX_YZ00-0xfecX_Y2FF range appears in _CRS?

Yes. That range appears in _CRS for each IOAPIC. I'll make it cleaner in
the commit message.

Thanks
Rui


Re: [PATCH 1/4] x86/ioapic: Support hot-removal of IOAPICs present during boot boot

2016-07-26 Thread Rui Wang
On Wed, July 27, 2016 4:20 AM Bjorn Helgaas wrote:
> On Wed, Jul 27, 2016 at 12:13:14AM +0800, Rui Wang wrote:
> > IOAPICs present during system boot aren't added to ioapic_list, thus
> > are unable to be hot-removed. Fix it by calling
> > acpi_ioapic_add() during root bus enumeration.
> >
> > Signed-off-by: Rui Wang <rui.y.w...@intel.com>
> > ---
> >  drivers/acpi/internal.h |  2 --
> >  drivers/acpi/ioapic.c   |  7 ---
> >  drivers/acpi/pci_root.c | 13 -  drivers/pci/setup-bus.c |
> > 5 -
> >  include/linux/acpi.h|  6 ++
> >  5 files changed, 26 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index
> > 27cc7fe..6d8e67e 100644
> > --- a/drivers/acpi/internal.h
> > +++ b/drivers/acpi/internal.h
> > @@ -40,10 +40,8 @@ int acpi_sysfs_init(void);  void
> > acpi_container_init(void);  void acpi_memory_hotplug_init(void);
> >  #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
> > -int acpi_ioapic_add(struct acpi_pci_root *root);  int
> > acpi_ioapic_remove(struct acpi_pci_root *root);  #else -static inline
> > int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
> 
> It would be nicer if the interface change and header file munging were in a
> separate patch so they wouldn't obscure the meat of the change, i.e., the
> addition of calls to acpi_ioapic_add().

Sure. I'll split it in a newer version.

> 
> >  static inline int acpi_ioapic_remove(struct acpi_pci_root *root) {
> > return 0; }  #endif  #ifdef CONFIG_ACPI_DOCK diff --git
> > a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c index ccdc8db..0f272e2
> > 100644
> > --- a/drivers/acpi/ioapic.c
> > +++ b/drivers/acpi/ioapic.c
> > @@ -189,16 +189,17 @@ exit:
> > return AE_OK;
> >  }
> >
> > -int acpi_ioapic_add(struct acpi_pci_root *root)
> > +int acpi_ioapic_add(acpi_handle root_handle)
> >  {
> > acpi_status status, retval = AE_OK;
> >
> > -   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device-
> >handle,
> > +   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
> >  UINT_MAX, handle_ioapic_add, NULL,
> > -root->device->handle, (void **));
> > +root_handle, (void **));
> >
> > return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -
> ENODEV;
> > }
> > +EXPORT_SYMBOL_GPL(acpi_ioapic_add);
> 
> What loadable module needs to call this?  It shouldn't be exported unless
> there is such a module.

It's called from the ioapic driver which is built-in. I'll remove the export.

Thanks
Rui



Re: [PATCH 1/4] x86/ioapic: Support hot-removal of IOAPICs present during boot boot

2016-07-26 Thread Rui Wang
On Wed, July 27, 2016 4:20 AM Bjorn Helgaas wrote:
> On Wed, Jul 27, 2016 at 12:13:14AM +0800, Rui Wang wrote:
> > IOAPICs present during system boot aren't added to ioapic_list, thus
> > are unable to be hot-removed. Fix it by calling
> > acpi_ioapic_add() during root bus enumeration.
> >
> > Signed-off-by: Rui Wang 
> > ---
> >  drivers/acpi/internal.h |  2 --
> >  drivers/acpi/ioapic.c   |  7 ---
> >  drivers/acpi/pci_root.c | 13 -  drivers/pci/setup-bus.c |
> > 5 -
> >  include/linux/acpi.h|  6 ++
> >  5 files changed, 26 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index
> > 27cc7fe..6d8e67e 100644
> > --- a/drivers/acpi/internal.h
> > +++ b/drivers/acpi/internal.h
> > @@ -40,10 +40,8 @@ int acpi_sysfs_init(void);  void
> > acpi_container_init(void);  void acpi_memory_hotplug_init(void);
> >  #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
> > -int acpi_ioapic_add(struct acpi_pci_root *root);  int
> > acpi_ioapic_remove(struct acpi_pci_root *root);  #else -static inline
> > int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
> 
> It would be nicer if the interface change and header file munging were in a
> separate patch so they wouldn't obscure the meat of the change, i.e., the
> addition of calls to acpi_ioapic_add().

Sure. I'll split it in a newer version.

> 
> >  static inline int acpi_ioapic_remove(struct acpi_pci_root *root) {
> > return 0; }  #endif  #ifdef CONFIG_ACPI_DOCK diff --git
> > a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c index ccdc8db..0f272e2
> > 100644
> > --- a/drivers/acpi/ioapic.c
> > +++ b/drivers/acpi/ioapic.c
> > @@ -189,16 +189,17 @@ exit:
> > return AE_OK;
> >  }
> >
> > -int acpi_ioapic_add(struct acpi_pci_root *root)
> > +int acpi_ioapic_add(acpi_handle root_handle)
> >  {
> > acpi_status status, retval = AE_OK;
> >
> > -   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device-
> >handle,
> > +   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
> >  UINT_MAX, handle_ioapic_add, NULL,
> > -root->device->handle, (void **));
> > +root_handle, (void **));
> >
> > return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -
> ENODEV;
> > }
> > +EXPORT_SYMBOL_GPL(acpi_ioapic_add);
> 
> What loadable module needs to call this?  It shouldn't be exported unless
> there is such a module.

It's called from the ioapic driver which is built-in. I'll remove the export.

Thanks
Rui



[PATCH 2/4] x86/ioapic: Fix setup_res() failing to get resource

2016-07-26 Thread Rui Wang
setup_res() doesn't actually get any resoure because it mistakenly
checks the return value of acpi_dev_filter_resource_type(), which
returns 0 on success, and 1 on failure. Fix it by taking the return
value of non-zero as failing to match the specified resource type.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/ioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 0f272e2..daf4a40 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -46,7 +46,7 @@ static acpi_status setup_res(struct acpi_resource *acpi_res, 
void *data)
struct resource_win win;
 
res->flags = 0;
-   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM) == 0)
+   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
return AE_OK;
 
if (!acpi_dev_resource_memory(acpi_res, res)) {
-- 
1.8.3.1



[PATCH 3/4] x86/ioapic: Fix lost ioapic resource after hot-removal and hotadd

2016-07-26 Thread Rui Wang
ioapic resource at 0xfecx gets lost from /proc/iomem after
hot-removing and then hot-adding the ioapic devices.

After system boot, in /proc/iomem:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

Then hot-remove IOAPIC 2 and hot-add it again:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

The range at 0xfec4 is lost from /proc/iomem. It is because
handle_ioapic_add() requests resource from either PCI config BAR or
acpi _CRS, not both. But Intel platforms map the IOxAPIC registers
at both the PCI config BAR (called MBAR) and the 0xfecX_YZ00 to
0xfecX_Y2FF range (called ABAR). Both of the ranges should be claimed
from /proc/iomem for exclusive use.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/ioapic.c | 36 
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index daf4a40..80b0b1a 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -97,7 +97,7 @@ static acpi_status handle_ioapic_add(acpi_handle handle, u32 
lvl,
unsigned long long gsi_base;
struct acpi_pci_ioapic *ioapic;
struct pci_dev *dev = NULL;
-   struct resource *res = NULL;
+   struct resource *res = NULL, *pci_res, *crs_res;
char *type = NULL;
 
if (!acpi_is_ioapic(handle, ))
@@ -137,23 +137,28 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
pci_set_master(dev);
if (pci_request_region(dev, 0, type))
goto exit_disable;
-   res = >resource[0];
+   pci_res = >resource[0];
ioapic->pdev = dev;
} else {
pci_dev_put(dev);
dev = NULL;
+   }
 
-   res = >res;
-   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, res);
-   if (res->flags == 0) {
-   acpi_handle_warn(handle, "failed to get resource\n");
-   goto exit_free;
-   } else if (request_resource(_resource, res)) {
-   acpi_handle_warn(handle, "failed to insert resource\n");
-   goto exit_free;
-   }
+   crs_res = >res;
+   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   if (crs_res->flags == 0) {
+   acpi_handle_warn(handle, "failed to get resource\n");
+   goto exit_release;
+   } else if (request_resource(_resource, crs_res)) {
+   acpi_handle_warn(handle, "failed to insert resource\n");
+   goto exit_release;
}
 
+   /* try pci resource first, then "_CRS" resource */
+   res = pci_res;
+   if (!res || !res->flags)
+   res = crs_res;
+
if (acpi_register_ioapic(handle, res->start, (u32)gsi_base)) {
acpi_handle_warn(handle, "failed to register IOAPIC\n");
goto exit_release;
@@ -174,14 +179,13 @@ done:
 exit_release:
if (dev)
pci_release_region(dev, 0);
-   else
-   release_resource(res);
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
 exit_disable:
if (dev)
pci_disable_device(dev);
 exit_put:
pci_dev_put(dev);
-exit_free:
kfree(ioapic);
 exit:
mutex_unlock(_list_lock);
@@ -218,9 +222,9 @@ int acpi_ioapic_remove(struct acpi_pci_root *root)
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
-   } else if (ioapic->res.flags && ioapic->res.parent) {
-   release_resource(>res);
}
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
list_del(>list);
kfree(ioapic);
}
-- 
1.8.3.1



[PATCH 2/4] x86/ioapic: Fix setup_res() failing to get resource

2016-07-26 Thread Rui Wang
setup_res() doesn't actually get any resoure because it mistakenly
checks the return value of acpi_dev_filter_resource_type(), which
returns 0 on success, and 1 on failure. Fix it by taking the return
value of non-zero as failing to match the specified resource type.

Signed-off-by: Rui Wang 
---
 drivers/acpi/ioapic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 0f272e2..daf4a40 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -46,7 +46,7 @@ static acpi_status setup_res(struct acpi_resource *acpi_res, 
void *data)
struct resource_win win;
 
res->flags = 0;
-   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM) == 0)
+   if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
return AE_OK;
 
if (!acpi_dev_resource_memory(acpi_res, res)) {
-- 
1.8.3.1



[PATCH 3/4] x86/ioapic: Fix lost ioapic resource after hot-removal and hotadd

2016-07-26 Thread Rui Wang
ioapic resource at 0xfecx gets lost from /proc/iomem after
hot-removing and then hot-adding the ioapic devices.

After system boot, in /proc/iomem:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

Then hot-remove IOAPIC 2 and hot-add it again:
fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec8-fec803ff : IOAPIC 3
  fecc-fecc03ff : IOAPIC 4

The range at 0xfec4 is lost from /proc/iomem. It is because
handle_ioapic_add() requests resource from either PCI config BAR or
acpi _CRS, not both. But Intel platforms map the IOxAPIC registers
at both the PCI config BAR (called MBAR) and the 0xfecX_YZ00 to
0xfecX_Y2FF range (called ABAR). Both of the ranges should be claimed
from /proc/iomem for exclusive use.

Signed-off-by: Rui Wang 
---
 drivers/acpi/ioapic.c | 36 
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index daf4a40..80b0b1a 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -97,7 +97,7 @@ static acpi_status handle_ioapic_add(acpi_handle handle, u32 
lvl,
unsigned long long gsi_base;
struct acpi_pci_ioapic *ioapic;
struct pci_dev *dev = NULL;
-   struct resource *res = NULL;
+   struct resource *res = NULL, *pci_res, *crs_res;
char *type = NULL;
 
if (!acpi_is_ioapic(handle, ))
@@ -137,23 +137,28 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
pci_set_master(dev);
if (pci_request_region(dev, 0, type))
goto exit_disable;
-   res = >resource[0];
+   pci_res = >resource[0];
ioapic->pdev = dev;
} else {
pci_dev_put(dev);
dev = NULL;
+   }
 
-   res = >res;
-   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, res);
-   if (res->flags == 0) {
-   acpi_handle_warn(handle, "failed to get resource\n");
-   goto exit_free;
-   } else if (request_resource(_resource, res)) {
-   acpi_handle_warn(handle, "failed to insert resource\n");
-   goto exit_free;
-   }
+   crs_res = >res;
+   acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   if (crs_res->flags == 0) {
+   acpi_handle_warn(handle, "failed to get resource\n");
+   goto exit_release;
+   } else if (request_resource(_resource, crs_res)) {
+   acpi_handle_warn(handle, "failed to insert resource\n");
+   goto exit_release;
}
 
+   /* try pci resource first, then "_CRS" resource */
+   res = pci_res;
+   if (!res || !res->flags)
+   res = crs_res;
+
if (acpi_register_ioapic(handle, res->start, (u32)gsi_base)) {
acpi_handle_warn(handle, "failed to register IOAPIC\n");
goto exit_release;
@@ -174,14 +179,13 @@ done:
 exit_release:
if (dev)
pci_release_region(dev, 0);
-   else
-   release_resource(res);
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
 exit_disable:
if (dev)
pci_disable_device(dev);
 exit_put:
pci_dev_put(dev);
-exit_free:
kfree(ioapic);
 exit:
mutex_unlock(_list_lock);
@@ -218,9 +222,9 @@ int acpi_ioapic_remove(struct acpi_pci_root *root)
pci_release_region(ioapic->pdev, 0);
pci_disable_device(ioapic->pdev);
pci_dev_put(ioapic->pdev);
-   } else if (ioapic->res.flags && ioapic->res.parent) {
-   release_resource(>res);
}
+   if (ioapic->res.flags && ioapic->res.parent)
+   release_resource(>res);
list_del(>list);
kfree(ioapic);
}
-- 
1.8.3.1



[PATCH 1/4] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-07-26 Thread Rui Wang
IOAPICs present during system boot aren't added to ioapic_list,
thus are unable to be hot-removed. Fix it by calling
acpi_ioapic_add() during root bus enumeration.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/internal.h |  2 --
 drivers/acpi/ioapic.c   |  7 ---
 drivers/acpi/pci_root.c | 13 -
 drivers/pci/setup-bus.c |  5 -
 include/linux/acpi.h|  6 ++
 5 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 27cc7fe..6d8e67e 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -40,10 +40,8 @@ int acpi_sysfs_init(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
-int acpi_ioapic_add(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
-static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ccdc8db..0f272e2 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -189,16 +189,17 @@ exit:
return AE_OK;
 }
 
-int acpi_ioapic_add(struct acpi_pci_root *root)
+int acpi_ioapic_add(acpi_handle root_handle)
 {
acpi_status status, retval = AE_OK;
 
-   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle,
+   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
 UINT_MAX, handle_ioapic_add, NULL,
-root->device->handle, (void **));
+root_handle, (void **));
 
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
+EXPORT_SYMBOL_GPL(acpi_ioapic_add);
 
 int acpi_ioapic_remove(struct acpi_pci_root *root)
 {
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index ae3fe4e..d818c61 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,7 +614,18 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
-   acpi_ioapic_add(root);
+
+   /*
+* This is only called for the hotadd case. For the boot-time
+* case, we need to wait until after PCI initialization in
+* order to deal with IOAPICs mapped in on a PCI BAR.
+*
+* This is currently x86-specific, because acpi_ioapic_add()
+* is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC.
+* And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC
+* (see drivers/acpi/Kconfig).
+*/
+   acpi_ioapic_add(root->device->handle);
}
 
pci_lock_rescan_remove();
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 55641a3..e32c356 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pci.h"
 
 unsigned int pci_flags;
@@ -1779,8 +1780,10 @@ void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
 
-   list_for_each_entry(root_bus, _root_buses, node)
+   list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   }
 }
 
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 288fac5..f5114dc 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -680,6 +680,12 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct 
acpi_device *adev)
 
 #endif /* !CONFIG_ACPI */
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+int acpi_ioapic_add(acpi_handle root);
+#else
+static inline int acpi_ioapic_add(acpi_handle root) { return 0; }
+#endif
+
 #ifdef CONFIG_ACPI
 void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
   u32 pm1a_ctrl,  u32 pm1b_ctrl));
-- 
1.8.3.1



[PATCH 1/4] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-07-26 Thread Rui Wang
IOAPICs present during system boot aren't added to ioapic_list,
thus are unable to be hot-removed. Fix it by calling
acpi_ioapic_add() during root bus enumeration.

Signed-off-by: Rui Wang 
---
 drivers/acpi/internal.h |  2 --
 drivers/acpi/ioapic.c   |  7 ---
 drivers/acpi/pci_root.c | 13 -
 drivers/pci/setup-bus.c |  5 -
 include/linux/acpi.h|  6 ++
 5 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 27cc7fe..6d8e67e 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -40,10 +40,8 @@ int acpi_sysfs_init(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
-int acpi_ioapic_add(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
-static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ccdc8db..0f272e2 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -189,16 +189,17 @@ exit:
return AE_OK;
 }
 
-int acpi_ioapic_add(struct acpi_pci_root *root)
+int acpi_ioapic_add(acpi_handle root_handle)
 {
acpi_status status, retval = AE_OK;
 
-   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle,
+   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
 UINT_MAX, handle_ioapic_add, NULL,
-root->device->handle, (void **));
+root_handle, (void **));
 
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
+EXPORT_SYMBOL_GPL(acpi_ioapic_add);
 
 int acpi_ioapic_remove(struct acpi_pci_root *root)
 {
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index ae3fe4e..d818c61 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,7 +614,18 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
-   acpi_ioapic_add(root);
+
+   /*
+* This is only called for the hotadd case. For the boot-time
+* case, we need to wait until after PCI initialization in
+* order to deal with IOAPICs mapped in on a PCI BAR.
+*
+* This is currently x86-specific, because acpi_ioapic_add()
+* is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC.
+* And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC
+* (see drivers/acpi/Kconfig).
+*/
+   acpi_ioapic_add(root->device->handle);
}
 
pci_lock_rescan_remove();
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 55641a3..e32c356 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pci.h"
 
 unsigned int pci_flags;
@@ -1779,8 +1780,10 @@ void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
 
-   list_for_each_entry(root_bus, _root_buses, node)
+   list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   }
 }
 
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 288fac5..f5114dc 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -680,6 +680,12 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct 
acpi_device *adev)
 
 #endif /* !CONFIG_ACPI */
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+int acpi_ioapic_add(acpi_handle root);
+#else
+static inline int acpi_ioapic_add(acpi_handle root) { return 0; }
+#endif
+
 #ifdef CONFIG_ACPI
 void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
   u32 pm1a_ctrl,  u32 pm1b_ctrl));
-- 
1.8.3.1



[PATCH 4/4] x86/ioapic: Fix ioapic failing to request resource

2016-07-26 Thread Rui Wang
handle_ioapic_add() uses request_resource() to request ACPI "_CRS"
resources. This can fail with the following error message:

[  247.325693] ACPI: \_SB_.IIO1.AID1: failed to insert resource

This happens when there are multiple ioapics and DSDT groups their
"_CRS" resources as the children of a parent resource, as seen from
/proc/iomem:

fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2

In this case request_resource() fails because there's a conflicting
resource which is the parent (fec-fecf). Fix it by using
insert_resoure() which can request resources by taking the conflicting
resource as the parent.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/ioapic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 80b0b1a..2c38ce0 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -146,10 +146,12 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
 
crs_res = >res;
acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   crs_res->name = type;
+   crs_res->flags |= IORESOURCE_BUSY;
if (crs_res->flags == 0) {
acpi_handle_warn(handle, "failed to get resource\n");
goto exit_release;
-   } else if (request_resource(_resource, crs_res)) {
+   } else if (insert_resource(_resource, crs_res)) {
acpi_handle_warn(handle, "failed to insert resource\n");
goto exit_release;
}
-- 
1.8.3.1



[PATCH 4/4] x86/ioapic: Fix ioapic failing to request resource

2016-07-26 Thread Rui Wang
handle_ioapic_add() uses request_resource() to request ACPI "_CRS"
resources. This can fail with the following error message:

[  247.325693] ACPI: \_SB_.IIO1.AID1: failed to insert resource

This happens when there are multiple ioapics and DSDT groups their
"_CRS" resources as the children of a parent resource, as seen from
/proc/iomem:

fec0-fecf : PNP0003:00
  fec0-fec003ff : IOAPIC 0
  fec01000-fec013ff : IOAPIC 1
  fec4-fec403ff : IOAPIC 2

In this case request_resource() fails because there's a conflicting
resource which is the parent (fec-fecf). Fix it by using
insert_resoure() which can request resources by taking the conflicting
resource as the parent.

Signed-off-by: Rui Wang 
---
 drivers/acpi/ioapic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index 80b0b1a..2c38ce0 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -146,10 +146,12 @@ static acpi_status handle_ioapic_add(acpi_handle handle, 
u32 lvl,
 
crs_res = >res;
acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
+   crs_res->name = type;
+   crs_res->flags |= IORESOURCE_BUSY;
if (crs_res->flags == 0) {
acpi_handle_warn(handle, "failed to get resource\n");
goto exit_release;
-   } else if (request_resource(_resource, crs_res)) {
+   } else if (insert_resource(_resource, crs_res)) {
acpi_handle_warn(handle, "failed to insert resource\n");
goto exit_release;
}
-- 
1.8.3.1



[PATCH 0/4] Fixing a set of bugs for ioapic hotplug

2016-07-26 Thread Rui Wang
Hi all,

The 1st patch has been discussed before Bjorn went on vacation. I've fixed
all the issues. Bjorn, please advise how we'll move forward.

The remaining patches fix newly found bugs while testing ioapic hotplug.

Regards,
Rui

Rui Wang (4):
  x86/ioapic: Support hot-removal of IOAPICs present during boot
  x86/ioapic: Fix setup_res() failing to get resource
  x86/ioapic: Fix lost ioapic resource after hot-removal and hotadd
  x86/ioapic: Fix ioapic failing to request resource

 drivers/acpi/internal.h |  2 --
 drivers/acpi/ioapic.c   | 47 +++
 drivers/acpi/pci_root.c | 13 -
 drivers/pci/setup-bus.c |  5 -
 include/linux/acpi.h|  6 ++
 5 files changed, 49 insertions(+), 24 deletions(-)

-- 
1.8.3.1



[PATCH 0/4] Fixing a set of bugs for ioapic hotplug

2016-07-26 Thread Rui Wang
Hi all,

The 1st patch has been discussed before Bjorn went on vacation. I've fixed
all the issues. Bjorn, please advise how we'll move forward.

The remaining patches fix newly found bugs while testing ioapic hotplug.

Regards,
Rui

Rui Wang (4):
  x86/ioapic: Support hot-removal of IOAPICs present during boot
  x86/ioapic: Fix setup_res() failing to get resource
  x86/ioapic: Fix lost ioapic resource after hot-removal and hotadd
  x86/ioapic: Fix ioapic failing to request resource

 drivers/acpi/internal.h |  2 --
 drivers/acpi/ioapic.c   | 47 +++
 drivers/acpi/pci_root.c | 13 -
 drivers/pci/setup-bus.c |  5 -
 include/linux/acpi.h|  6 ++
 5 files changed, 49 insertions(+), 24 deletions(-)

-- 
1.8.3.1



[PATCH V5 1/3] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-06-25 Thread Rui Wang
v5: Remove #ifdef CONFIG_X86 from setup-bus.c, making it neutral to archs.
v4: Add comments explaining when to call acpi_ioapic_add().
v3: Previous versions break mips. This version fixes it.

IOAPICs present during system boot aren't added to ioapic_list,
thus are unable to be hot-removed. Fix it by calling
acpi_ioapic_add() during root bus enumeration.

Signed-off-by: Rui Wang <rui.y.w...@intel.com>
---
 drivers/acpi/internal.h |  2 --
 drivers/acpi/ioapic.c   |  7 ---
 drivers/acpi/pci_root.c | 13 -
 drivers/pci/setup-bus.c |  5 -
 include/linux/acpi.h|  6 ++
 5 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 27cc7fe..6d8e67e 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -40,10 +40,8 @@ int acpi_sysfs_init(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
-int acpi_ioapic_add(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
-static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ccdc8db..0f272e2 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -189,16 +189,17 @@ exit:
return AE_OK;
 }
 
-int acpi_ioapic_add(struct acpi_pci_root *root)
+int acpi_ioapic_add(acpi_handle root_handle)
 {
acpi_status status, retval = AE_OK;
 
-   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle,
+   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
 UINT_MAX, handle_ioapic_add, NULL,
-root->device->handle, (void **));
+root_handle, (void **));
 
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
+EXPORT_SYMBOL_GPL(acpi_ioapic_add);
 
 int acpi_ioapic_remove(struct acpi_pci_root *root)
 {
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index ae3fe4e..31e4440 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,7 +614,18 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
-   acpi_ioapic_add(root);
+
+   /*
+* This is only called for the hotadd case. For the boot-time
+* case, we need to wait until after PCI initialization in
+* order to deal with IOAPICs mapped in on a PCI BAR.
+*
+* This is currently x86-specific, because acpi_ioapic_add()
+* is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC.
+* And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC
+* (see drivers/acpi/Kconfig).
+*/
+   acpi_ioapic_add(root->device->handle);
}
 
pci_lock_rescan_remove();
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 55641a3..e32c356 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pci.h"
 
 unsigned int pci_flags;
@@ -1779,8 +1780,10 @@ void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
 
-   list_for_each_entry(root_bus, _root_buses, node)
+   list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   }
 }
 
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 288fac5..f5114dc 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -680,6 +680,12 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct 
acpi_device *adev)
 
 #endif /* !CONFIG_ACPI */
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+int acpi_ioapic_add(acpi_handle root);
+#else
+static inline int acpi_ioapic_add(acpi_handle root) { return 0; }
+#endif
+
 #ifdef CONFIG_ACPI
 void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
   u32 pm1a_ctrl,  u32 pm1b_ctrl));
-- 
1.8.3.1



[PATCH V5 1/3] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-06-25 Thread Rui Wang
v5: Remove #ifdef CONFIG_X86 from setup-bus.c, making it neutral to archs.
v4: Add comments explaining when to call acpi_ioapic_add().
v3: Previous versions break mips. This version fixes it.

IOAPICs present during system boot aren't added to ioapic_list,
thus are unable to be hot-removed. Fix it by calling
acpi_ioapic_add() during root bus enumeration.

Signed-off-by: Rui Wang 
---
 drivers/acpi/internal.h |  2 --
 drivers/acpi/ioapic.c   |  7 ---
 drivers/acpi/pci_root.c | 13 -
 drivers/pci/setup-bus.c |  5 -
 include/linux/acpi.h|  6 ++
 5 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 27cc7fe..6d8e67e 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -40,10 +40,8 @@ int acpi_sysfs_init(void);
 void acpi_container_init(void);
 void acpi_memory_hotplug_init(void);
 #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
-int acpi_ioapic_add(struct acpi_pci_root *root);
 int acpi_ioapic_remove(struct acpi_pci_root *root);
 #else
-static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
 static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
 #endif
 #ifdef CONFIG_ACPI_DOCK
diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c
index ccdc8db..0f272e2 100644
--- a/drivers/acpi/ioapic.c
+++ b/drivers/acpi/ioapic.c
@@ -189,16 +189,17 @@ exit:
return AE_OK;
 }
 
-int acpi_ioapic_add(struct acpi_pci_root *root)
+int acpi_ioapic_add(acpi_handle root_handle)
 {
acpi_status status, retval = AE_OK;
 
-   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle,
+   status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
 UINT_MAX, handle_ioapic_add, NULL,
-root->device->handle, (void **));
+root_handle, (void **));
 
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
 }
+EXPORT_SYMBOL_GPL(acpi_ioapic_add);
 
 int acpi_ioapic_remove(struct acpi_pci_root *root)
 {
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index ae3fe4e..31e4440 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -614,7 +614,18 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (hotadd) {
pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_root_bus_resources(root->bus);
-   acpi_ioapic_add(root);
+
+   /*
+* This is only called for the hotadd case. For the boot-time
+* case, we need to wait until after PCI initialization in
+* order to deal with IOAPICs mapped in on a PCI BAR.
+*
+* This is currently x86-specific, because acpi_ioapic_add()
+* is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC.
+* And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC
+* (see drivers/acpi/Kconfig).
+*/
+   acpi_ioapic_add(root->device->handle);
}
 
pci_lock_rescan_remove();
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 55641a3..e32c356 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pci.h"
 
 unsigned int pci_flags;
@@ -1779,8 +1780,10 @@ void __init pci_assign_unassigned_resources(void)
 {
struct pci_bus *root_bus;
 
-   list_for_each_entry(root_bus, _root_buses, node)
+   list_for_each_entry(root_bus, _root_buses, node) {
pci_assign_unassigned_root_bus_resources(root_bus);
+   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
+   }
 }
 
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 288fac5..f5114dc 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -680,6 +680,12 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct 
acpi_device *adev)
 
 #endif /* !CONFIG_ACPI */
 
+#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
+int acpi_ioapic_add(acpi_handle root);
+#else
+static inline int acpi_ioapic_add(acpi_handle root) { return 0; }
+#endif
+
 #ifdef CONFIG_ACPI
 void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
   u32 pm1a_ctrl,  u32 pm1b_ctrl));
-- 
1.8.3.1



Re: [PATCH V4 1/3] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-06-24 Thread Rui Wang
On Fri, Jun 24, 2016 1:35 AM Bjorn Helgaas wrote:
> On Thu, Jun 23, 2016 at 01:11:41PM +0800, Rui Wang wrote:
> > On Wed, June 22, 2016 11:15 PM Bjorn Helgaas wrote:
> > > [...]
> > > > @@ -1779,8 +1780,12 @@ void __init
> > > > pci_assign_unassigned_resources(void)
> > > >  {
> > > > struct pci_bus *root_bus;
> > > >
> > > > -   list_for_each_entry(root_bus, _root_buses, node)
> > > > +   list_for_each_entry(root_bus, _root_buses, node) {
> > > > pci_assign_unassigned_root_bus_resources(root_bus);
> > > > +#ifdef CONFIG_X86
> > > > +   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
> > > > +#endif
> > >
> > > Doesn't this do the right thing even if you omit the #ifdefs, since
> > > you define a stub function below?
> > >
> >
> > No. Without the '#ifdef CONFIG_X86' it breaks MIPS arch. The stub
> > function is within 'ifdef CONFIG_ACPI'. On archs without ACPI it
> > doesn't compile due to 'undefined reference to acpi_ioapic_add'.
> 
> But this *could* be made to work by defining a stub for the non-
> CONFIG_ACPI case.  That's what we generally do to avoid ifdefs in the code.

That can be done. I'll make the change and do some cross-compiling tests first.

Thanks
Rui



Re: [PATCH V4 1/3] x86/ioapic: Support hot-removal of IOAPICs present during boot

2016-06-24 Thread Rui Wang
On Fri, Jun 24, 2016 1:35 AM Bjorn Helgaas wrote:
> On Thu, Jun 23, 2016 at 01:11:41PM +0800, Rui Wang wrote:
> > On Wed, June 22, 2016 11:15 PM Bjorn Helgaas wrote:
> > > [...]
> > > > @@ -1779,8 +1780,12 @@ void __init
> > > > pci_assign_unassigned_resources(void)
> > > >  {
> > > > struct pci_bus *root_bus;
> > > >
> > > > -   list_for_each_entry(root_bus, _root_buses, node)
> > > > +   list_for_each_entry(root_bus, _root_buses, node) {
> > > > pci_assign_unassigned_root_bus_resources(root_bus);
> > > > +#ifdef CONFIG_X86
> > > > +   acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
> > > > +#endif
> > >
> > > Doesn't this do the right thing even if you omit the #ifdefs, since
> > > you define a stub function below?
> > >
> >
> > No. Without the '#ifdef CONFIG_X86' it breaks MIPS arch. The stub
> > function is within 'ifdef CONFIG_ACPI'. On archs without ACPI it
> > doesn't compile due to 'undefined reference to acpi_ioapic_add'.
> 
> But this *could* be made to work by defining a stub for the non-
> CONFIG_ACPI case.  That's what we generally do to avoid ifdefs in the code.

That can be done. I'll make the change and do some cross-compiling tests first.

Thanks
Rui



  1   2   3   >