diff options
-rw-r--r-- | arch/ia64/kernel/vmlinux.lds.S | 1 | ||||
-rw-r--r-- | arch/ia64/oprofile/backtrace.c | 2 | ||||
-rw-r--r-- | drivers/acpi/apei/Kconfig | 1 | ||||
-rw-r--r-- | drivers/acpi/apei/erst.c | 61 | ||||
-rw-r--r-- | fs/pstore/platform.c | 12 | ||||
-rw-r--r-- | include/linux/pstore.h | 4 |
6 files changed, 60 insertions, 21 deletions
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index 787de4a77d82..53c0ba004e9e 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S | |||
@@ -209,6 +209,7 @@ SECTIONS { | |||
209 | data : { | 209 | data : { |
210 | } :data | 210 | } :data |
211 | .data : AT(ADDR(.data) - LOAD_OFFSET) { | 211 | .data : AT(ADDR(.data) - LOAD_OFFSET) { |
212 | _sdata = .; | ||
212 | INIT_TASK_DATA(PAGE_SIZE) | 213 | INIT_TASK_DATA(PAGE_SIZE) |
213 | CACHELINE_ALIGNED_DATA(SMP_CACHE_BYTES) | 214 | CACHELINE_ALIGNED_DATA(SMP_CACHE_BYTES) |
214 | READ_MOSTLY_DATA(SMP_CACHE_BYTES) | 215 | READ_MOSTLY_DATA(SMP_CACHE_BYTES) |
diff --git a/arch/ia64/oprofile/backtrace.c b/arch/ia64/oprofile/backtrace.c index 5cdd7e4a597c..f7b798993cea 100644 --- a/arch/ia64/oprofile/backtrace.c +++ b/arch/ia64/oprofile/backtrace.c | |||
@@ -29,7 +29,7 @@ typedef struct | |||
29 | unsigned int depth; | 29 | unsigned int depth; |
30 | struct pt_regs *regs; | 30 | struct pt_regs *regs; |
31 | struct unw_frame_info frame; | 31 | struct unw_frame_info frame; |
32 | u64 *prev_pfs_loc; /* state for WAR for old spinlock ool code */ | 32 | unsigned long *prev_pfs_loc; /* state for WAR for old spinlock ool code */ |
33 | } ia64_backtrace_t; | 33 | } ia64_backtrace_t; |
34 | 34 | ||
35 | /* Returns non-zero if the PC is in the Interrupt Vector Table */ | 35 | /* Returns non-zero if the PC is in the Interrupt Vector Table */ |
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index 66a03caa2ad9..f739a70b1c70 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config ACPI_APEI | 1 | config ACPI_APEI |
2 | bool "ACPI Platform Error Interface (APEI)" | 2 | bool "ACPI Platform Error Interface (APEI)" |
3 | select MISC_FILESYSTEMS | ||
3 | select PSTORE | 4 | select PSTORE |
4 | depends on X86 | 5 | depends on X86 |
5 | help | 6 | help |
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index d6cb0ff6988e..e6cef8e1b534 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -929,13 +929,17 @@ static int erst_check_table(struct acpi_table_erst *erst_tab) | |||
929 | return 0; | 929 | return 0; |
930 | } | 930 | } |
931 | 931 | ||
932 | static size_t erst_reader(u64 *id, enum pstore_type_id *type, | 932 | static int erst_open_pstore(struct pstore_info *psi); |
933 | static int erst_close_pstore(struct pstore_info *psi); | ||
934 | static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, | ||
933 | struct timespec *time); | 935 | struct timespec *time); |
934 | static u64 erst_writer(enum pstore_type_id type, size_t size); | 936 | static u64 erst_writer(enum pstore_type_id type, size_t size); |
935 | 937 | ||
936 | static struct pstore_info erst_info = { | 938 | static struct pstore_info erst_info = { |
937 | .owner = THIS_MODULE, | 939 | .owner = THIS_MODULE, |
938 | .name = "erst", | 940 | .name = "erst", |
941 | .open = erst_open_pstore, | ||
942 | .close = erst_close_pstore, | ||
939 | .read = erst_reader, | 943 | .read = erst_reader, |
940 | .write = erst_writer, | 944 | .write = erst_writer, |
941 | .erase = erst_clear | 945 | .erase = erst_clear |
@@ -957,12 +961,32 @@ struct cper_pstore_record { | |||
957 | char data[]; | 961 | char data[]; |
958 | } __packed; | 962 | } __packed; |
959 | 963 | ||
960 | static size_t erst_reader(u64 *id, enum pstore_type_id *type, | 964 | static int reader_pos; |
965 | |||
966 | static int erst_open_pstore(struct pstore_info *psi) | ||
967 | { | ||
968 | int rc; | ||
969 | |||
970 | if (erst_disable) | ||
971 | return -ENODEV; | ||
972 | |||
973 | rc = erst_get_record_id_begin(&reader_pos); | ||
974 | |||
975 | return rc; | ||
976 | } | ||
977 | |||
978 | static int erst_close_pstore(struct pstore_info *psi) | ||
979 | { | ||
980 | erst_get_record_id_end(); | ||
981 | |||
982 | return 0; | ||
983 | } | ||
984 | |||
985 | static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, | ||
961 | struct timespec *time) | 986 | struct timespec *time) |
962 | { | 987 | { |
963 | int rc; | 988 | int rc; |
964 | ssize_t len; | 989 | ssize_t len = 0; |
965 | unsigned long flags; | ||
966 | u64 record_id; | 990 | u64 record_id; |
967 | struct cper_pstore_record *rcd = (struct cper_pstore_record *) | 991 | struct cper_pstore_record *rcd = (struct cper_pstore_record *) |
968 | (erst_info.buf - sizeof(*rcd)); | 992 | (erst_info.buf - sizeof(*rcd)); |
@@ -970,24 +994,28 @@ static size_t erst_reader(u64 *id, enum pstore_type_id *type, | |||
970 | if (erst_disable) | 994 | if (erst_disable) |
971 | return -ENODEV; | 995 | return -ENODEV; |
972 | 996 | ||
973 | raw_spin_lock_irqsave(&erst_lock, flags); | ||
974 | skip: | 997 | skip: |
975 | rc = __erst_get_next_record_id(&record_id); | 998 | rc = erst_get_record_id_next(&reader_pos, &record_id); |
976 | if (rc) { | 999 | if (rc) |
977 | raw_spin_unlock_irqrestore(&erst_lock, flags); | 1000 | goto out; |
978 | return rc; | 1001 | |
979 | } | ||
980 | /* no more record */ | 1002 | /* no more record */ |
981 | if (record_id == APEI_ERST_INVALID_RECORD_ID) { | 1003 | if (record_id == APEI_ERST_INVALID_RECORD_ID) { |
982 | raw_spin_unlock_irqrestore(&erst_lock, flags); | 1004 | rc = -1; |
983 | return 0; | 1005 | goto out; |
984 | } | 1006 | } |
985 | 1007 | ||
986 | len = __erst_read(record_id, &rcd->hdr, sizeof(*rcd) + | 1008 | len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) + |
987 | erst_erange.size); | 1009 | erst_info.bufsize); |
1010 | /* The record may be cleared by others, try read next record */ | ||
1011 | if (len == -ENOENT) | ||
1012 | goto skip; | ||
1013 | else if (len < 0) { | ||
1014 | rc = -1; | ||
1015 | goto out; | ||
1016 | } | ||
988 | if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) | 1017 | if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) |
989 | goto skip; | 1018 | goto skip; |
990 | raw_spin_unlock_irqrestore(&erst_lock, flags); | ||
991 | 1019 | ||
992 | *id = record_id; | 1020 | *id = record_id; |
993 | if (uuid_le_cmp(rcd->sec_hdr.section_type, | 1021 | if (uuid_le_cmp(rcd->sec_hdr.section_type, |
@@ -1005,7 +1033,8 @@ skip: | |||
1005 | time->tv_sec = 0; | 1033 | time->tv_sec = 0; |
1006 | time->tv_nsec = 0; | 1034 | time->tv_nsec = 0; |
1007 | 1035 | ||
1008 | return len - sizeof(*rcd); | 1036 | out: |
1037 | return (rc < 0) ? rc : (len - sizeof(*rcd)); | ||
1009 | } | 1038 | } |
1010 | 1039 | ||
1011 | static u64 erst_writer(enum pstore_type_id type, size_t size) | 1040 | static u64 erst_writer(enum pstore_type_id type, size_t size) |
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index f835a25625ff..f2c3ff20ea68 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c | |||
@@ -152,21 +152,27 @@ EXPORT_SYMBOL_GPL(pstore_register); | |||
152 | void pstore_get_records(void) | 152 | void pstore_get_records(void) |
153 | { | 153 | { |
154 | struct pstore_info *psi = psinfo; | 154 | struct pstore_info *psi = psinfo; |
155 | size_t size; | 155 | ssize_t size; |
156 | u64 id; | 156 | u64 id; |
157 | enum pstore_type_id type; | 157 | enum pstore_type_id type; |
158 | struct timespec time; | 158 | struct timespec time; |
159 | int failed = 0; | 159 | int failed = 0, rc; |
160 | 160 | ||
161 | if (!psi) | 161 | if (!psi) |
162 | return; | 162 | return; |
163 | 163 | ||
164 | mutex_lock(&psinfo->buf_mutex); | 164 | mutex_lock(&psinfo->buf_mutex); |
165 | rc = psi->open(psi); | ||
166 | if (rc) | ||
167 | goto out; | ||
168 | |||
165 | while ((size = psi->read(&id, &type, &time)) > 0) { | 169 | while ((size = psi->read(&id, &type, &time)) > 0) { |
166 | if (pstore_mkfile(type, psi->name, id, psi->buf, size, | 170 | if (pstore_mkfile(type, psi->name, id, psi->buf, (size_t)size, |
167 | time, psi->erase)) | 171 | time, psi->erase)) |
168 | failed++; | 172 | failed++; |
169 | } | 173 | } |
174 | psi->close(psi); | ||
175 | out: | ||
170 | mutex_unlock(&psinfo->buf_mutex); | 176 | mutex_unlock(&psinfo->buf_mutex); |
171 | 177 | ||
172 | if (failed) | 178 | if (failed) |
diff --git a/include/linux/pstore.h b/include/linux/pstore.h index 41977737bb7d..2455ef2683f0 100644 --- a/include/linux/pstore.h +++ b/include/linux/pstore.h | |||
@@ -35,7 +35,9 @@ struct pstore_info { | |||
35 | struct mutex buf_mutex; /* serialize access to 'buf' */ | 35 | struct mutex buf_mutex; /* serialize access to 'buf' */ |
36 | char *buf; | 36 | char *buf; |
37 | size_t bufsize; | 37 | size_t bufsize; |
38 | size_t (*read)(u64 *id, enum pstore_type_id *type, | 38 | int (*open)(struct pstore_info *psi); |
39 | int (*close)(struct pstore_info *psi); | ||
40 | ssize_t (*read)(u64 *id, enum pstore_type_id *type, | ||
39 | struct timespec *time); | 41 | struct timespec *time); |
40 | u64 (*write)(enum pstore_type_id type, size_t size); | 42 | u64 (*write)(enum pstore_type_id type, size_t size); |
41 | int (*erase)(u64 id); | 43 | int (*erase)(u64 id); |