Release 4.11 arch/arm/kernel/machine_kexec.c
/*
* machine_kexec.c - handle transition of Linux booting another kernel
*/
#include <linux/mm.h>
#include <linux/kexec.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/memblock.h>
#include <asm/pgtable.h>
#include <linux/of_fdt.h>
#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#include <asm/cacheflush.h>
#include <asm/fncpy.h>
#include <asm/mach-types.h>
#include <asm/smp_plat.h>
#include <asm/system_misc.h>
extern void relocate_new_kernel(void);
extern const unsigned int relocate_new_kernel_size;
extern unsigned long kexec_start_address;
extern unsigned long kexec_indirection_page;
extern unsigned long kexec_mach_type;
extern unsigned long kexec_boot_atags;
static atomic_t waiting_for_crash_ipi;
static unsigned long dt_mem;
/*
* Provide a dummy crash_notes definition while crash dump arrives to arm.
* This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
*/
int machine_kexec_prepare(struct kimage *image)
{
struct kexec_segment *current_segment;
__be32 header;
int i, err;
/*
* Validate that if the current HW supports SMP, then the SW supports
* and implements CPU hotplug for the current HW. If not, we won't be
* able to kexec reliably, so fail the prepare operation.
*/
if (num_possible_cpus() > 1 && platform_can_secondary_boot() &&
!platform_can_cpu_hotplug())
return -EINVAL;
/*
* No segment at default ATAGs address. try to locate
* a dtb using magic.
*/
for (i = 0; i < image->nr_segments; i++) {
current_segment = &image->segment[i];
if (!memblock_is_region_memory(idmap_to_phys(current_segment->mem),
current_segment->memsz))
return -EINVAL;
err = get_user(header, (__be32*)current_segment->buf);
if (err)
return err;
if (be32_to_cpu(header) == OF_DT_HEADER)
dt_mem = current_segment->mem;
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Matthew Leach | 92 | 70.23% | 2 | 25.00% |
Stephen Warren | 16 | 12.21% | 1 | 12.50% |
Richard Purdie | 13 | 9.92% | 1 | 12.50% |
Aaro Koskinen | 3 | 2.29% | 1 | 12.50% |
Geert Uytterhoeven | 3 | 2.29% | 1 | 12.50% |
Russell King | 3 | 2.29% | 1 | 12.50% |
Nikolay Borisov | 1 | 0.76% | 1 | 12.50% |
Total | 131 | 100.00% | 8 | 100.00% |
void machine_kexec_cleanup(struct kimage *image)
{
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Richard Purdie | 9 | 100.00% | 1 | 100.00% |
Total | 9 | 100.00% | 1 | 100.00% |
void machine_crash_nonpanic_core(void *unused)
{
struct pt_regs regs;
crash_setup_regs(®s, NULL);
printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n",
smp_processor_id());
crash_save_cpu(®s, smp_processor_id());
flush_cache_all();
set_cpu_online(smp_processor_id(), false);
atomic_dec(&waiting_for_crash_ipi);
while (1)
cpu_relax();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Per Fransson | 55 | 87.30% | 1 | 50.00% |
Vijaya Kumar K | 8 | 12.70% | 1 | 50.00% |
Total | 63 | 100.00% | 2 | 100.00% |
static void machine_kexec_mask_interrupts(void)
{
unsigned int i;
struct irq_desc *desc;
for_each_irq_desc(i, desc) {
struct irq_chip *chip;
chip = irq_desc_get_chip(desc);
if (!chip)
continue;
if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
chip->irq_eoi(&desc->irq_data);
if (chip->irq_mask)
chip->irq_mask(&desc->irq_data);
if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
chip->irq_disable(&desc->irq_data);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Will Deacon | 108 | 100.00% | 1 | 100.00% |
Total | 108 | 100.00% | 1 | 100.00% |
void machine_crash_shutdown(struct pt_regs *regs)
{
unsigned long msecs;
local_irq_disable();
atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
smp_call_function(machine_crash_nonpanic_core, NULL, false);
msecs = 1000; /* Wait at most a second for the other cpus to stop */
while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
mdelay(1);
msecs--;
}
if (atomic_read(&waiting_for_crash_ipi) > 0)
pr_warn("Non-crashing CPUs did not react to IPI\n");
crash_save_cpu(regs, smp_processor_id());
machine_kexec_mask_interrupts();
pr_info("Loading crashdump kernel...\n");
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Per Fransson | 67 | 69.07% | 1 | 20.00% |
Mika Westerberg | 17 | 17.53% | 1 | 20.00% |
Richard Purdie | 8 | 8.25% | 1 | 20.00% |
Will Deacon | 3 | 3.09% | 1 | 20.00% |
Russell King | 2 | 2.06% | 1 | 20.00% |
Total | 97 | 100.00% | 5 | 100.00% |
/*
* Function pointer to optional machine-specific reinitialization
*/
void (*kexec_reinit)(void);
void machine_kexec(struct kimage *image)
{
unsigned long page_list, reboot_entry_phys;
void (*reboot_entry)(void);
void *reboot_code_buffer;
/*
* This can only happen if machine_shutdown() failed to disable some
* CPU, and that can only happen if the checks in
* machine_kexec_prepare() were not correct. If this fails, we can't
* reliably kexec anyway, so BUG_ON is appropriate.
*/
BUG_ON(num_online_cpus() > 1);
page_list = image->head & PAGE_MASK;
reboot_code_buffer = page_address(image->control_code_page);
/* Prepare parameters for reboot_code_buffer*/
set_kernel_text_rw();
kexec_start_address = image->start;
kexec_indirection_page = page_list;
kexec_mach_type = machine_arch_type;
kexec_boot_atags = dt_mem ?: image->start - KEXEC_ARM_ZIMAGE_OFFSET
+ KEXEC_ARM_ATAGS_OFFSET;
/* copy our kernel relocation code to the control code page */
reboot_entry = fncpy(reboot_code_buffer,
&relocate_new_kernel,
relocate_new_kernel_size);
/* get the identity mapping physical address for the reboot code */
reboot_entry_phys = virt_to_idmap(reboot_entry);
pr_info("Bye!\n");
if (kexec_reinit)
kexec_reinit();
soft_restart(reboot_entry_phys);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Russell King | 60 | 48.39% | 3 | 27.27% |
Richard Purdie | 32 | 25.81% | 1 | 9.09% |
Stephen Warren | 9 | 7.26% | 2 | 18.18% |
Dave P Martin | 9 | 7.26% | 1 | 9.09% |
Eric Cooper | 7 | 5.65% | 1 | 9.09% |
Nikolay Borisov | 3 | 2.42% | 1 | 9.09% |
Kees Cook | 3 | 2.42% | 1 | 9.09% |
Will Deacon | 1 | 0.81% | 1 | 9.09% |
Total | 124 | 100.00% | 11 | 100.00% |
void arch_crash_save_vmcoreinfo(void)
{
#ifdef CONFIG_ARM_LPAE
VMCOREINFO_CONFIG(ARM_LPAE);
#endif
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Liu Hua | 17 | 100.00% | 1 | 100.00% |
Total | 17 | 100.00% | 1 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Per Fransson | 126 | 19.35% | 1 | 4.00% |
Will Deacon | 117 | 17.97% | 2 | 8.00% |
Richard Purdie | 117 | 17.97% | 2 | 8.00% |
Matthew Leach | 98 | 15.05% | 2 | 8.00% |
Russell King | 69 | 10.60% | 5 | 20.00% |
Stephen Warren | 28 | 4.30% | 2 | 8.00% |
Mika Westerberg | 17 | 2.61% | 1 | 4.00% |
Liu Hua | 17 | 2.61% | 1 | 4.00% |
Eric Cooper | 17 | 2.61% | 1 | 4.00% |
Dave P Martin | 17 | 2.61% | 1 | 4.00% |
Nikolay Borisov | 9 | 1.38% | 1 | 4.00% |
Vijaya Kumar K | 8 | 1.23% | 1 | 4.00% |
Geert Uytterhoeven | 3 | 0.46% | 1 | 4.00% |
Aaro Koskinen | 3 | 0.46% | 1 | 4.00% |
Kees Cook | 3 | 0.46% | 1 | 4.00% |
Tobias Klauser | 1 | 0.15% | 1 | 4.00% |
David Howells | 1 | 0.15% | 1 | 4.00% |
Total | 651 | 100.00% | 25 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.