Example #1
0
static int ipanic_die(struct notifier_block *self, unsigned long cmd, void *ptr)
{
	struct kmsg_dumper dumper;
	struct die_args *dargs = (struct die_args *)ptr;

#if 0//                           
		return NOTIFY_DONE;
	
#endif
	aee_disable_api();

	aee_rr_rec_fiq_step(AEE_FIQ_STEP_KE_IPANIC_DIE);
	mrdump_mini_ke_cpu_regs(dargs->regs);
	flush_cache_all();

	/* No return if mrdump is enable */
	aee_kdump_reboot(AEE_REBOOT_MODE_KERNEL_OOPS, "Kernel Oops");

	smp_send_stop();

	ipanic_mrdump_mini(AEE_REBOOT_MODE_KERNEL_PANIC, "kernel Oops");
	ipanic_klog_region(&dumper);
	ipanic_data_to_sd(IPANIC_DT_KERNEL_LOG, &dumper);
	ipanic_data_to_sd(IPANIC_DT_CURRENT_TSK, dargs->regs);
	return NOTIFY_DONE;
}
Example #2
0
struct ipanic_header *ipanic_header_from_sd(unsigned int offset, unsigned int magic)
{
	struct ipanic_data_header *dheader;
	int dt;
	char str[256];
	size_t size = 0;
	struct ipanic_header *header;
	struct ipanic_data_header dheader_header = {
		.type = IPANIC_DT_HEADER,
		.offset = offset,
		.used = sizeof(struct ipanic_header),
	};
	header = (struct ipanic_header *)ipanic_data_from_sd(&dheader_header, 0);
	if (IS_ERR_OR_NULL((void *)header)) {
		LOGD("read header failed[%ld]\n", PTR_ERR((void *)header));
		header = NULL;
	} else if (header->magic != magic) {
		LOGD("no ipanic data[%x]\n", header->magic);
		kfree(header);
		header = NULL;
		ipanic_erase();
	} else {
		for (dt = IPANIC_DT_HEADER + 1; dt < IPANIC_DT_RESERVED31; dt++) {
			dheader = &header->data_hdr[dt];
			if (dheader->valid) {
				size += snprintf(str + size, 256 - size, "%s[%x@%x],",
						 dheader->name, dheader->used, dheader->offset);
			}
		}
		LOGD("ipanic data available^v^%s^v^\n", str);
	}
	return header;
}

struct aee_oops *ipanic_oops_from_sd(void)
{
	struct aee_oops *oops = NULL;
	struct ipanic_header *hdr = NULL;
	struct ipanic_data_header *dheader;
	char *data;
	int i;
	hdr = ipanic_header_from_sd(0, AEE_IPANIC_MAGIC);
	if (hdr == NULL) {
		return NULL;
	}

	oops = aee_oops_create(AE_DEFECT_FATAL, AE_KE, IPANIC_MODULE_TAG);
	if (oops == NULL) {
		LOGE("%s: can not allocate buffer\n", __func__);
		return NULL;
	}

	for (i = IPANIC_DT_HEADER + 1; i < IPANIC_DT_RESERVED31; i++) {
		dheader = &hdr->data_hdr[i];
		if (dheader->valid == 0) {
			continue;
		}
		data = ipanic_data_from_sd(dheader, 1);
		if (data) {
			switch (i) {
			case IPANIC_DT_KERNEL_LOG:
				oops->console = data;
				oops->console_len = dheader->used;
				break;
			case IPANIC_DT_MINI_RDUMP:
				oops->mini_rdump = data;
				oops->mini_rdump_len = dheader->used;
				break;
			case IPANIC_DT_MAIN_LOG:
				oops->android_main = data;
				oops->android_main_len = dheader->used;
				break;
			case IPANIC_DT_SYSTEM_LOG:
				oops->android_system = data;
				oops->android_system_len = dheader->used;
				break;
			case IPANIC_DT_EVENTS_LOG:
				/* Todo .. */
				break;
			case IPANIC_DT_RADIO_LOG:
				oops->android_radio = data;
				oops->android_radio_len = dheader->used;
				break;
			case IPANIC_DT_CURRENT_TSK:
				memcpy(oops->process_path, data, sizeof(struct aee_process_info));
				break;
			case IPANIC_DT_MMPROFILE:
				oops->mmprofile = data;
				oops->mmprofile_len = dheader->used;
				break;
			default:
				LOGI("%s: [%d] NOT USED.\n", __func__, i);
			}
		} else {
			LOGW("%s: read %s failed, %x@%x\n", __func__,
			     dheader->name, dheader->used, dheader->offset);
		}
	}
	return oops;
}

