public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [GIT PULL] x86/apic changes for v3.14
@ 2014-01-20 13:42 Ingo Molnar
  2014-03-23  0:00 ` Maciej W. Rozycki
  0 siblings, 1 reply; 3+ messages in thread
From: Ingo Molnar @ 2014-01-20 13:42 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-kernel, H. Peter Anvin, Thomas Gleixner, Andrew Morton

Linus,

Please pull the latest x86-apic-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-apic-for-linus

   # HEAD: 5b4d1dbc24bb6fd7179ada0f47be34e27e64decb x86, apic: Make disabled_cpu_apicid static read_mostly, fix typos

Two main changes:

 - Improve local APIC Error Status Register reporting robustness.

 - Add the 'disable_cpu_apicid=x' boot parameter for kexec booting.

 Thanks,

	Ingo

------------------>
H. Peter Anvin (1):
      x86, apic: Make disabled_cpu_apicid static read_mostly, fix typos

HATAYAMA Daisuke (1):
      x86, apic, kexec: Add disable_cpu_apicid kernel parameter

Richard Weinberger (1):
      x86/apic: Read Error Status Register correctly


 Documentation/kernel-parameters.txt |  9 +++++
 arch/x86/kernel/apic/apic.c         | 66 ++++++++++++++++++++++++++++++++-----
 2 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index b9e9bd8..6fdbf8c 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -774,6 +774,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 	disable=	[IPV6]
 			See Documentation/networking/ipv6.txt.
 
+	disable_cpu_apicid= [X86,APIC,SMP]
+			Format: <int>
+			The number of initial APIC ID for the
+			corresponding CPU to be disabled at boot,
+			mostly used for the kdump 2nd kernel to
+			disable BSP to wake up multiple CPUs without
+			causing system reset or hang due to sending
+			INIT from AP to BSP.
+
 	disable_ddw     [PPC/PSERIES]
 			Disable Dynamic DMA Window support. Use this if
 			to workaround buggy firmware.
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index d278736..7f26c9a 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -75,6 +75,13 @@ unsigned int max_physical_apicid;
 physid_mask_t phys_cpu_present_map;
 
 /*
+ * Processor to be disabled specified by kernel parameter
+ * disable_cpu_apicid=<int>, mostly used for the kdump 2nd kernel to
+ * avoid undefined behaviour caused by sending INIT from AP to BSP.
+ */
+static unsigned int disabled_cpu_apicid __read_mostly = BAD_APICID;
+
+/*
  * Map cpu index to physical APIC ID
  */
 DEFINE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_cpu_to_apicid, BAD_APICID);
@@ -1968,7 +1975,7 @@ __visible void smp_trace_spurious_interrupt(struct pt_regs *regs)
  */
 static inline void __smp_error_interrupt(struct pt_regs *regs)
 {
-	u32 v0, v1;
+	u32 v;
 	u32 i = 0;
 	static const char * const error_interrupt_reason[] = {
 		"Send CS error",		/* APIC Error Bit 0 */
@@ -1982,21 +1989,20 @@ static inline void __smp_error_interrupt(struct pt_regs *regs)
 	};
 
 	/* First tickle the hardware, only then report what went on. -- REW */
-	v0 = apic_read(APIC_ESR);
 	apic_write(APIC_ESR, 0);
-	v1 = apic_read(APIC_ESR);
+	v = apic_read(APIC_ESR);
 	ack_APIC_irq();
 	atomic_inc(&irq_err_count);
 
-	apic_printk(APIC_DEBUG, KERN_DEBUG "APIC error on CPU%d: %02x(%02x)",
-		    smp_processor_id(), v0 , v1);
+	apic_printk(APIC_DEBUG, KERN_DEBUG "APIC error on CPU%d: %02x",
+		    smp_processor_id(), v);
 
-	v1 = v1 & 0xff;
-	while (v1) {
-		if (v1 & 0x1)
+	v &= 0xff;
+	while (v) {
+		if (v & 0x1)
 			apic_printk(APIC_DEBUG, KERN_CONT " : %s", error_interrupt_reason[i]);
 		i++;
-		v1 >>= 1;
+		v >>= 1;
 	}
 
 	apic_printk(APIC_DEBUG, KERN_CONT "\n");
@@ -2115,6 +2121,39 @@ int generic_processor_info(int apicid, int version)
 				phys_cpu_present_map);
 
 	/*
+	 * boot_cpu_physical_apicid is designed to have the apicid
+	 * returned by read_apic_id(), i.e, the apicid of the
+	 * currently booting-up processor. However, on some platforms,
+	 * it is temporarily modified by the apicid reported as BSP
+	 * through MP table. Concretely:
+	 *
+	 * - arch/x86/kernel/mpparse.c: MP_processor_info()
+	 * - arch/x86/mm/amdtopology.c: amd_numa_init()
+	 * - arch/x86/platform/visws/visws_quirks.c: MP_processor_info()
+	 *
+	 * This function is executed with the modified
+	 * boot_cpu_physical_apicid. So, disabled_cpu_apicid kernel
+	 * parameter doesn't work to disable APs on kdump 2nd kernel.
+	 *
+	 * Since fixing handling of boot_cpu_physical_apicid requires
+	 * another discussion and tests on each platform, we leave it
+	 * for now and here we use read_apic_id() directly in this
+	 * function, generic_processor_info().
+	 */
+	if (disabled_cpu_apicid != BAD_APICID &&
+	    disabled_cpu_apicid != read_apic_id() &&
+	    disabled_cpu_apicid == apicid) {
+		int thiscpu = num_processors + disabled_cpus;
+
+		pr_warning("APIC: Disabling requested cpu."
+			   " Processor %d/0x%x ignored.\n",
+			   thiscpu, apicid);
+
+		disabled_cpus++;
+		return -ENODEV;
+	}
+
+	/*
 	 * If boot cpu has not been detected yet, then only allow upto
 	 * nr_cpu_ids - 1 processors and keep one slot free for boot cpu
 	 */
@@ -2592,3 +2631,12 @@ static int __init lapic_insert_resource(void)
  * that is using request_resource
  */
 late_initcall(lapic_insert_resource);
+
+static int __init apic_set_disabled_cpu_apicid(char *arg)
+{
+	if (!arg || !get_option(&arg, &disabled_cpu_apicid))
+		return -EINVAL;
+
+	return 0;
+}
+early_param("disable_cpu_apicid", apic_set_disabled_cpu_apicid);

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

* Re: [GIT PULL] x86/apic changes for v3.14
  2014-01-20 13:42 [GIT PULL] x86/apic changes for v3.14 Ingo Molnar
@ 2014-03-23  0:00 ` Maciej W. Rozycki
  2014-03-24  9:24   ` Ingo Molnar
  0 siblings, 1 reply; 3+ messages in thread
From: Maciej W. Rozycki @ 2014-03-23  0:00 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Linus Torvalds, linux-kernel, H. Peter Anvin, Thomas Gleixner,
	Andrew Morton

On Mon, 20 Jan 2014, Ingo Molnar wrote:

> diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
> index d278736..7f26c9a 100644
> --- a/arch/x86/kernel/apic/apic.c
> +++ b/arch/x86/kernel/apic/apic.c
> @@ -1982,21 +1989,20 @@ static inline void __smp_error_interrupt(struct pt_regs *regs)
>  	};
>  
>  	/* First tickle the hardware, only then report what went on. -- REW */
> -	v0 = apic_read(APIC_ESR);
>  	apic_write(APIC_ESR, 0);
> -	v1 = apic_read(APIC_ESR);
> +	v = apic_read(APIC_ESR);
>  	ack_APIC_irq();
>  	atomic_inc(&irq_err_count);
>  
> -	apic_printk(APIC_DEBUG, KERN_DEBUG "APIC error on CPU%d: %02x(%02x)",
> -		    smp_processor_id(), v0 , v1);
> +	apic_printk(APIC_DEBUG, KERN_DEBUG "APIC error on CPU%d: %02x",
> +		    smp_processor_id(), v);
>  
> -	v1 = v1 & 0xff;
> -	while (v1) {
> -		if (v1 & 0x1)
> +	v &= 0xff;
> +	while (v) {
> +		if (v & 0x1)
>  			apic_printk(APIC_DEBUG, KERN_CONT " : %s", error_interrupt_reason[i]);
>  		i++;
> -		v1 >>= 1;
> +		v >>= 1;
>  	}
>  
>  	apic_printk(APIC_DEBUG, KERN_CONT "\n");

 Sorry to come up with this so late, I've been cleaning up my mailbox from 
old mailing traffic and came across your change only now.

 I'm afraid this interferes with an old Pentium APIC erratum:

"3AP. Writes to Error Register Clears Register

PROBLEM: The APIC Error register is intended to only be read.  If there is 
a write to this register the data in the APIC Error register will be 
cleared and lost.

IMPLICATION: There is a possibility of clearing the Error register status 
since the write to the register is not specifically blocked.

WORKAROUND: Writes should not occur to the Pentium processor APIC Error 
register.

STATUS: For the steppings affected see the Summary Table of Changes at the 
beginning of this section."

The steppings affected are actually: B1, B3 and B5.  Do we want to keep 
supporting them?  I think yes, we already handle the erratum elsewhere 
(lapic_setup_esr).  So how about:

	if (lapic_get_maxlvt() > 3)	/* Due to the Pentium erratum 3AP. */
		apic_write(APIC_ESR, 0);
	v = apic_read(APIC_ESR);

instead?  I can make a patch if that would make your life easier.

 There's room for optimisation here, but I think it's not worth the effort 
as this is a slow path, APIC error interrupts are not supposed to happen 
and are I believe extremely uncommon with FSB message delivery.

  Maciej

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

* Re: [GIT PULL] x86/apic changes for v3.14
  2014-03-23  0:00 ` Maciej W. Rozycki
