int machine_kexec_prepare(struct kimage *image)
{
#ifdef CONFIG_KEXEC_HARDBOOT
	struct kexec_segment *current_segment;
	__be32 header;
	int i, err;

	/* 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];

		err = memblock_is_region_memory(current_segment->mem,
						current_segment->memsz);
		if (!err)
			return - EINVAL;

		if(current_segment->mem == image->start)
			mem_text_write_kernel_word(&kexec_kernel_len, current_segment->memsz);

		err = get_user(header, (__be32*)current_segment->buf);
		if (err)
			return err;

		if (be32_to_cpu(header) == OF_DT_HEADER)
		{
			mem_text_write_kernel_word(&kexec_boot_atags, current_segment->mem);
			mem_text_write_kernel_word(&kexec_boot_atags_len, current_segment->memsz);
		}
	}
#endif
	return 0;
}
예제 #2
0
inline void arm_write_hook ( void *target, char *code )
{
    unsigned long *target_arm = (unsigned long *)target;
    unsigned long *code_arm = (unsigned long *)code;

    mem_text_write_kernel_word(target_arm, *code_arm);
    mem_text_write_kernel_word(target_arm + 1, *(code_arm + 1));
    mem_text_write_kernel_word(target_arm + 2, *(code_arm + 2));
}
예제 #3
0
파일: util.c 프로젝트: Ch0pp3r/suterusu
inline void arm_write_hook ( void *target, char *code )
{
    unsigned long *target_arm = (unsigned long *)target;
    unsigned long *code_arm = (unsigned long *)code;

    // We should have something more generalized here, but we'll
    // get away with it since the ARM hook is always 12 bytes
    mem_text_write_kernel_word(target_arm, *code_arm);
    mem_text_write_kernel_word(target_arm + 1, *(code_arm + 1));
    mem_text_write_kernel_word(target_arm + 2, *(code_arm + 2));
}
void machine_kexec(struct kimage *image)
{
	unsigned long page_list;
	unsigned long reboot_code_buffer_phys;
	void *reboot_code_buffer;

	arch_kexec();

	page_list = image->head & PAGE_MASK;

	/* we need both effective and real address here */
	reboot_code_buffer_phys =
	    page_to_pfn(image->control_code_page) << PAGE_SHIFT;
	reboot_code_buffer = page_address(image->control_code_page);

	/* Prepare parameters for reboot_code_buffer*/

#ifdef CONFIG_KEXEC_HARDBOOT
	mem_text_write_kernel_word(&kexec_start_address, image->start);
	mem_text_write_kernel_word(&kexec_indirection_page, page_list);
	mem_text_write_kernel_word(&kexec_mach_type, machine_arch_type);
	if (!kexec_boot_atags)
		mem_text_write_kernel_word(&kexec_boot_atags, image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET);
	mem_text_write_kernel_word(&kexec_hardboot, image->hardboot);
#else

	kexec_start_address = image->start;
	kexec_indirection_page = page_list;
	kexec_mach_type = machine_arch_type;
	kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
#endif

	/* copy our kernel relocation code to the control code page */
	memcpy(reboot_code_buffer,
	       relocate_new_kernel, relocate_new_kernel_size);


	flush_icache_range((unsigned long) reboot_code_buffer,
			   (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
	printk(KERN_INFO "Bye!\n");

	if (kexec_reinit)
		kexec_reinit();

#ifdef CONFIG_KEXEC_HARDBOOT
	/* Run any final machine-specific shutdown code. */
	if (image->hardboot && kexec_hardboot_hook)
		kexec_hardboot_hook();
#endif

	soft_restart(reboot_code_buffer_phys);
}
void machine_kexec(struct kimage *image)
{
	unsigned long page_list;
	unsigned long reboot_code_buffer_phys;
	void *reboot_code_buffer;

	arch_kexec();

	page_list = image->head & PAGE_MASK;

	/* we need both effective and real address here */
	reboot_code_buffer_phys =
	    page_to_pfn(image->control_code_page) << PAGE_SHIFT;
	reboot_code_buffer = page_address(image->control_code_page);

	/* Prepare parameters for reboot_code_buffer*/
	mem_text_write_kernel_word(&kexec_start_address, image->start);
	mem_text_write_kernel_word(&kexec_indirection_page, page_list);
	mem_text_write_kernel_word(&kexec_mach_type, machine_arch_type);
	mem_text_write_kernel_word(&kexec_boot_atags, image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET);

#ifdef CONFIG_KEXEC_HARDBOOT
	mem_text_write_kernel_word(&kexec_hardboot, image->hardboot);
#endif

	/* copy our kernel relocation code to the control code page */
	memcpy(reboot_code_buffer,
	       relocate_new_kernel, relocate_new_kernel_size);


	flush_icache_range((unsigned long) reboot_code_buffer,
			   (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
	printk(KERN_INFO "Bye!\n");

	if (kexec_reinit)
		kexec_reinit();
	local_irq_disable();
	local_fiq_disable();
	setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
#ifdef CONFIG_KEXEC_HARDBOOT
	if (image->hardboot && kexec_hardboot_hook)
		/* Run any final machine-specific shutdown code. */
		kexec_hardboot_hook();
#endif
	flush_cache_all();
	outer_flush_all();
	outer_disable();
	cpu_proc_fin();
	outer_inv_all();
	flush_cache_all();
	__virt_to_phys(cpu_reset)(reboot_code_buffer_phys);
}
예제 #6
0
파일: wp_mod.c 프로젝트: McBane87/wp_mod
inline void arm_write_hook ( void *target, char *code )
{
#ifdef ARM64
    u32 *target_arm = (u32 *)target;
    u32 *code_arm = (u32 *)code;
#else
    unsigned long *target_arm = (unsigned long *)target;
    unsigned long *code_arm = (unsigned long *)code;
#endif

    mem_text_write_kernel_word(target_arm, *code_arm);
    mem_text_write_kernel_word(target_arm + 1, *(code_arm + 1));
    mem_text_write_kernel_word(target_arm + 2, *(code_arm + 2));
}
예제 #7
0
void machine_kexec(struct kimage *image)
{
    unsigned long page_list;
    unsigned long reboot_code_buffer_phys;
    unsigned long reboot_entry = (unsigned long)relocate_new_kernel;
    unsigned long reboot_entry_phys;
    void *reboot_code_buffer;

    if (num_online_cpus() > 1) {
        pr_err("kexec: error: multiple CPUs still online\n");
        return;
    }

    page_list = image->head & PAGE_MASK;

    /* we need both effective and real address here */
    reboot_code_buffer_phys =
        page_to_pfn(image->control_code_page) << PAGE_SHIFT;
    reboot_code_buffer = page_address(image->control_code_page);

    /* Prepare parameters for reboot_code_buffer*/
    mem_text_write_kernel_word(&kexec_start_address, image->start);
    mem_text_write_kernel_word(&kexec_indirection_page, page_list);
    mem_text_write_kernel_word(&kexec_mach_type, machine_arch_type);
    if (!kexec_boot_atags)
        mem_text_write_kernel_word(&kexec_boot_atags, image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET);
#ifdef CONFIG_KEXEC_HARDBOOT
    mem_text_write_kernel_word(&kexec_hardboot, image->hardboot);
#endif

    /* copy our kernel relocation code to the control code page */
    reboot_entry = fncpy(reboot_code_buffer,
                         reboot_entry,
                         relocate_new_kernel_size);
    reboot_entry_phys = (unsigned long)reboot_entry +
                        (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer);

    printk(KERN_INFO "Bye!\n");

    if (kexec_reinit)
        kexec_reinit();

#ifdef CONFIG_KEXEC_HARDBOOT
    /* Run any final machine-specific shutdown code. */
    if (image->hardboot && kexec_hardboot_hook)
        kexec_hardboot_hook();
#endif

    soft_restart(reboot_code_buffer_phys);
}