Пример #1
0
static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
				   int *count, struct timespec *time,
				   char **buf, struct pstore_info *psi)
{
	ssize_t size;
	struct ramoops_context *cxt = psi->data;
	struct persistent_ram_zone *prz;

	prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt,
				   cxt->max_dump_cnt, id, type,
				   PSTORE_TYPE_DMESG, 1);
	if (!prz)
		prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt,
					   1, id, type, PSTORE_TYPE_CONSOLE, 0);
	if (!prz)
		prz = ramoops_get_next_prz(&cxt->fprz, &cxt->ftrace_read_cnt,
					   1, id, type, PSTORE_TYPE_FTRACE, 0);
	if (!prz)
		return 0;

	/* TODO(kees): Bogus time for the moment. */
	time->tv_sec = 0;
	time->tv_nsec = 0;

	size = persistent_ram_old_size(prz);
	*buf = kmalloc(size, GFP_KERNEL);
	if (*buf == NULL)
		return -ENOMEM;
	memcpy(*buf, persistent_ram_old(prz), size);

	return size;
}
static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
				   int *count, struct timespec *time,
				   char **buf, struct pstore_info *psi)
{
	ssize_t size;
	ssize_t ecc_notice_size;
	struct ramoops_context *cxt = psi->data;
	struct persistent_ram_zone *prz;

	prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt,
				   cxt->max_dump_cnt, id, type,
				   PSTORE_TYPE_DMESG, 1);
	if (!prz_ok(prz)) {
		prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt,
					   1, id, type, PSTORE_TYPE_CONSOLE, 0);
		if (prz && !persistent_ram_old_size(prz))
			persistent_ram_annotation_merge(NULL);
	}
	if (!prz_ok(prz))
		prz = ramoops_get_next_prz(&cxt->fprz, &cxt->ftrace_read_cnt,
					   1, id, type, PSTORE_TYPE_FTRACE, 0);
	if (!prz_ok(prz)) {
		prz = ramoops_get_next_prz(&cxt->aprz, &cxt->annotate_read_cnt,
					1, id, type, PSTORE_TYPE_ANNOTATE, 0);
		persistent_ram_annotation_merge(prz);
	}
	if (!prz_ok(prz))
		prz = ramoops_get_next_prz(&cxt->mprz, &cxt->pmsg_read_cnt,
					   1, id, type, PSTORE_TYPE_PMSG, 0);
	if (!prz_ok(prz))
		return 0;

	/* TODO(kees): Bogus time for the moment. */
	time->tv_sec = 0;
	time->tv_nsec = 0;

	size = persistent_ram_old_size(prz);

	/* ECC correction notice */
	ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);

	*buf = kmalloc(size + ecc_notice_size + 1, GFP_KERNEL);
	if (*buf == NULL)
		return -ENOMEM;

	memcpy(*buf, persistent_ram_old(prz), size);
	persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1);

	return size + ecc_notice_size;
}
Пример #3
0
static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
				   int *count, struct timespec *time,
				   char **buf, bool *compressed,
				   struct pstore_info *psi)
{
	ssize_t size;
	ssize_t ecc_notice_size;
	struct ramoops_context *cxt = psi->data;
	struct persistent_ram_zone *prz;

	prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt,
				   cxt->max_dump_cnt, id, type,
				   PSTORE_TYPE_DMESG, 1);
	if (!prz_ok(prz))
		prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt,
					   1, id, type, PSTORE_TYPE_CONSOLE, 0);
	if (!prz_ok(prz)) {
		prz = ramoops_get_next_prz(&cxt->bprz, &cxt->bconsole_read_cnt,
					   1, id, type, PSTORE_TYPE_CONSOLE, 0);
		/*pr_notice("pstore: pstore_read bprz type: %d count %d id %llx\n", *type, cxt->bconsole_read_cnt, *id);
		*id = 2;*/
	}
	if (!prz_ok(prz))
		prz = ramoops_get_next_prz(&cxt->fprz, &cxt->ftrace_read_cnt,
					   1, id, type, PSTORE_TYPE_FTRACE, 0);
	if (!prz_ok(prz))
		prz = ramoops_get_next_prz(&cxt->mprz, &cxt->pmsg_read_cnt,
					   1, id, type, PSTORE_TYPE_PMSG, 0);
	if (!prz_ok(prz))
		return 0;

	size = persistent_ram_old_size(prz);

	/* ECC correction notice */
	ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);

	*buf = kmalloc(size + ecc_notice_size + 1, GFP_KERNEL);
	if (*buf == NULL)
		return -ENOMEM;

	memcpy(*buf, persistent_ram_old(prz), size);
	ramoops_read_kmsg_hdr(*buf, time, compressed);
	persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1);

	return size + ecc_notice_size;
}
Пример #4
0
static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
				   int *count, struct timespec *time,
				   char **buf, bool *compressed,
				   struct pstore_info *psi)
{
	ssize_t size;
	ssize_t ecc_notice_size;
	struct ramoops_context *cxt = psi->data;
	struct persistent_ram_zone *prz;
	int header_length;

	prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt,
				   cxt->max_dump_cnt, id, type,
				   PSTORE_TYPE_DMESG, 1);
	if (!prz)
		prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt,
					   1, id, type, PSTORE_TYPE_CONSOLE, 0);
	if (!prz)
		prz = ramoops_get_next_prz(&cxt->fprz, &cxt->ftrace_read_cnt,
					   1, id, type, PSTORE_TYPE_FTRACE, 0);
	if (!prz)
		return 0;

	if (!persistent_ram_old(prz))
		return 0;

	size = persistent_ram_old_size(prz);
	header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz), time,
			compressed);
	size -= header_length;

	/* ECC correction notice */
	ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);

	*buf = kmalloc(size + ecc_notice_size + 1, GFP_KERNEL);
	if (*buf == NULL)
		return -ENOMEM;

	memcpy(*buf, (char *)persistent_ram_old(prz) + header_length, size);
	persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1);

	return size + ecc_notice_size;
}
Пример #5
0
static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
				   int *count, struct timespec *time,
				   char **buf, bool *compressed,
				   ssize_t *ecc_notice_size,
				   struct pstore_info *psi)
{
	ssize_t size;
	struct ramoops_context *cxt = psi->data;
	struct persistent_ram_zone *prz = NULL;
	int header_length = 0;

	/* Ramoops headers provide time stamps for PSTORE_TYPE_DMESG, but
	 * PSTORE_TYPE_CONSOLE and PSTORE_TYPE_FTRACE don't currently have
	 * valid time stamps, so it is initialized to zero.
	 */
	time->tv_sec = 0;
	time->tv_nsec = 0;
	*compressed = false;

	/* Find the next valid persistent_ram_zone for DMESG */
	while (cxt->dump_read_cnt < cxt->max_dump_cnt && !prz) {
		prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt,
					   cxt->max_dump_cnt, id, type,
					   PSTORE_TYPE_DMESG, 1);
		if (!prz_ok(prz))
			continue;
		header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz),
						      time, compressed);
		/* Clear and skip this DMESG record if it has no valid header */
		if (!header_length) {
			persistent_ram_free_old(prz);
			persistent_ram_zap(prz);
			prz = NULL;
		}
	}

	if (!prz_ok(prz))
		prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt,
					   1, id, type, PSTORE_TYPE_CONSOLE, 0);
	if (!prz_ok(prz))
		prz = ramoops_get_next_prz(&cxt->fprz, &cxt->ftrace_read_cnt,
					   1, id, type, PSTORE_TYPE_FTRACE, 0);
	if (!prz_ok(prz))
		prz = ramoops_get_next_prz(&cxt->mprz, &cxt->pmsg_read_cnt,
					   1, id, type, PSTORE_TYPE_PMSG, 0);
	if (!prz_ok(prz))
		return 0;

	size = persistent_ram_old_size(prz) - header_length;

	/* ECC correction notice */
	*ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);

	*buf = kmalloc(size + *ecc_notice_size + 1, GFP_KERNEL);
	if (*buf == NULL)
		return -ENOMEM;

	memcpy(*buf, (char *)persistent_ram_old(prz) + header_length, size);
	persistent_ram_ecc_string(prz, *buf + size, *ecc_notice_size + 1);

	return size;
}
Пример #6
0
static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
				   int *count, struct timespec *time,
				   char **buf, bool *compressed,
				   ssize_t *ecc_notice_size,
				   struct pstore_info *psi)
{
	ssize_t size = 0;
	struct ramoops_context *cxt = psi->data;
	struct persistent_ram_zone *prz = NULL;
	int header_length = 0;
	bool free_prz = false;

