mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 15:41:36 +00:00
pstore: Replace arguments for write_buf() API
As with the other API updates, this removes the long argument list in favor of passing a single pstore recaord. Signed-off-by: Kees Cook <keescook@chromium.org>
This commit is contained in:
parent
a61072aae6
commit
b10b471145
@ -37,6 +37,12 @@ static void notrace pstore_ftrace_call(unsigned long ip,
|
|||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct pstore_ftrace_record rec = {};
|
struct pstore_ftrace_record rec = {};
|
||||||
|
struct pstore_record record = {
|
||||||
|
.type = PSTORE_TYPE_FTRACE,
|
||||||
|
.buf = (char *)&rec,
|
||||||
|
.size = sizeof(rec),
|
||||||
|
.psi = psinfo,
|
||||||
|
};
|
||||||
|
|
||||||
if (unlikely(oops_in_progress))
|
if (unlikely(oops_in_progress))
|
||||||
return;
|
return;
|
||||||
@ -47,8 +53,7 @@ static void notrace pstore_ftrace_call(unsigned long ip,
|
|||||||
rec.parent_ip = parent_ip;
|
rec.parent_ip = parent_ip;
|
||||||
pstore_ftrace_write_timestamp(&rec, pstore_ftrace_stamp++);
|
pstore_ftrace_write_timestamp(&rec, pstore_ftrace_stamp++);
|
||||||
pstore_ftrace_encode_cpu(&rec, raw_smp_processor_id());
|
pstore_ftrace_encode_cpu(&rec, raw_smp_processor_id());
|
||||||
psinfo->write_buf(PSTORE_TYPE_FTRACE, 0, NULL, 0, (void *)&rec,
|
psinfo->write_buf(&record);
|
||||||
0, sizeof(rec), psinfo);
|
|
||||||
|
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
@ -587,8 +587,11 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
|
|||||||
const char *e = s + c;
|
const char *e = s + c;
|
||||||
|
|
||||||
while (s < e) {
|
while (s < e) {
|
||||||
|
struct pstore_record record = {
|
||||||
|
.type = PSTORE_TYPE_CONSOLE,
|
||||||
|
.psi = psinfo,
|
||||||
|
};
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u64 id;
|
|
||||||
|
|
||||||
if (c > psinfo->bufsize)
|
if (c > psinfo->bufsize)
|
||||||
c = psinfo->bufsize;
|
c = psinfo->bufsize;
|
||||||
@ -599,8 +602,9 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
|
|||||||
} else {
|
} else {
|
||||||
spin_lock_irqsave(&psinfo->buf_lock, flags);
|
spin_lock_irqsave(&psinfo->buf_lock, flags);
|
||||||
}
|
}
|
||||||
psinfo->write_buf(PSTORE_TYPE_CONSOLE, 0, &id, 0,
|
record.buf = (char *)s;
|
||||||
s, 0, c, psinfo);
|
record.size = c;
|
||||||
|
psinfo->write_buf(&record);
|
||||||
spin_unlock_irqrestore(&psinfo->buf_lock, flags);
|
spin_unlock_irqrestore(&psinfo->buf_lock, flags);
|
||||||
s += c;
|
s += c;
|
||||||
c = e - s;
|
c = e - s;
|
||||||
@ -630,10 +634,9 @@ static void pstore_unregister_console(void) {}
|
|||||||
|
|
||||||
static int pstore_write_compat(struct pstore_record *record)
|
static int pstore_write_compat(struct pstore_record *record)
|
||||||
{
|
{
|
||||||
return record->psi->write_buf(record->type, record->reason,
|
record->buf = psinfo->buf;
|
||||||
&record->id, record->part,
|
|
||||||
psinfo->buf, record->compressed,
|
return record->psi->write_buf(record);
|
||||||
record->size, record->psi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pstore_write_buf_user_compat(enum pstore_type_id type,
|
static int pstore_write_buf_user_compat(enum pstore_type_id type,
|
||||||
@ -653,6 +656,15 @@ static int pstore_write_buf_user_compat(enum pstore_type_id type,
|
|||||||
bufsize = psinfo->bufsize;
|
bufsize = psinfo->bufsize;
|
||||||
spin_lock_irqsave(&psinfo->buf_lock, flags);
|
spin_lock_irqsave(&psinfo->buf_lock, flags);
|
||||||
for (i = 0; i < size; ) {
|
for (i = 0; i < size; ) {
|
||||||
|
struct pstore_record record = {
|
||||||
|
.type = type,
|
||||||
|
.reason = reason,
|
||||||
|
.id = id,
|
||||||
|
.part = part,
|
||||||
|
.buf = psinfo->buf,
|
||||||
|
.compressed = compressed,
|
||||||
|
.psi = psi,
|
||||||
|
};
|
||||||
size_t c = min(size - i, bufsize);
|
size_t c = min(size - i, bufsize);
|
||||||
|
|
||||||
ret = __copy_from_user(psinfo->buf, buf + i, c);
|
ret = __copy_from_user(psinfo->buf, buf + i, c);
|
||||||
@ -660,8 +672,8 @@ static int pstore_write_buf_user_compat(enum pstore_type_id type,
|
|||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret = psi->write_buf(type, reason, id, part, psinfo->buf,
|
record.size = c;
|
||||||
compressed, c, psi);
|
ret = psi->write_buf(&record);
|
||||||
if (unlikely(ret < 0))
|
if (unlikely(ret < 0))
|
||||||
break;
|
break;
|
||||||
i += c;
|
i += c;
|
||||||
|
@ -378,23 +378,18 @@ static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
|
static int notrace ramoops_pstore_write_buf(struct pstore_record *record)
|
||||||
enum kmsg_dump_reason reason,
|
|
||||||
u64 *id, unsigned int part,
|
|
||||||
const char *buf,
|
|
||||||
bool compressed, size_t size,
|
|
||||||
struct pstore_info *psi)
|
|
||||||
{
|
{
|
||||||
struct ramoops_context *cxt = psi->data;
|
struct ramoops_context *cxt = record->psi->data;
|
||||||
struct persistent_ram_zone *prz;
|
struct persistent_ram_zone *prz;
|
||||||
size_t hlen;
|
size_t size, hlen;
|
||||||
|
|
||||||
if (type == PSTORE_TYPE_CONSOLE) {
|
if (record->type == PSTORE_TYPE_CONSOLE) {
|
||||||
if (!cxt->cprz)
|
if (!cxt->cprz)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
persistent_ram_write(cxt->cprz, buf, size);
|
persistent_ram_write(cxt->cprz, record->buf, record->size);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (type == PSTORE_TYPE_FTRACE) {
|
} else if (record->type == PSTORE_TYPE_FTRACE) {
|
||||||
int zonenum;
|
int zonenum;
|
||||||
|
|
||||||
if (!cxt->fprzs)
|
if (!cxt->fprzs)
|
||||||
@ -407,33 +402,36 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
|
|||||||
else
|
else
|
||||||
zonenum = 0;
|
zonenum = 0;
|
||||||
|
|
||||||
persistent_ram_write(cxt->fprzs[zonenum], buf, size);
|
persistent_ram_write(cxt->fprzs[zonenum], record->buf,
|
||||||
|
record->size);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (type == PSTORE_TYPE_PMSG) {
|
} else if (record->type == PSTORE_TYPE_PMSG) {
|
||||||
pr_warn_ratelimited("PMSG shouldn't call %s\n", __func__);
|
pr_warn_ratelimited("PMSG shouldn't call %s\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != PSTORE_TYPE_DMESG)
|
if (record->type != PSTORE_TYPE_DMESG)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Out of the various dmesg dump types, ramoops is currently designed
|
/*
|
||||||
|
* Out of the various dmesg dump types, ramoops is currently designed
|
||||||
* to only store crash logs, rather than storing general kernel logs.
|
* to only store crash logs, rather than storing general kernel logs.
|
||||||
*/
|
*/
|
||||||
if (reason != KMSG_DUMP_OOPS &&
|
if (record->reason != KMSG_DUMP_OOPS &&
|
||||||
reason != KMSG_DUMP_PANIC)
|
record->reason != KMSG_DUMP_PANIC)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Skip Oopes when configured to do so. */
|
/* Skip Oopes when configured to do so. */
|
||||||
if (reason == KMSG_DUMP_OOPS && !cxt->dump_oops)
|
if (record->reason == KMSG_DUMP_OOPS && !cxt->dump_oops)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Explicitly only take the first part of any new crash.
|
/*
|
||||||
|
* Explicitly only take the first part of any new crash.
|
||||||
* If our buffer is larger than kmsg_bytes, this can never happen,
|
* If our buffer is larger than kmsg_bytes, this can never happen,
|
||||||
* and if our buffer is smaller than kmsg_bytes, we don't want the
|
* and if our buffer is smaller than kmsg_bytes, we don't want the
|
||||||
* report split across multiple records.
|
* report split across multiple records.
|
||||||
*/
|
*/
|
||||||
if (part != 1)
|
if (record->part != 1)
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
if (!cxt->dprzs)
|
if (!cxt->dprzs)
|
||||||
@ -441,10 +439,12 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
|
|||||||
|
|
||||||
prz = cxt->dprzs[cxt->dump_write_cnt];
|
prz = cxt->dprzs[cxt->dump_write_cnt];
|
||||||
|
|
||||||
hlen = ramoops_write_kmsg_hdr(prz, compressed);
|
/* Build header and append record contents. */
|
||||||
|
hlen = ramoops_write_kmsg_hdr(prz, record->compressed);
|
||||||
|
size = record->size;
|
||||||
if (size + hlen > prz->buffer_size)
|
if (size + hlen > prz->buffer_size)
|
||||||
size = prz->buffer_size - hlen;
|
size = prz->buffer_size - hlen;
|
||||||
persistent_ram_write(prz, buf, size);
|
persistent_ram_write(prz, record->buf, size);
|
||||||
|
|
||||||
cxt->dump_write_cnt = (cxt->dump_write_cnt + 1) % cxt->max_dump_cnt;
|
cxt->dump_write_cnt = (cxt->dump_write_cnt + 1) % cxt->max_dump_cnt;
|
||||||
|
|
||||||
|
@ -142,19 +142,11 @@ struct pstore_record {
|
|||||||
* Returns 0 on success, and non-zero on error.
|
* Returns 0 on success, and non-zero on error.
|
||||||
*
|
*
|
||||||
* @write_buf:
|
* @write_buf:
|
||||||
* Perform a frontend write to a backend record, using a specified
|
* Perform a frontend write to a backend record. The record contains
|
||||||
* buffer. Unlike @write, this does not use the @psi @buf.
|
* all metadata and the buffer to write to backend storage. (Unlike
|
||||||
|
* @write, this does not use the @psi @buf.)
|
||||||
*
|
*
|
||||||
* @type: in: pstore record type to write
|
* @record: pointer to record metadata.
|
||||||
* @reason:
|
|
||||||
* in: pstore write reason
|
|
||||||
* @id: out: unique identifier for the record
|
|
||||||
* @part: in: position in a multipart write
|
|
||||||
* @buf: in: pointer to contents to write to backend record
|
|
||||||
* @compressed:
|
|
||||||
* in: if the record is compressed
|
|
||||||
* @size: in: size of the write
|
|
||||||
* @psi: in: pointer to the struct pstore_info for the backend
|
|
||||||
*
|
*
|
||||||
* Returns 0 on success, and non-zero on error.
|
* Returns 0 on success, and non-zero on error.
|
||||||
*
|
*
|
||||||
@ -203,10 +195,7 @@ struct pstore_info {
|
|||||||
int (*close)(struct pstore_info *psi);
|
int (*close)(struct pstore_info *psi);
|
||||||
ssize_t (*read)(struct pstore_record *record);
|
ssize_t (*read)(struct pstore_record *record);
|
||||||
int (*write)(struct pstore_record *record);
|
int (*write)(struct pstore_record *record);
|
||||||
int (*write_buf)(enum pstore_type_id type,
|
int (*write_buf)(struct pstore_record *record);
|
||||||
enum kmsg_dump_reason reason, u64 *id,
|
|
||||||
unsigned int part, const char *buf, bool compressed,
|
|
||||||
size_t size, struct pstore_info *psi);
|
|
||||||
int (*write_buf_user)(enum pstore_type_id type,
|
int (*write_buf_user)(enum pstore_type_id type,
|
||||||
enum kmsg_dump_reason reason, u64 *id,
|
enum kmsg_dump_reason reason, u64 *id,
|
||||||
unsigned int part, const char __user *buf,
|
unsigned int part, const char __user *buf,
|
||||||
|
Loading…
Reference in New Issue
Block a user