linux/include/linux/pstore.h
<<
>>
Prefs
   1/*
   2 * Persistent Storage - pstore.h
   3 *
   4 * Copyright (C) 2010 Intel Corporation <tony.luck@intel.com>
   5 *
   6 * This code is the generic layer to export data records from platform
   7 * level persistent storage via a file system.
   8 *
   9 *  This program is free software; you can redistribute it and/or modify
  10 *  it under the terms of the GNU General Public License version 2 as
  11 *  published by the Free Software Foundation.
  12 *
  13 *  This program is distributed in the hope that it will be useful,
  14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 *  GNU General Public License for more details.
  17 *
  18 *  You should have received a copy of the GNU General Public License
  19 *  along with this program; if not, write to the Free Software
  20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21 */
  22#ifndef _LINUX_PSTORE_H
  23#define _LINUX_PSTORE_H
  24
  25#include <linux/compiler.h>
  26#include <linux/errno.h>
  27#include <linux/kmsg_dump.h>
  28#include <linux/mutex.h>
  29#include <linux/semaphore.h>
  30#include <linux/time.h>
  31#include <linux/types.h>
  32
  33struct module;
  34
  35/*
  36 * pstore record types (see fs/pstore/platform.c for pstore_type_names[])
  37 * These values may be written to storage (see EFI vars backend), so
  38 * they are kind of an ABI. Be careful changing the mappings.
  39 */
  40enum pstore_type_id {
  41        /* Frontend storage types */
  42        PSTORE_TYPE_DMESG       = 0,
  43        PSTORE_TYPE_MCE         = 1,
  44        PSTORE_TYPE_CONSOLE     = 2,
  45        PSTORE_TYPE_FTRACE      = 3,
  46
  47        /* PPC64-specific partition types */
  48        PSTORE_TYPE_PPC_RTAS    = 4,
  49        PSTORE_TYPE_PPC_OF      = 5,
  50        PSTORE_TYPE_PPC_COMMON  = 6,
  51        PSTORE_TYPE_PMSG        = 7,
  52        PSTORE_TYPE_PPC_OPAL    = 8,
  53
  54        /* End of the list */
  55        PSTORE_TYPE_MAX
  56};
  57
  58const char *pstore_type_to_name(enum pstore_type_id type);
  59enum pstore_type_id pstore_name_to_type(const char *name);
  60
  61struct pstore_info;
  62/**
  63 * struct pstore_record - details of a pstore record entry
  64 * @psi:        pstore backend driver information
  65 * @type:       pstore record type
  66 * @id:         per-type unique identifier for record
  67 * @time:       timestamp of the record
  68 * @buf:        pointer to record contents
  69 * @size:       size of @buf
  70 * @ecc_notice_size:
  71 *              ECC information for @buf
  72 *
  73 * Valid for PSTORE_TYPE_DMESG @type:
  74 *
  75 * @count:      Oops count since boot
  76 * @reason:     kdump reason for notification
  77 * @part:       position in a multipart record
  78 * @compressed: whether the buffer is compressed
  79 *
  80 */
  81struct pstore_record {
  82        struct pstore_info      *psi;
  83        enum pstore_type_id     type;
  84        u64                     id;
  85        struct timespec64       time;
  86        char                    *buf;
  87        ssize_t                 size;
  88        ssize_t                 ecc_notice_size;
  89
  90        int                     count;
  91        enum kmsg_dump_reason   reason;
  92        unsigned int            part;
  93        bool                    compressed;
  94};
  95
  96/**
  97 * struct pstore_info - backend pstore driver structure
  98 *
  99 * @owner:      module which is responsible for this backend driver
 100 * @name:       name of the backend driver
 101 *
 102 * @buf_lock:   semaphore to serialize access to @buf
 103 * @buf:        preallocated crash dump buffer
 104 * @bufsize:    size of @buf available for crash dump bytes (must match
 105 *              smallest number of bytes available for writing to a
 106 *              backend entry, since compressed bytes don't take kindly
 107 *              to being truncated)
 108 *
 109 * @read_mutex: serializes @open, @read, @close, and @erase callbacks
 110 * @flags:      bitfield of frontends the backend can accept writes for
 111 * @data:       backend-private pointer passed back during callbacks
 112 *
 113 * Callbacks:
 114 *
 115 * @open:
 116 *      Notify backend that pstore is starting a full read of backend
 117 *      records. Followed by one or more @read calls, and a final @close.
 118 *
 119 *      @psi:   in: pointer to the struct pstore_info for the backend
 120 *
 121 *      Returns 0 on success, and non-zero on error.
 122 *
 123 * @close:
 124 *      Notify backend that pstore has finished a full read of backend
 125 *      records. Always preceded by an @open call and one or more @read
 126 *      calls.
 127 *
 128 *      @psi:   in: pointer to the struct pstore_info for the backend
 129 *
 130 *      Returns 0 on success, and non-zero on error. (Though pstore will
 131 *      ignore the error.)
 132 *
 133 * @read:
 134 *      Read next available backend record. Called after a successful
 135 *      @open.
 136 *
 137 *      @record:
 138 *              pointer to record to populate. @buf should be allocated
 139 *              by the backend and filled. At least @type and @id should
 140 *              be populated, since these are used when creating pstorefs
 141 *              file names.
 142 *
 143 *      Returns record size on success, zero when no more records are
 144 *      available, or negative on error.
 145 *
 146 * @write:
 147 *      A newly generated record needs to be written to backend storage.
 148 *
 149 *      @record:
 150 *              pointer to record metadata. When @type is PSTORE_TYPE_DMESG,
 151 *              @buf will be pointing to the preallocated @psi.buf, since
 152 *              memory allocation may be broken during an Oops. Regardless,
 153 *              @buf must be proccesed or copied before returning. The
 154 *              backend is also expected to write @id with something that
 155 *              can help identify this record to a future @erase callback.
 156 *              The @time field will be prepopulated with the current time,
 157 *              when available. The @size field will have the size of data
 158 *              in @buf.
 159 *
 160 *      Returns 0 on success, and non-zero on error.
 161 *
 162 * @write_user:
 163 *      Perform a frontend write to a backend record, using a specified
 164 *      buffer that is coming directly from userspace, instead of the
 165 *      @record @buf.
 166 *
 167 *      @record:        pointer to record metadata.
 168 *      @buf:           pointer to userspace contents to write to backend
 169 *
 170 *      Returns 0 on success, and non-zero on error.
 171 *
 172 * @erase:
 173 *      Delete a record from backend storage.  Different backends
 174 *      identify records differently, so entire original record is
 175 *      passed back to assist in identification of what the backend
 176 *      should remove from storage.
 177 *
 178 *      @record:        pointer to record metadata.
 179 *
 180 *      Returns 0 on success, and non-zero on error.
 181 *
 182 */
 183struct pstore_info {
 184        struct module   *owner;
 185        char            *name;
 186
 187        struct semaphore buf_lock;
 188        char            *buf;
 189        size_t          bufsize;
 190
 191        struct mutex    read_mutex;
 192
 193        int             flags;
 194        void            *data;
 195
 196        int             (*open)(struct pstore_info *psi);
 197        int             (*close)(struct pstore_info *psi);
 198        ssize_t         (*read)(struct pstore_record *record);
 199        int             (*write)(struct pstore_record *record);
 200        int             (*write_user)(struct pstore_record *record,
 201                                      const char __user *buf);
 202        int             (*erase)(struct pstore_record *record);
 203};
 204
 205/* Supported frontends */
 206#define PSTORE_FLAGS_DMESG      BIT(0)
 207#define PSTORE_FLAGS_CONSOLE    BIT(1)
 208#define PSTORE_FLAGS_FTRACE     BIT(2)
 209#define PSTORE_FLAGS_PMSG       BIT(3)
 210
 211extern int pstore_register(struct pstore_info *);
 212extern void pstore_unregister(struct pstore_info *);
 213
 214struct pstore_ftrace_record {
 215        unsigned long ip;
 216        unsigned long parent_ip;
 217        u64 ts;
 218};
 219
 220/*
 221 * ftrace related stuff: Both backends and frontends need these so expose
 222 * them here.
 223 */
 224
 225#if NR_CPUS <= 2 && defined(CONFIG_ARM_THUMB)
 226#define PSTORE_CPU_IN_IP 0x1
 227#elif NR_CPUS <= 4 && defined(CONFIG_ARM)
 228#define PSTORE_CPU_IN_IP 0x3
 229#endif
 230
 231#define TS_CPU_SHIFT 8
 232#define TS_CPU_MASK (BIT(TS_CPU_SHIFT) - 1)
 233
 234/*
 235 * If CPU number can be stored in IP, store it there, otherwise store it in
 236 * the time stamp. This means more timestamp resolution is available when
 237 * the CPU can be stored in the IP.
 238 */
 239#ifdef PSTORE_CPU_IN_IP
 240static inline void
 241pstore_ftrace_encode_cpu(struct pstore_ftrace_record *rec, unsigned int cpu)
 242{
 243        rec->ip |= cpu;
 244}
 245
 246static inline unsigned int
 247pstore_ftrace_decode_cpu(struct pstore_ftrace_record *rec)
 248{
 249        return rec->ip & PSTORE_CPU_IN_IP;
 250}
 251
 252static inline u64
 253pstore_ftrace_read_timestamp(struct pstore_ftrace_record *rec)
 254{
 255        return rec->ts;
 256}
 257
 258static inline void
 259pstore_ftrace_write_timestamp(struct pstore_ftrace_record *rec, u64 val)
 260{
 261        rec->ts = val;
 262}
 263#else
 264static inline void
 265pstore_ftrace_encode_cpu(struct pstore_ftrace_record *rec, unsigned int cpu)
 266{
 267        rec->ts &= ~(TS_CPU_MASK);
 268        rec->ts |= cpu;
 269}
 270
 271static inline unsigned int
 272pstore_ftrace_decode_cpu(struct pstore_ftrace_record *rec)
 273{
 274        return rec->ts & TS_CPU_MASK;
 275}
 276
 277static inline u64
 278pstore_ftrace_read_timestamp(struct pstore_ftrace_record *rec)
 279{
 280        return rec->ts >> TS_CPU_SHIFT;
 281}
 282
 283static inline void
 284pstore_ftrace_write_timestamp(struct pstore_ftrace_record *rec, u64 val)
 285{
 286        rec->ts = (rec->ts & TS_CPU_MASK) | (val << TS_CPU_SHIFT);
 287}
 288#endif
 289
 290#endif /*_LINUX_PSTORE_H*/
 291