	/* Ramoops headers provide time stamps for PSTORE_TYPE_DMESG, but
	 * PSTORE_TYPE_CONSOLE and PSTORE_TYPE_FTRACE don't currently have
	 * valid time stamps, so it is initialized to zero.
	 */
	time->tv_sec = 0;
	time->tv_nsec = 0;
	*compressed = false;

	/* Find the next valid persistent_ram_zone for DMESG */
	while (cxt->dump_read_cnt < cxt->max_dump_cnt && !prz) {
		prz = ramoops_get_next_prz(cxt->dprzs, &cxt->dump_read_cnt,
					   cxt->max_dump_cnt, id, type,
					   PSTORE_TYPE_DMESG, 1);
		if (!prz_ok(prz))
			continue;
		header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz),
						      time, compressed);
		/* Clear and skip this DMESG record if it has no valid header */
		if (!header_length) {
			persistent_ram_free_old(prz);
			persistent_ram_zap(prz);
			prz = NULL;
		}
	}

	if (!prz_ok(prz))
		prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt,
					   1, id, type, PSTORE_TYPE_CONSOLE, 0);

	if (!prz_ok(prz))
		prz = ramoops_get_next_prz(&cxt->mprz, &cxt->pmsg_read_cnt,
					   1, id, type, PSTORE_TYPE_PMSG, 0);

	/* ftrace is last since it may want to dynamically allocate memory. */
	if (!prz_ok(prz)) {
		if (!(cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)) {
			prz = ramoops_get_next_prz(cxt->fprzs,
					&cxt->ftrace_read_cnt, 1, id, type,
					PSTORE_TYPE_FTRACE, 0);
		} else {
			/*
			 * Build a new dummy record which combines all the
			 * per-cpu records including metadata and ecc info.
			 */
			struct persistent_ram_zone *tmp_prz, *prz_next;

			tmp_prz = kzalloc(sizeof(struct persistent_ram_zone),
					  GFP_KERNEL);
			if (!tmp_prz)
				return -ENOMEM;
			free_prz = true;

			while (cxt->ftrace_read_cnt < cxt->max_ftrace_cnt) {
				prz_next = ramoops_get_next_prz(cxt->fprzs,
						&cxt->ftrace_read_cnt,
						cxt->max_ftrace_cnt, id,
						type, PSTORE_TYPE_FTRACE, 0);

				if (!prz_ok(prz_next))
					continue;

				tmp_prz->ecc_info = prz_next->ecc_info;
				tmp_prz->corrected_bytes +=
						prz_next->corrected_bytes;
				tmp_prz->bad_blocks += prz_next->bad_blocks;
				size = ftrace_log_combine(tmp_prz, prz_next);
				if (size)
					goto out;
			}
			*id = 0;
			prz = tmp_prz;
		}
	}

	if (!prz_ok(prz)) {
		size = 0;
		goto out;
	}

	size = persistent_ram_old_size(prz) - header_length;

	/* ECC correction notice */
	*ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);

	*buf = kmalloc(size + *ecc_notice_size + 1, GFP_KERNEL);
	if (*buf == NULL) {
		size = -ENOMEM;
		goto out;
	}

	memcpy(*buf, (char *)persistent_ram_old(prz) + header_length, size);

	persistent_ram_ecc_string(prz, *buf + size, *ecc_notice_size + 1);

out:
	if (free_prz) {
		kfree(prz->old_log);
		kfree(prz);
	}

	return size;
}