aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/tpm/tpm_bios.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
index 5bcbaef53798..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
32enum bios_platform_class {
33 BIOS_CLIENT = 0x00,
34 BIOS_SERVER = 0x01,
35};
36
32struct tpm_bios_log { 37struct 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
37struct acpi_tcpa { 42struct 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
44struct tcpa_event { 58struct tcpa_event {
@@ -379,6 +393,7 @@ static int read_log(struct tpm_bios_log *log)
379 struct acpi_tcpa *buff; 393 struct acpi_tcpa *buff;
380 acpi_status status; 394 acpi_status status;
381 struct acpi_table_header *virt; 395 struct acpi_table_header *virt;
396 u64 len, start;
382 397
383 if (log->bios_event_log != NULL) { 398 if (log->bios_event_log != NULL) {
384 printk(KERN_ERR 399 printk(KERN_ERR
@@ -399,27 +414,37 @@ static int read_log(struct tpm_bios_log *log)
399 return -EIO; 414 return -EIO;
400 } 415 }
401 416
402 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) {
403 printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__); 429 printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
404 return -EIO; 430 return -EIO;
405 } 431 }
406 432
407 /* malloc EventLog space */ 433 /* malloc EventLog space */
408 log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL); 434 log->bios_event_log = kmalloc(len, GFP_KERNEL);
409 if (!log->bios_event_log) { 435 if (!log->bios_event_log) {
410 printk 436 printk("%s: ERROR - Not enough Memory for BIOS measurements\n",
411 ("%s: ERROR - Not enough Memory for BIOS measurements\n", 437 __func__);
412 __func__);
413 return -ENOMEM; 438 return -ENOMEM;
414 } 439 }
415 440
416 log->bios_event_log_end = log->bios_event_log + buff->log_max_len; 441 log->bios_event_log_end = log->bios_event_log + len;
417 442
418 acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt); 443 acpi_os_map_memory(start, len, (void *) &virt);
419 444
420 memcpy(log->bios_event_log, virt, buff->log_max_len); 445 memcpy(log->bios_event_log, virt, len);
421 446
422 acpi_os_unmap_memory(virt, buff->log_max_len); 447 acpi_os_unmap_memory(virt, len);
423 return 0; 448 return 0;
424} 449}
425 450