diff options
Diffstat (limited to 'drivers/char/tpm/tpm_bios.c')
-rw-r--r-- | drivers/char/tpm/tpm_bios.c | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 537aa45d8c67..e45f0d3d12de 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c | |||
@@ -29,6 +29,11 @@ | |||
29 | #define MAX_TEXT_EVENT 1000 /* Max event string length */ | 29 | #define MAX_TEXT_EVENT 1000 /* Max event string length */ |
30 | #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ | 30 | #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ |
31 | 31 | ||
32 | enum bios_platform_class { | ||
33 | BIOS_CLIENT = 0x00, | ||
34 | BIOS_SERVER = 0x01, | ||
35 | }; | ||
36 | |||
32 | struct tpm_bios_log { | 37 | struct tpm_bios_log { |
33 | void *bios_event_log; | 38 | void *bios_event_log; |
34 | void *bios_event_log_end; | 39 | void *bios_event_log_end; |
@@ -36,9 +41,18 @@ struct tpm_bios_log { | |||
36 | 41 | ||
37 | struct acpi_tcpa { | 42 | struct acpi_tcpa { |
38 | struct acpi_table_header hdr; | 43 | struct acpi_table_header hdr; |
39 | u16 reserved; | 44 | u16 platform_class; |
40 | u32 log_max_len __attribute__ ((packed)); | 45 | union { |
41 | u32 log_start_addr __attribute__ ((packed)); | 46 | struct client_hdr { |
47 | u32 log_max_len __attribute__ ((packed)); | ||
48 | u64 log_start_addr __attribute__ ((packed)); | ||
49 | } client; | ||
50 | struct server_hdr { | ||
51 | u16 reserved; | ||
52 | u64 log_max_len __attribute__ ((packed)); | ||
53 | u64 log_start_addr __attribute__ ((packed)); | ||
54 | } server; | ||
55 | }; | ||
42 | }; | 56 | }; |
43 | 57 | ||
44 | struct tcpa_event { | 58 | struct tcpa_event { |
@@ -120,6 +134,7 @@ static const char* tcpa_pc_event_id_strings[] = { | |||
120 | "S-CRTM Version", | 134 | "S-CRTM Version", |
121 | "S-CRTM Contents", | 135 | "S-CRTM Contents", |
122 | "S-CRTM POST Contents", | 136 | "S-CRTM POST Contents", |
137 | "POST Contents", | ||
123 | }; | 138 | }; |
124 | 139 | ||
125 | /* returns pointer to start of pos. entry of tcg log */ | 140 | /* returns pointer to start of pos. entry of tcg log */ |
@@ -306,6 +321,7 @@ static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v) | |||
306 | /* 5th: delimiter */ | 321 | /* 5th: delimiter */ |
307 | seq_putc(m, '\0'); | 322 | seq_putc(m, '\0'); |
308 | 323 | ||
324 | kfree(eventname); | ||
309 | return 0; | 325 | return 0; |
310 | } | 326 | } |
311 | 327 | ||
@@ -353,6 +369,7 @@ static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v) | |||
353 | /* 4th: eventname <= max + \'0' delimiter */ | 369 | /* 4th: eventname <= max + \'0' delimiter */ |
354 | seq_printf(m, " %s\n", eventname); | 370 | seq_printf(m, " %s\n", eventname); |
355 | 371 | ||
372 | kfree(eventname); | ||
356 | return 0; | 373 | return 0; |
357 | } | 374 | } |
358 | 375 | ||
@@ -376,6 +393,7 @@ static int read_log(struct tpm_bios_log *log) | |||
376 | struct acpi_tcpa *buff; | 393 | struct acpi_tcpa *buff; |
377 | acpi_status status; | 394 | acpi_status status; |
378 | struct acpi_table_header *virt; | 395 | struct acpi_table_header *virt; |
396 | u64 len, start; | ||
379 | 397 | ||
380 | if (log->bios_event_log != NULL) { | 398 | if (log->bios_event_log != NULL) { |
381 | printk(KERN_ERR | 399 | printk(KERN_ERR |
@@ -396,27 +414,37 @@ static int read_log(struct tpm_bios_log *log) | |||
396 | return -EIO; | 414 | return -EIO; |
397 | } | 415 | } |
398 | 416 | ||
399 | if (buff->log_max_len == 0) { | 417 | switch(buff->platform_class) { |
418 | case BIOS_SERVER: | ||
419 | len = buff->server.log_max_len; | ||
420 | start = buff->server.log_start_addr; | ||
421 | break; | ||
422 | case BIOS_CLIENT: | ||
423 | default: | ||
424 | len = buff->client.log_max_len; | ||
425 | start = buff->client.log_start_addr; | ||
426 | break; | ||
427 | } | ||
428 | if (!len) { | ||
400 | printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__); | 429 | printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__); |
401 | return -EIO; | 430 | return -EIO; |
402 | } | 431 | } |
403 | 432 | ||
404 | /* malloc EventLog space */ | 433 | /* malloc EventLog space */ |
405 | log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL); | 434 | log->bios_event_log = kmalloc(len, GFP_KERNEL); |
406 | if (!log->bios_event_log) { | 435 | if (!log->bios_event_log) { |
407 | printk | 436 | printk("%s: ERROR - Not enough Memory for BIOS measurements\n", |
408 | ("%s: ERROR - Not enough Memory for BIOS measurements\n", | 437 | __func__); |
409 | __func__); | ||
410 | return -ENOMEM; | 438 | return -ENOMEM; |
411 | } | 439 | } |
412 | 440 | ||
413 | log->bios_event_log_end = log->bios_event_log + buff->log_max_len; | 441 | log->bios_event_log_end = log->bios_event_log + len; |
414 | 442 | ||
415 | acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt); | 443 | acpi_os_map_memory(start, len, (void *) &virt); |
416 | 444 | ||
417 | memcpy(log->bios_event_log, virt, buff->log_max_len); | 445 | memcpy(log->bios_event_log, virt, len); |
418 | 446 | ||
419 | acpi_os_unmap_memory(virt, buff->log_max_len); | 447 | acpi_os_unmap_memory(virt, len); |
420 | return 0; | 448 | return 0; |
421 | } | 449 | } |
422 | 450 | ||