1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Functions corresponding to sure start object type attributes under |
4 | * BIOS for use with hp-bioscfg driver |
5 | * |
6 | * Copyright (c) 2022 HP Development Company, L.P. |
7 | */ |
8 | |
9 | #include "bioscfg.h" |
10 | #include <linux/types.h> |
11 | |
12 | /* Maximum number of log entries supported when log entry size is 16 |
13 | * bytes. This value is calculated by dividing 4096 (page size) by |
14 | * log entry size. |
15 | */ |
16 | #define LOG_MAX_ENTRIES 254 |
17 | |
18 | /* |
19 | * Current Log entry size. This value size will change in the |
20 | * future. The driver reads a total of 128 bytes for each log entry |
21 | * provided by BIOS but only the first 16 bytes are used/read. |
22 | */ |
23 | #define LOG_ENTRY_SIZE 16 |
24 | |
25 | /* |
26 | * audit_log_entry_count_show - Reports the number of |
27 | * existing audit log entries available |
28 | * to be read |
29 | */ |
30 | static ssize_t audit_log_entry_count_show(struct kobject *kobj, |
31 | struct kobj_attribute *attr, char *buf) |
32 | { |
33 | int ret; |
34 | u32 count = 0; |
35 | |
36 | ret = hp_wmi_perform_query(query: HPWMI_SURESTART_GET_LOG_COUNT, |
37 | command: HPWMI_SURESTART, |
38 | buffer: &count, insize: 1, outsize: sizeof(count)); |
39 | |
40 | if (ret < 0) |
41 | return ret; |
42 | |
43 | return sysfs_emit(buf, fmt: "%d,%d,%d\n" , count, LOG_ENTRY_SIZE, |
44 | LOG_MAX_ENTRIES); |
45 | } |
46 | |
47 | /* |
48 | * audit_log_entries_show() - Return all entries found in log file |
49 | */ |
50 | static ssize_t audit_log_entries_show(struct kobject *kobj, |
51 | struct kobj_attribute *attr, char *buf) |
52 | { |
53 | int ret; |
54 | int i; |
55 | u32 count = 0; |
56 | u8 audit_log_buffer[128]; |
57 | |
58 | // Get the number of event logs |
59 | ret = hp_wmi_perform_query(query: HPWMI_SURESTART_GET_LOG_COUNT, |
60 | command: HPWMI_SURESTART, |
61 | buffer: &count, insize: 1, outsize: sizeof(count)); |
62 | |
63 | if (ret < 0) |
64 | return ret; |
65 | |
66 | /* |
67 | * The show() api will not work if the audit logs ever go |
68 | * beyond 4KB |
69 | */ |
70 | if (count * LOG_ENTRY_SIZE > PAGE_SIZE) |
71 | return -EIO; |
72 | |
73 | /* |
74 | * We are guaranteed the buffer is 4KB so today all the event |
75 | * logs will fit |
76 | */ |
77 | for (i = 0; i < count; i++) { |
78 | audit_log_buffer[0] = i + 1; |
79 | |
80 | /* |
81 | * read audit log entry at a time. 'buf' input value |
82 | * provides the audit log entry to be read. On |
83 | * input, Byte 0 = Audit Log entry number from |
84 | * beginning (1..254) |
85 | * Entry number 1 is the newest entry whereas the |
86 | * highest entry number (number of entries) is the |
87 | * oldest entry. |
88 | */ |
89 | ret = hp_wmi_perform_query(query: HPWMI_SURESTART_GET_LOG, |
90 | command: HPWMI_SURESTART, |
91 | buffer: audit_log_buffer, insize: 1, outsize: 128); |
92 | |
93 | if (ret < 0 || (LOG_ENTRY_SIZE * i) > PAGE_SIZE) { |
94 | /* |
95 | * Encountered a failure while reading |
96 | * individual logs. Only a partial list of |
97 | * audit log will be returned. |
98 | */ |
99 | break; |
100 | } else { |
101 | memcpy(buf, audit_log_buffer, LOG_ENTRY_SIZE); |
102 | buf += LOG_ENTRY_SIZE; |
103 | } |
104 | } |
105 | |
106 | return i * LOG_ENTRY_SIZE; |
107 | } |
108 | |
109 | static struct kobj_attribute sure_start_audit_log_entry_count = __ATTR_RO(audit_log_entry_count); |
110 | static struct kobj_attribute sure_start_audit_log_entries = __ATTR_RO(audit_log_entries); |
111 | |
112 | static struct attribute *sure_start_attrs[] = { |
113 | &sure_start_audit_log_entry_count.attr, |
114 | &sure_start_audit_log_entries.attr, |
115 | NULL |
116 | }; |
117 | |
118 | static const struct attribute_group sure_start_attr_group = { |
119 | .attrs = sure_start_attrs, |
120 | }; |
121 | |
122 | void hp_exit_sure_start_attributes(void) |
123 | { |
124 | sysfs_remove_group(kobj: bioscfg_drv.sure_start_attr_kobj, |
125 | grp: &sure_start_attr_group); |
126 | } |
127 | |
128 | int hp_populate_sure_start_data(struct kobject *attr_name_kobj) |
129 | { |
130 | bioscfg_drv.sure_start_attr_kobj = attr_name_kobj; |
131 | return sysfs_create_group(kobj: attr_name_kobj, grp: &sure_start_attr_group); |
132 | } |
133 | |