xref: /linux/drivers/char/tpm/eventlog/efi.c (revision d6869352cb3c3cf3450637a52349e2e87c1354aa)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2017 Google
4  *
5  * Authors:
6  *      Thiebaud Weksteen <tweek@google.com>
7  */
8 
9 #include <linux/efi.h>
10 #include <linux/tpm_eventlog.h>
11 
12 #include "../tpm.h"
13 #include "common.h"
14 
15 /* read binary bios log from EFI configuration table */
16 int tpm_read_log_efi(struct tpm_chip *chip)
17 {
18 
19 	struct linux_efi_tpm_eventlog *log_tbl;
20 	struct tpm_bios_log *log;
21 	u32 log_size;
22 	u8 tpm_log_version;
23 
24 	if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
25 		return -ENODEV;
26 
27 	if (efi.tpm_log == EFI_INVALID_TABLE_ADDR)
28 		return -ENODEV;
29 
30 	log = &chip->log;
31 
32 	log_tbl = memremap(efi.tpm_log, sizeof(*log_tbl), MEMREMAP_WB);
33 	if (!log_tbl) {
34 		pr_err("Could not map UEFI TPM log table !\n");
35 		return -ENOMEM;
36 	}
37 
38 	log_size = log_tbl->size;
39 	memunmap(log_tbl);
40 
41 	log_tbl = memremap(efi.tpm_log, sizeof(*log_tbl) + log_size,
42 			   MEMREMAP_WB);
43 	if (!log_tbl) {
44 		pr_err("Could not map UEFI TPM log table payload!\n");
45 		return -ENOMEM;
46 	}
47 
48 	/* malloc EventLog space */
49 	log->bios_event_log = kmemdup(log_tbl->log, log_size, GFP_KERNEL);
50 	if (!log->bios_event_log)
51 		goto err_memunmap;
52 	log->bios_event_log_end = log->bios_event_log + log_size;
53 
54 	tpm_log_version = log_tbl->version;
55 	memunmap(log_tbl);
56 	return tpm_log_version;
57 
58 err_memunmap:
59 	memunmap(log_tbl);
60 	return -ENOMEM;
61 }
62