1/* 2 * Copyright 2012 IBM Corporation 3 * 4 * Author: Ashley Lai <ashleydlai@gmail.com> 5 * 6 * Maintained by: <tpmdd-devel@lists.sourceforge.net> 7 * 8 * Read the event log created by the firmware on PPC64 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License 12 * as published by the Free Software Foundation; either version 13 * 2 of the License, or (at your option) any later version. 14 * 15 */ 16 17#include <linux/slab.h> 18#include <linux/of.h> 19 20#include "tpm.h" 21#include "tpm_eventlog.h" 22 23int read_log(struct tpm_bios_log *log) 24{ 25 struct device_node *np; 26 const u32 *sizep; 27 const __be64 *basep; 28 29 if (log->bios_event_log != NULL) { 30 pr_err("%s: ERROR - Eventlog already initialized\n", __func__); 31 return -EFAULT; 32 } 33 34 np = of_find_node_by_name(NULL, "ibm,vtpm"); 35 if (!np) { 36 pr_err("%s: ERROR - IBMVTPM not supported\n", __func__); 37 return -ENODEV; 38 } 39 40 sizep = of_get_property(np, "linux,sml-size", NULL); 41 if (sizep == NULL) { 42 pr_err("%s: ERROR - SML size not found\n", __func__); 43 goto cleanup_eio; 44 } 45 if (*sizep == 0) { 46 pr_err("%s: ERROR - event log area empty\n", __func__); 47 goto cleanup_eio; 48 } 49 50 basep = of_get_property(np, "linux,sml-base", NULL); 51 if (basep == NULL) { 52 pr_err(KERN_ERR "%s: ERROR - SML not found\n", __func__); 53 goto cleanup_eio; 54 } 55 56 of_node_put(np); 57 log->bios_event_log = kmalloc(*sizep, GFP_KERNEL); 58 if (!log->bios_event_log) { 59 pr_err("%s: ERROR - Not enough memory for BIOS measurements\n", 60 __func__); 61 return -ENOMEM; 62 } 63 64 log->bios_event_log_end = log->bios_event_log + *sizep; 65 66 memcpy(log->bios_event_log, __va(be64_to_cpup(basep)), *sizep); 67 68 return 0; 69 70cleanup_eio: 71 of_node_put(np); 72 return -EIO; 73} 74