int ipanic(struct notifier_block *this, unsigned long event, void *ptr)
{
	struct ipanic_data_header *dheader;
	struct kmsg_dumper dumper;
	ipanic_atf_log_rec_t atf_log = {ATF_LOG_SIZE, 0, 0};
	int dt;
	int errno;
	struct ipanic_header *ipanic_hdr;
	aee_rr_rec_fiq_step(AEE_FIQ_STEP_KE_IPANIC_START);
	aee_rr_rec_exp_type(2);
	bust_spinlocks(1);
	spin_lock_irq(&ipanic_lock);
	aee_disable_api();
	mrdump_mini_ke_cpu_regs(NULL);
	ipanic_mrdump_mini(AEE_REBOOT_MODE_KERNEL_PANIC, "kernel PANIC");
	if (!ipanic_data_is_valid(IPANIC_DT_KERNEL_LOG)) {
		ipanic_klog_region(&dumper);
		errno = ipanic_data_to_sd(IPANIC_DT_KERNEL_LOG, &dumper);
		if (errno == -1)
			aee_nested_printf("$");
	}
	ipanic_klog_region(&dumper);
	errno = ipanic_data_to_sd(IPANIC_DT_OOPS_LOG, &dumper);
	if (errno == -1)
		aee_nested_printf("$");
	ipanic_data_to_sd(IPANIC_DT_CURRENT_TSK, 0);
	/* kick wdt after save the most critical infos */
	ipanic_kick_wdt();
	ipanic_data_to_sd(IPANIC_DT_MAIN_LOG, (void *)1);
	ipanic_data_to_sd(IPANIC_DT_SYSTEM_LOG, (void *)4);
	ipanic_data_to_sd(IPANIC_DT_EVENTS_LOG, (void *)2);
	ipanic_data_to_sd(IPANIC_DT_RADIO_LOG, (void *)3);
	aee_wdt_dump_info();
	ipanic_klog_region(&dumper);
	ipanic_data_to_sd(IPANIC_DT_WDT_LOG, &dumper);
#ifdef CONFIG_MTK_WQ_DEBUG
	mt_dump_wq_debugger();
#endif
	ipanic_klog_region(&dumper);
	ipanic_data_to_sd(IPANIC_DT_WQ_LOG, &dumper);
	ipanic_data_to_sd(IPANIC_DT_MMPROFILE, 0);
	ipanic_data_to_sd(IPANIC_DT_ATF_LOG, &atf_log);
	errno = ipanic_header_to_sd(0);
	if (!IS_ERR(ERR_PTR(errno)))
		mrdump_mini_ipanic_done();
	ipanic_klog_region(&dumper);
	ipanic_data_to_sd(IPANIC_DT_LAST_LOG, &dumper);
	LOGD("ipanic done^_^");
	ipanic_hdr = ipanic_header();
	for (dt = IPANIC_DT_HEADER + 1; dt < IPANIC_DT_RESERVED31; dt++) {
		dheader = &ipanic_hdr->data_hdr[dt];
		if (dheader->valid) {
			LOGD("%s[%x@%x],", dheader->name, dheader->used, dheader->offset);
		}
	}
	LOGD("^_^\n");
	aee_rr_rec_fiq_step(AEE_FIQ_STEP_KE_IPANIC_DONE);

	return NOTIFY_DONE;
}

void ipanic_recursive_ke(struct pt_regs *regs, struct pt_regs *excp_regs, int cpu)
{
	int errno;
	struct kmsg_dumper dumper;
	aee_nested_printf("minidump\n");
	aee_rr_rec_exp_type(3);
	bust_spinlocks(1);
	flush_cache_all();
#ifdef __aarch64__
	cpu_cache_off();
#else
	cpu_proc_fin();
#endif
	mrdump_mini_ke_cpu_regs(excp_regs);
	mrdump_mini_per_cpu_regs(cpu, regs);
	flush_cache_all();
	ipanic_mrdump_mini(AEE_REBOOT_MODE_NESTED_EXCEPTION, "Nested Panic");

	ipanic_data_to_sd(IPANIC_DT_CURRENT_TSK, 0);
	ipanic_kick_wdt();
	ipanic_klog_region(&dumper);
	ipanic_data_to_sd(IPANIC_DT_KERNEL_LOG, &dumper);
	errno = ipanic_header_to_sd(0);
	if (!IS_ERR(ERR_PTR(errno)))
		mrdump_mini_ipanic_done();
	if (ipanic_dt_active(IPANIC_DT_RAM_DUMP)) {
		aee_nested_printf("RAMDUMP.\n");
		__mrdump_create_oops_dump(AEE_REBOOT_MODE_NESTED_EXCEPTION, excp_regs,
					  "Nested Panic");
	}
	bust_spinlocks(0);
}