@ 2014-03-24  9:24   ` Ingo Molnar
  0 siblings, 0 replies; 3+ messages in thread
From: Ingo Molnar @ 2014-03-24  9:24 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Linus Torvalds, linux-kernel, H. Peter Anvin, Thomas Gleixner,
	Andrew Morton


* Maciej W. Rozycki <macro@linux-mips.org> wrote:

> IMPLICATION: There is a possibility of clearing the Error register 
> status since the write to the register is not specifically blocked.
> 
> WORKAROUND: Writes should not occur to the Pentium processor APIC 
> Error register.
> 
> STATUS: For the steppings affected see the Summary Table of Changes 
> at the beginning of this section."
> 
> The steppings affected are actually: B1, B3 and B5.  Do we want to 
> keep supporting them?  I think yes, we already handle the erratum 
> elsewhere (lapic_setup_esr).  So how about:
> 
> 	if (lapic_get_maxlvt() > 3)	/* Due to the Pentium erratum 3AP. */
> 		apic_write(APIC_ESR, 0);
> 	v = apic_read(APIC_ESR);
> 
> instead?  I can make a patch if that would make your life easier.

Sure, a patch would be helpful.

>  There's room for optimisation here, but I think it's not worth the 
> effort as this is a slow path, APIC error interrupts are not 
> supposed to happen and are I believe extremely uncommon with FSB 
> message delivery.

Agreed.

Thanks,

	Ingo

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

end of thread, other threads:[~2014-03-24  9:24 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-20 13:42 [GIT PULL] x86/apic changes for v3.14 Ingo Molnar
2014-03-23  0:00 ` Maciej W. Rozycki
2014-03-24  9:24   ` Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox