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