mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 09:31:50 +00:00
Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86/apic changes from Ingo Molnar: "Two main changes: - improve local APIC Error Status Register reporting robustness - add the 'disable_cpu_apicid=x' boot parameter for kexec booting" * 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86, apic: Make disabled_cpu_apicid static read_mostly, fix typos x86, apic, kexec: Add disable_cpu_apicid kernel parameter x86/apic: Read Error Status Register correctly
This commit is contained in:
commit
1a7dbbcc8c
@ -774,6 +774,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||||||
disable= [IPV6]
|
disable= [IPV6]
|
||||||
See Documentation/networking/ipv6.txt.
|
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_ddw [PPC/PSERIES]
|
||||||
Disable Dynamic DMA Window support. Use this if
|
Disable Dynamic DMA Window support. Use this if
|
||||||
to workaround buggy firmware.
|
to workaround buggy firmware.
|
||||||
|
@ -74,6 +74,13 @@ unsigned int max_physical_apicid;
|
|||||||
*/
|
*/
|
||||||
physid_mask_t phys_cpu_present_map;
|
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
|
* Map cpu index to physical APIC ID
|
||||||
*/
|
*/
|
||||||
@ -1968,7 +1975,7 @@ __visible void smp_trace_spurious_interrupt(struct pt_regs *regs)
|
|||||||
*/
|
*/
|
||||||
static inline void __smp_error_interrupt(struct pt_regs *regs)
|
static inline void __smp_error_interrupt(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
u32 v0, v1;
|
u32 v;
|
||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
static const char * const error_interrupt_reason[] = {
|
static const char * const error_interrupt_reason[] = {
|
||||||
"Send CS error", /* APIC Error Bit 0 */
|
"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 */
|
/* First tickle the hardware, only then report what went on. -- REW */
|
||||||
v0 = apic_read(APIC_ESR);
|
|
||||||
apic_write(APIC_ESR, 0);
|
apic_write(APIC_ESR, 0);
|
||||||
v1 = apic_read(APIC_ESR);
|
v = apic_read(APIC_ESR);
|
||||||
ack_APIC_irq();
|
ack_APIC_irq();
|
||||||
atomic_inc(&irq_err_count);
|
atomic_inc(&irq_err_count);
|
||||||
|
|
||||||
apic_printk(APIC_DEBUG, KERN_DEBUG "APIC error on CPU%d: %02x(%02x)",
|
apic_printk(APIC_DEBUG, KERN_DEBUG "APIC error on CPU%d: %02x",
|
||||||
smp_processor_id(), v0 , v1);
|
smp_processor_id(), v);
|
||||||
|
|
||||||
v1 = v1 & 0xff;
|
v &= 0xff;
|
||||||
while (v1) {
|
while (v) {
|
||||||
if (v1 & 0x1)
|
if (v & 0x1)
|
||||||
apic_printk(APIC_DEBUG, KERN_CONT " : %s", error_interrupt_reason[i]);
|
apic_printk(APIC_DEBUG, KERN_CONT " : %s", error_interrupt_reason[i]);
|
||||||
i++;
|
i++;
|
||||||
v1 >>= 1;
|
v >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
apic_printk(APIC_DEBUG, KERN_CONT "\n");
|
apic_printk(APIC_DEBUG, KERN_CONT "\n");
|
||||||
@ -2114,6 +2120,39 @@ int generic_processor_info(int apicid, int version)
|
|||||||
bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid,
|
bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid,
|
||||||
phys_cpu_present_map);
|
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
|
* 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
|
* 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
|
* that is using request_resource
|
||||||
*/
|
*/
|
||||||
late_initcall(lapic_insert_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);
|
||||||
|
Loading…
Reference in New Issue
Block a user