Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.12-rc4 77 lines 2.0 kB view raw
1/* 2 * Copyright 2012 IBM Corporation 3 * 4 * Author: Ashley Lai <ashleydlai@gmail.com> 5 * Nayna Jain <nayna@linux.vnet.ibm.com> 6 * 7 * Maintained by: <tpmdd-devel@lists.sourceforge.net> 8 * 9 * Read the event log created by the firmware on PPC64 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License 13 * as published by the Free Software Foundation; either version 14 * 2 of the License, or (at your option) any later version. 15 * 16 */ 17 18#include <linux/slab.h> 19#include <linux/of.h> 20 21#include "tpm.h" 22#include "tpm_eventlog.h" 23 24int tpm_read_log_of(struct tpm_chip *chip) 25{ 26 struct device_node *np; 27 const u32 *sizep; 28 const u64 *basep; 29 struct tpm_bios_log *log; 30 u32 size; 31 u64 base; 32 33 log = &chip->log; 34 if (chip->dev.parent && chip->dev.parent->of_node) 35 np = chip->dev.parent->of_node; 36 else 37 return -ENODEV; 38 39 sizep = of_get_property(np, "linux,sml-size", NULL); 40 basep = of_get_property(np, "linux,sml-base", NULL); 41 if (sizep == NULL && basep == NULL) 42 return -ENODEV; 43 if (sizep == NULL || basep == NULL) 44 return -EIO; 45 46 /* 47 * For both vtpm/tpm, firmware has log addr and log size in big 48 * endian format. But in case of vtpm, there is a method called 49 * sml-handover which is run during kernel init even before 50 * device tree is setup. This sml-handover function takes care 51 * of endianness and writes to sml-base and sml-size in little 52 * endian format. For this reason, vtpm doesn't need conversion 53 * but physical tpm needs the conversion. 54 */ 55 if (of_property_match_string(np, "compatible", "IBM,vtpm") < 0) { 56 size = be32_to_cpup(sizep); 57 base = be64_to_cpup(basep); 58 } else { 59 size = *sizep; 60 base = *basep; 61 } 62 63 if (size == 0) { 64 dev_warn(&chip->dev, "%s: Event log area empty\n", __func__); 65 return -EIO; 66 } 67 68 log->bios_event_log = kmalloc(size, GFP_KERNEL); 69 if (!log->bios_event_log) 70 return -ENOMEM; 71 72 log->bios_event_log_end = log->bios_event_log + size; 73 74 memcpy(log->bios_event_log, __va(base), size); 75 76 return 0; 77}