aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm/tpm_bios.c
diff options
context:
space:
mode:
authorKylene Jo Hall <kjhall@us.ibm.com>2006-01-08 04:03:48 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-08 23:14:00 -0500
commitd09cf7d77f62f6fb2f6d63fe5980583805f2d559 (patch)
tree59192c9b47c424bdbc67606f6c2fc2214e7a37d2 /drivers/char/tpm/tpm_bios.c
parent5e38291d80086f6972f471c7caffa03184de0bf0 (diff)
[PATCH] tpmdd: remove global event log
Remove global event log in the tpm bios event measurement log code that would have caused problems when the code was run concurrently. A log is now allocated and attached to the seq file upon open and destroyed appropriately. Signed-off-by: Kylene Jo Hall <kjhall@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char/tpm/tpm_bios.c')
-rw-r--r--drivers/char/tpm/tpm_bios.c92
1 files changed, 62 insertions, 30 deletions
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
index 5e1f4dfefa17..aedf7a8e6da7 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
32struct tpm_bios_log {
33 void *bios_event_log;
34 void *bios_event_log_end;
35};
36
32struct acpi_tcpa { 37struct acpi_tcpa {
33 struct acpi_table_header hdr; 38 struct acpi_table_header hdr;
34 u16 reserved; 39 u16 reserved;
@@ -117,39 +122,34 @@ static const char* tcpa_pc_event_id_strings[] = {
117 "S-CRTM POST Contents", 122 "S-CRTM POST Contents",
118}; 123};
119 124
120/* (Binary) bios measurement buffer */
121static void *tcg_eventlog;
122static void *tcg_eventlog_addr_limit; /* MAX */
123
124/* returns pointer to start of pos. entry of tcg log */ 125/* returns pointer to start of pos. entry of tcg log */
125static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos) 126static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos)
126{ 127{
127 loff_t i; 128 loff_t i;
128 void *addr = tcg_eventlog; 129 struct tpm_bios_log *log = m->private;
130 void *addr = log->bios_event_log;
131 void *limit = log->bios_event_log_end;
129 struct tcpa_event *event; 132 struct tcpa_event *event;
130 133
131 /* read over *pos measurements */ 134 /* read over *pos measurements */
132 for (i = 0; i < *pos; i++) { 135 for (i = 0; i < *pos; i++) {
133 event = addr; 136 event = addr;
134 137
135 if ((addr + sizeof(struct tcpa_event)) < 138 if ((addr + sizeof(struct tcpa_event)) < limit) {
136 tcg_eventlog_addr_limit) {
137 if (event->event_type == 0 && event->event_size == 0) 139 if (event->event_type == 0 && event->event_size == 0)
138 return NULL; 140 return NULL;
139 addr += 141 addr += sizeof(struct tcpa_event) + event->event_size;
140 sizeof(struct tcpa_event) + event->event_size;
141 } 142 }
142 } 143 }
143 144
144 /* now check if current entry is valid */ 145 /* now check if current entry is valid */
145 if ((addr + sizeof(struct tcpa_event)) >= tcg_eventlog_addr_limit) 146 if ((addr + sizeof(struct tcpa_event)) >= limit)
146 return NULL; 147 return NULL;
147 148
148 event = addr; 149 event = addr;
149 150
150 if ((event->event_type == 0 && event->event_size == 0) || 151 if ((event->event_type == 0 && event->event_size == 0) ||
151 ((addr + sizeof(struct tcpa_event) + event->event_size) >= 152 ((addr + sizeof(struct tcpa_event) + event->event_size) >= limit))
152 tcg_eventlog_addr_limit))
153 return NULL; 153 return NULL;
154 154
155 return addr; 155 return addr;
@@ -159,11 +159,13 @@ static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
159 loff_t *pos) 159 loff_t *pos)
160{ 160{
161 struct tcpa_event *event = v; 161 struct tcpa_event *event = v;
162 struct tpm_bios_log *log = m->private;
163 void *limit = log->bios_event_log_end;
162 164
163 v += sizeof(struct tcpa_event) + event->event_size; 165 v += sizeof(struct tcpa_event) + event->event_size;
164 166
165 /* now check if current entry is valid */ 167 /* now check if current entry is valid */
166 if ((v + sizeof(struct tcpa_event)) >= tcg_eventlog_addr_limit) 168 if ((v + sizeof(struct tcpa_event)) >= limit)
167 return NULL; 169 return NULL;
168 170
169 event = v; 171 event = v;
@@ -172,8 +174,7 @@ static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
172 return NULL; 174 return NULL;
173 175
174 if ((event->event_type == 0 && event->event_size == 0) || 176 if ((event->event_type == 0 && event->event_size == 0) ||
175 ((v + sizeof(struct tcpa_event) + event->event_size) >= 177 ((v + sizeof(struct tcpa_event) + event->event_size) >= limit))
176 tcg_eventlog_addr_limit))
177 return NULL; 178 return NULL;
178 179
179 (*pos)++; 180 (*pos)++;
@@ -312,10 +313,14 @@ static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
312static int tpm_bios_measurements_release(struct inode *inode, 313static int tpm_bios_measurements_release(struct inode *inode,
313 struct file *file) 314 struct file *file)
314{ 315{
315 if (tcg_eventlog) { 316 struct seq_file *seq = file->private_data;
316 kfree(tcg_eventlog); 317 struct tpm_bios_log *log = seq->private;
317 tcg_eventlog = NULL; 318
319 if (log) {
320 kfree(log->bios_event_log);
321 kfree(log);
318 } 322 }
323
319 return seq_release(inode, file); 324 return seq_release(inode, file);
320} 325}
321 326
@@ -367,13 +372,13 @@ static struct seq_operations tpm_binary_b_measurments_seqops = {
367}; 372};
368 373
369/* read binary bios log */ 374/* read binary bios log */
370static int read_log(void) 375static int read_log(struct tpm_bios_log *log)
371{ 376{
372 struct acpi_tcpa *buff; 377 struct acpi_tcpa *buff;
373 acpi_status status; 378 acpi_status status;
374 void *virt; 379 void *virt;
375 380
376 if (tcg_eventlog != NULL) { 381 if (log->bios_event_log != NULL) {
377 printk(KERN_ERR 382 printk(KERN_ERR
378 "%s: ERROR - Eventlog already initialized\n", 383 "%s: ERROR - Eventlog already initialized\n",
379 __func__); 384 __func__);
@@ -393,25 +398,24 @@ static int read_log(void)
393 } 398 }
394 399
395 if (buff->log_max_len == 0) { 400 if (buff->log_max_len == 0) {
396 printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", 401 printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
397 __func__);
398 return -EIO; 402 return -EIO;
399 } 403 }
400 404
401 /* malloc EventLog space */ 405 /* malloc EventLog space */
402 tcg_eventlog = kmalloc(buff->log_max_len, GFP_KERNEL); 406 log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
403 if (!tcg_eventlog) { 407 if (!log->bios_event_log) {
404 printk 408 printk
405 ("%s: ERROR - Not enough Memory for BIOS measurements\n", 409 ("%s: ERROR - Not enough Memory for BIOS measurements\n",
406 __func__); 410 __func__);
407 return -ENOMEM; 411 return -ENOMEM;
408 } 412 }
409 413
410 tcg_eventlog_addr_limit = tcg_eventlog + buff->log_max_len; 414 log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
411 415
412 acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, &virt); 416 acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, &virt);
413 417
414 memcpy(tcg_eventlog, virt, buff->log_max_len); 418 memcpy(log->bios_event_log, virt, buff->log_max_len);
415 419
416 acpi_os_unmap_memory(virt, buff->log_max_len); 420 acpi_os_unmap_memory(virt, buff->log_max_len);
417 return 0; 421 return 0;
@@ -421,12 +425,26 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode,
421 struct file *file) 425 struct file *file)
422{ 426{
423 int err; 427 int err;
428 struct tpm_bios_log *log;
429 struct seq_file *seq;
424 430
425 if ((err = read_log())) 431 log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL);
432 if (!log)
433 return -ENOMEM;
434
435 if ((err = read_log(log)))
426 return err; 436 return err;
427 437
428 /* now register seq file */ 438 /* now register seq file */
429 return seq_open(file, &tpm_ascii_b_measurments_seqops); 439 err = seq_open(file, &tpm_ascii_b_measurments_seqops);
440 if (!err) {
441 seq = file->private_data;
442 seq->private = log;
443 } else {
444 kfree(log->bios_event_log);
445 kfree(log);
446 }
447 return err;
430} 448}
431 449
432struct file_operations tpm_ascii_bios_measurements_ops = { 450struct file_operations tpm_ascii_bios_measurements_ops = {
@@ -440,12 +458,26 @@ static int tpm_binary_bios_measurements_open(struct inode *inode,
440 struct file *file) 458 struct file *file)
441{ 459{
442 int err; 460 int err;
461 struct tpm_bios_log *log;
462 struct seq_file *seq;
443 463
444 if ((err = read_log())) 464 log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL);
465 if (!log)
466 return -ENOMEM;
467
468 if ((err = read_log(log)))
445 return err; 469 return err;
446 470
447 /* now register seq file */ 471 /* now register seq file */
448 return seq_open(file, &tpm_binary_b_measurments_seqops); 472 err = seq_open(file, &tpm_binary_b_measurments_seqops);
473 if (!err) {
474 seq = file->private_data;
475 seq->private = log;
476 } else {
477 kfree(log->bios_event_log);
478 kfree(log);
479 }
480 return err;
449} 481}
450 482
451struct file_operations tpm_binary_bios_measurements_ops = { 483struct file_operations tpm_binary_bios_measurements_ops = {