linux/drivers/char/tpm/tpm_of.c
<<
>>
Prefs
   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 u64 *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, "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("%s: ERROR - SML not found\n", __func__);
  53                goto cleanup_eio;
  54        }
  55
  56        log->bios_event_log = kmalloc(*sizep, GFP_KERNEL);
  57        if (!log->bios_event_log) {
  58                pr_err("%s: ERROR - Not enough memory for BIOS measurements\n",
  59                       __func__);
  60                of_node_put(np);
  61                return -ENOMEM;
  62        }
  63
  64        log->bios_event_log_end = log->bios_event_log + *sizep;
  65
  66        memcpy(log->bios_event_log, __va(*basep), *sizep);
  67        of_node_put(np);
  68
  69        return 0;
  70
  71cleanup_eio:
  72        of_node_put(np);
  73        return -EIO;
  74}
  75