aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHon Ching \(Vicky\) Lo <honclo@linux.vnet.ibm.com>2015-06-17 18:17:08 -0400
committerPeter Huewe <peterhuewe@gmx.de>2015-10-18 19:09:30 -0400
commit0cc698af36ff22295dce2f5e46b0cfe605789fa4 (patch)
treecec30aa92173479c797cc0349a0536b5849637c8
parent09e23a4a5dc39ef874403f3f6fa419f49db3677a (diff)
vTPM: support little endian guests
This patch makes the code endianness independent. We defined a macro do_endian_conversion to apply endianness to raw integers in the event entries so that they will be displayed properly. tpm_binary_bios_measurements_show() is modified for the display. Signed-off-by: Hon Ching(Vicky) Lo <honclo@linux.vnet.ibm.com> Signed-off-by: Joy Latten <jmlatten@linux.vnet.ibm.com> Reviewed-by: Ashley Lai <ashley@ahsleylai.com> Reviewed-by: Ashley Lai <ashley@ahsleylai.com> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
-rw-r--r--drivers/char/tpm/tpm_eventlog.c78
-rw-r--r--drivers/char/tpm/tpm_eventlog.h6
2 files changed, 62 insertions, 22 deletions
diff --git a/drivers/char/tpm/tpm_eventlog.c b/drivers/char/tpm/tpm_eventlog.c
index 3a56a131586c..bd72fb04225e 100644
--- a/drivers/char/tpm/tpm_eventlog.c
+++ b/drivers/char/tpm/tpm_eventlog.c
@@ -76,15 +76,25 @@ static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos)
76 void *addr = log->bios_event_log; 76 void *addr = log->bios_event_log;
77 void *limit = log->bios_event_log_end; 77 void *limit = log->bios_event_log_end;
78 struct tcpa_event *event; 78 struct tcpa_event *event;
79 u32 converted_event_size;
80 u32 converted_event_type;
81
79 82
80 /* read over *pos measurements */ 83 /* read over *pos measurements */
81 for (i = 0; i < *pos; i++) { 84 for (i = 0; i < *pos; i++) {
82 event = addr; 85 event = addr;
83 86
87 converted_event_size =
88 do_endian_conversion(event->event_size);
89 converted_event_type =
90 do_endian_conversion(event->event_type);
91
84 if ((addr + sizeof(struct tcpa_event)) < limit) { 92 if ((addr + sizeof(struct tcpa_event)) < limit) {
85 if (event->event_type == 0 && event->event_size == 0) 93 if ((converted_event_type == 0) &&
94 (converted_event_size == 0))
86 return NULL; 95 return NULL;
87 addr += sizeof(struct tcpa_event) + event->event_size; 96 addr += (sizeof(struct tcpa_event) +
97 converted_event_size);
88 } 98 }
89 } 99 }
90 100
@@ -94,8 +104,12 @@ static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos)
94 104
95 event = addr; 105 event = addr;
96 106
97 if ((event->event_type == 0 && event->event_size == 0) || 107 converted_event_size = do_endian_conversion(event->event_size);
98 ((addr + sizeof(struct tcpa_event) + event->event_size) >= limit)) 108 converted_event_type = do_endian_conversion(event->event_type);
109
110 if (((converted_event_type == 0) && (converted_event_size == 0))
111 || ((addr + sizeof(struct tcpa_event) + converted_event_size)
112 >= limit))
99 return NULL; 113 return NULL;
100 114
101 return addr; 115 return addr;
@@ -107,8 +121,12 @@ static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
107 struct tcpa_event *event = v; 121 struct tcpa_event *event = v;
108 struct tpm_bios_log *log = m->private; 122 struct tpm_bios_log *log = m->private;
109 void *limit = log->bios_event_log_end; 123 void *limit = log->bios_event_log_end;
124 u32 converted_event_size;
125 u32 converted_event_type;
110 126
111 v += sizeof(struct tcpa_event) + event->event_size; 127 converted_event_size = do_endian_conversion(event->event_size);
128
129 v += sizeof(struct tcpa_event) + converted_event_size;
112 130
113 /* now check if current entry is valid */ 131 /* now check if current entry is valid */
114 if ((v + sizeof(struct tcpa_event)) >= limit) 132 if ((v + sizeof(struct tcpa_event)) >= limit)
@@ -116,11 +134,11 @@ static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
116 134
117 event = v; 135 event = v;
118 136
119 if (event->event_type == 0 && event->event_size == 0) 137 converted_event_size = do_endian_conversion(event->event_size);
120 return NULL; 138 converted_event_type = do_endian_conversion(event->event_type);
121 139
122 if ((event->event_type == 0 && event->event_size == 0) || 140 if (((converted_event_type == 0) && (converted_event_size == 0)) ||
123 ((v + sizeof(struct tcpa_event) + event->event_size) >= limit)) 141 ((v + sizeof(struct tcpa_event) + converted_event_size) >= limit))
124 return NULL; 142 return NULL;
125 143
126 (*pos)++; 144 (*pos)++;
@@ -140,7 +158,7 @@ static int get_event_name(char *dest, struct tcpa_event *event,
140 int i, n_len = 0, d_len = 0; 158 int i, n_len = 0, d_len = 0;
141 struct tcpa_pc_event *pc_event; 159 struct tcpa_pc_event *pc_event;
142 160
143 switch(event->event_type) { 161 switch (do_endian_conversion(event->event_type)) {
144 case PREBOOT: 162 case PREBOOT:
145 case POST_CODE: 163 case POST_CODE:
146 case UNUSED: 164 case UNUSED:
@@ -156,14 +174,16 @@ static int get_event_name(char *dest, struct tcpa_event *event,
156 case NONHOST_CODE: 174 case NONHOST_CODE:
157 case NONHOST_CONFIG: 175 case NONHOST_CONFIG:
158 case NONHOST_INFO: 176 case NONHOST_INFO:
159 name = tcpa_event_type_strings[event->event_type]; 177 name = tcpa_event_type_strings[do_endian_conversion
178 (event->event_type)];
160 n_len = strlen(name); 179 n_len = strlen(name);
161 break; 180 break;
162 case SEPARATOR: 181 case SEPARATOR:
163 case ACTION: 182 case ACTION:
164 if (MAX_TEXT_EVENT > event->event_size) { 183 if (MAX_TEXT_EVENT >
184 do_endian_conversion(event->event_size)) {
165 name = event_entry; 185 name = event_entry;
166 n_len = event->event_size; 186 n_len = do_endian_conversion(event->event_size);
167 } 187 }
168 break; 188 break;
169 case EVENT_TAG: 189 case EVENT_TAG:
@@ -171,7 +191,7 @@ static int get_event_name(char *dest, struct tcpa_event *event,
171 191
172 /* ToDo Row data -> Base64 */ 192 /* ToDo Row data -> Base64 */
173 193
174 switch (pc_event->event_id) { 194 switch (do_endian_conversion(pc_event->event_id)) {
175 case SMBIOS: 195 case SMBIOS:
176 case BIS_CERT: 196 case BIS_CERT:
177 case CMOS: 197 case CMOS:
@@ -179,7 +199,8 @@ static int get_event_name(char *dest, struct tcpa_event *event,
179 case OPTION_ROM_EXEC: 199 case OPTION_ROM_EXEC:
180 case OPTION_ROM_CONFIG: 200 case OPTION_ROM_CONFIG:
181 case S_CRTM_VERSION: 201 case S_CRTM_VERSION:
182 name = tcpa_pc_event_id_strings[pc_event->event_id]; 202 name = tcpa_pc_event_id_strings[do_endian_conversion
203 (pc_event->event_id)];
183 n_len = strlen(name); 204 n_len = strlen(name);
184 break; 205 break;
185 /* hash data */ 206 /* hash data */
@@ -188,7 +209,8 @@ static int get_event_name(char *dest, struct tcpa_event *event,
188 case OPTION_ROM_MICROCODE: 209 case OPTION_ROM_MICROCODE:
189 case S_CRTM_CONTENTS: 210 case S_CRTM_CONTENTS:
190 case POST_CONTENTS: 211 case POST_CONTENTS:
191 name = tcpa_pc_event_id_strings[pc_event->event_id]; 212 name = tcpa_pc_event_id_strings[do_endian_conversion
213 (pc_event->event_id)];
192 n_len = strlen(name); 214 n_len = strlen(name);
193 for (i = 0; i < 20; i++) 215 for (i = 0; i < 20; i++)
194 d_len += sprintf(&data[2*i], "%02x", 216 d_len += sprintf(&data[2*i], "%02x",
@@ -209,13 +231,24 @@ static int get_event_name(char *dest, struct tcpa_event *event,
209static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v) 231static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
210{ 232{
211 struct tcpa_event *event = v; 233 struct tcpa_event *event = v;
212 char *data = v; 234 struct tcpa_event temp_event;
235 char *tempPtr;
213 int i; 236 int i;
214 237
215 for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++) 238 memcpy(&temp_event, event, sizeof(struct tcpa_event));
216 seq_putc(m, data[i]); 239
240 /* convert raw integers for endianness */
241 temp_event.pcr_index = do_endian_conversion(event->pcr_index);
242 temp_event.event_type = do_endian_conversion(event->event_type);
243 temp_event.event_size = do_endian_conversion(event->event_size);
244
245 tempPtr = (char *)&temp_event;
246
247 for (i = 0; i < sizeof(struct tcpa_event) + temp_event.event_size; i++)
248 seq_putc(m, tempPtr[i]);
217 249
218 return 0; 250 return 0;
251
219} 252}
220 253
221static int tpm_bios_measurements_release(struct inode *inode, 254static int tpm_bios_measurements_release(struct inode *inode,
@@ -238,7 +271,7 @@ static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
238 char *eventname; 271 char *eventname;
239 struct tcpa_event *event = v; 272 struct tcpa_event *event = v;
240 unsigned char *event_entry = 273 unsigned char *event_entry =
241 (unsigned char *) (v + sizeof(struct tcpa_event)); 274 (unsigned char *)(v + sizeof(struct tcpa_event));
242 275
243 eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL); 276 eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
244 if (!eventname) { 277 if (!eventname) {
@@ -247,13 +280,14 @@ static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
247 return -EFAULT; 280 return -EFAULT;
248 } 281 }
249 282
250 seq_printf(m, "%2d ", event->pcr_index); 283 /* 1st: PCR */
284 seq_printf(m, "%2d ", do_endian_conversion(event->pcr_index));
251 285
252 /* 2nd: SHA1 */ 286 /* 2nd: SHA1 */
253 seq_printf(m, "%20phN", event->pcr_value); 287 seq_printf(m, "%20phN", event->pcr_value);
254 288
255 /* 3rd: event type identifier */ 289 /* 3rd: event type identifier */
256 seq_printf(m, " %02x", event->event_type); 290 seq_printf(m, " %02x", do_endian_conversion(event->event_type));
257 291
258 len += get_event_name(eventname, event, event_entry); 292 len += get_event_name(eventname, event, event_entry);
259 293
diff --git a/drivers/char/tpm/tpm_eventlog.h b/drivers/char/tpm/tpm_eventlog.h
index e7da086d6928..267bfbd1b7bb 100644
--- a/drivers/char/tpm/tpm_eventlog.h
+++ b/drivers/char/tpm/tpm_eventlog.h
@@ -6,6 +6,12 @@
6#define MAX_TEXT_EVENT 1000 /* Max event string length */ 6#define MAX_TEXT_EVENT 1000 /* Max event string length */
7#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ 7#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */
8 8
9#ifdef CONFIG_PPC64
10#define do_endian_conversion(x) be32_to_cpu(x)
11#else
12#define do_endian_conversion(x) x
13#endif
14
9enum bios_platform_class { 15enum bios_platform_class {
10 BIOS_CLIENT = 0x00, 16 BIOS_CLIENT = 0x00,
11 BIOS_SERVER = 0x01, 17 BIOS_SERVER = 0x01,