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(HPWMI_SURESTART_GET_LOG_COUNT, 37 HPWMI_SURESTART, 38 &count, 1, sizeof(count)); 39 40 if (ret < 0) 41 return ret; 42 43 return sysfs_emit(buf, "%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(HPWMI_SURESTART_GET_LOG_COUNT, 60 HPWMI_SURESTART, 61 &count, 1, 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(HPWMI_SURESTART_GET_LOG, 90 HPWMI_SURESTART, 91 audit_log_buffer, 1, 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(bioscfg_drv.sure_start_attr_kobj, 125 &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(attr_name_kobj, &sure_start_attr_group); 132 } 133