Commit 8b006db6 authored by Kylene Jo Hall's avatar Kylene Jo Hall Committed by Linus Torvalds

[PATCH] tpm: update bios log code for 1.2

The acpi table which contains the BIOS log events was updated for 1.2.
There are now client and server modes as defined in the specifications with
slightly different formats.  Additionally, the start field was even too
small for the 1.1 version but had been working anyway.  This patch updates
the code to deal with any of the three types of headers probperly (1.1, 1.2
client and 1.2 server).
Signed-off-by: default avatarKylie Hall <kjhall@us.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b09d5300
...@@ -29,6 +29,11 @@ ...@@ -29,6 +29,11 @@
#define MAX_TEXT_EVENT 1000 /* Max event string length */ #define MAX_TEXT_EVENT 1000 /* Max event string length */
#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */
enum bios_platform_class {
BIOS_CLIENT = 0x00,
BIOS_SERVER = 0x01,
};
struct tpm_bios_log { struct tpm_bios_log {
void *bios_event_log; void *bios_event_log;
void *bios_event_log_end; void *bios_event_log_end;
...@@ -36,9 +41,18 @@ struct tpm_bios_log { ...@@ -36,9 +41,18 @@ struct tpm_bios_log {
struct acpi_tcpa { struct acpi_tcpa {
struct acpi_table_header hdr; struct acpi_table_header hdr;
u16 reserved; u16 platform_class;
union {
struct client_hdr {
u32 log_max_len __attribute__ ((packed)); u32 log_max_len __attribute__ ((packed));
u32 log_start_addr __attribute__ ((packed)); u64 log_start_addr __attribute__ ((packed));
} client;
struct server_hdr {
u16 reserved;
u64 log_max_len __attribute__ ((packed));
u64 log_start_addr __attribute__ ((packed));
} server;
};
}; };
struct tcpa_event { struct tcpa_event {
...@@ -379,6 +393,7 @@ static int read_log(struct tpm_bios_log *log) ...@@ -379,6 +393,7 @@ static int read_log(struct tpm_bios_log *log)
struct acpi_tcpa *buff; struct acpi_tcpa *buff;
acpi_status status; acpi_status status;
struct acpi_table_header *virt; struct acpi_table_header *virt;
u64 len, start;
if (log->bios_event_log != NULL) { if (log->bios_event_log != NULL) {
printk(KERN_ERR printk(KERN_ERR
...@@ -399,27 +414,37 @@ static int read_log(struct tpm_bios_log *log) ...@@ -399,27 +414,37 @@ static int read_log(struct tpm_bios_log *log)
return -EIO; return -EIO;
} }
if (buff->log_max_len == 0) { switch(buff->platform_class) {
case BIOS_SERVER:
len = buff->server.log_max_len;
start = buff->server.log_start_addr;
break;
case BIOS_CLIENT:
default:
len = buff->client.log_max_len;
start = buff->client.log_start_addr;
break;
}
if (!len) {
printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__); printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
return -EIO; return -EIO;
} }
/* malloc EventLog space */ /* malloc EventLog space */
log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL); log->bios_event_log = kmalloc(len, GFP_KERNEL);
if (!log->bios_event_log) { if (!log->bios_event_log) {
printk printk("%s: ERROR - Not enough Memory for BIOS measurements\n",
("%s: ERROR - Not enough Memory for BIOS measurements\n",
__func__); __func__);
return -ENOMEM; return -ENOMEM;
} }
log->bios_event_log_end = log->bios_event_log + buff->log_max_len; log->bios_event_log_end = log->bios_event_log + len;
acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt); acpi_os_map_memory(start, len, (void *) &virt);
memcpy(log->bios_event_log, virt, buff->log_max_len); memcpy(log->bios_event_log, virt, len);
acpi_os_unmap_memory(virt, buff->log_max_len); acpi_os_unmap_memory(virt, len);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment