!454 [sync] PR-444: add support for hygon tpcm
From: @chench00 Reviewed-by: @t_feng Signed-off-by: @t_feng
This commit is contained in:
commit
92986515fd
374
0001-newfeature-tpcm-add-hygon-tpcm-support.patch
Normal file
374
0001-newfeature-tpcm-add-hygon-tpcm-support.patch
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
From da39c467f634f19ce913d8454b9a1be6d0f5f82a Mon Sep 17 00:00:00 2001
|
||||||
|
From: chench <chench@hygon.cn>
|
||||||
|
Date: Thu, 5 Dec 2023 20:37:04 +0800
|
||||||
|
Subject: [PATCH] newfeature: tpcm: add tpcm support
|
||||||
|
|
||||||
|
---
|
||||||
|
grub-core/Makefile.core.def | 7 ++
|
||||||
|
grub-core/commands/efi/tpcm_hygon.c | 163 ++++++++++++++++++++++++++++
|
||||||
|
grub-core/commands/tpcm_hygon.c | 100 +++++++++++++++++
|
||||||
|
include/grub/efi/tpcm_hygon.h | 42 ++++++++
|
||||||
|
include/grub/err.h | 3 +-
|
||||||
|
5 files changed, 314 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100755 grub-core/commands/efi/tpcm_hygon.c
|
||||||
|
create mode 100755 grub-core/commands/tpcm_hygon.c
|
||||||
|
create mode 100644 include/grub/efi/tpcm_hygon.h
|
||||||
|
|
||||||
|
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||||
|
index 4fb34b1..681f65a 100644
|
||||||
|
--- a/grub-core/Makefile.core.def
|
||||||
|
+++ b/grub-core/Makefile.core.def
|
||||||
|
@@ -2623,6 +2623,13 @@ module = {
|
||||||
|
enable = efi;
|
||||||
|
};
|
||||||
|
|
||||||
|
+module = {
|
||||||
|
+ name = tpcm_hygon;
|
||||||
|
+ common = commands/tpcm_hygon.c;
|
||||||
|
+ efi = commands/efi/tpcm_hygon.c;
|
||||||
|
+ enable = x86_64_efi;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
module = {
|
||||||
|
name = tr;
|
||||||
|
common = commands/tr.c;
|
||||||
|
diff --git a/grub-core/commands/efi/tpcm_hygon.c b/grub-core/commands/efi/tpcm_hygon.c
|
||||||
|
new file mode 100755
|
||||||
|
index 0000000..ffe86ef
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/grub-core/commands/efi/tpcm_hygon.c
|
||||||
|
@@ -0,0 +1,163 @@
|
||||||
|
+/*
|
||||||
|
+ * GRUB -- GRand Unified Bootloader
|
||||||
|
+ * Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
+ *
|
||||||
|
+ * GRUB is free software: you can redistribute it and/or modify
|
||||||
|
+ * it under the terms of the GNU General Public License as published by
|
||||||
|
+ * the Free Software Foundation, either version 3 of the License, or
|
||||||
|
+ * (at your option) any later version.
|
||||||
|
+ *
|
||||||
|
+ * GRUB is distributed in the hope that it will be useful,
|
||||||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
+ * GNU General Public License for more details.
|
||||||
|
+ *
|
||||||
|
+ * You should have received a copy of the GNU General Public License
|
||||||
|
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
+ *
|
||||||
|
+ * EFI TPCM support code.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <grub/err.h>
|
||||||
|
+#include <grub/efi/tpcm_hygon.h>
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static grub_uint32_t g_measured_id = STAGE_START;
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ get_tpcm_stage:
|
||||||
|
+ TPCM does not make a distinction with the type of
|
||||||
|
+ measured target, so we use g_measured_id directly
|
||||||
|
+ for the stage.
|
||||||
|
+ */
|
||||||
|
+static grub_uint32_t get_tpcm_stage(void)
|
||||||
|
+{
|
||||||
|
+ grub_uint32_t stage = STAGE_INVALID;
|
||||||
|
+
|
||||||
|
+ stage = g_measured_id;
|
||||||
|
+
|
||||||
|
+ if (stage < STAGE_START || stage > STAGE_END)
|
||||||
|
+ stage = STAGE_INVALID;
|
||||||
|
+
|
||||||
|
+ return stage;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ update_measured_id:
|
||||||
|
+ update g_measured_id +1 every time measured, and g_measured_id
|
||||||
|
+ will never be decreased.
|
||||||
|
+ */
|
||||||
|
+static void update_measured_id(void)
|
||||||
|
+{
|
||||||
|
+ g_measured_id++;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ measure_memory:
|
||||||
|
+ measure the memery region--(addr, size) through the TPCM protocol.
|
||||||
|
+ if TPCM protocol is not exist in BIOS, it will return SUCC to keep
|
||||||
|
+ compatible with non-measurement-support bios; if TPCM protocol is
|
||||||
|
+ exist but not enabled, it will also return SUCC.
|
||||||
|
+ */
|
||||||
|
+static grub_err_t measure_memory(enum grub_file_type type __attribute__((unused)),
|
||||||
|
+ char *desc,
|
||||||
|
+ grub_addr_t addr,
|
||||||
|
+ grub_size_t size)
|
||||||
|
+{
|
||||||
|
+ grub_efi_handle_t *handles = 0;
|
||||||
|
+ grub_efi_uintn_t num_handles;
|
||||||
|
+ grub_efi_handle_t grub_c2p_handle = 0;
|
||||||
|
+ grub_err_t test_c2p_err = GRUB_ERR_BAD_OS;
|
||||||
|
+ grub_guid_t c2p_guid = C2PGUID;
|
||||||
|
+ grub_uint32_t measure_result = 0;
|
||||||
|
+ grub_uint32_t control_result = 0;
|
||||||
|
+ grub_efi_boolean_t verify_enable = 0;
|
||||||
|
+ grub_size_t desc_len = 0;
|
||||||
|
+
|
||||||
|
+ handles = grub_efi_locate_handle(GRUB_EFI_BY_PROTOCOL, &c2p_guid, NULL, &num_handles);
|
||||||
|
+ if (handles && (num_handles > 0))
|
||||||
|
+ {
|
||||||
|
+ struct c2p_protocol *c2p;
|
||||||
|
+
|
||||||
|
+ grub_c2p_handle = handles[0];
|
||||||
|
+ grub_dprintf("tpcm_hygon", "measue memory addr 0x%lx size 0x%lx \n", addr, size);
|
||||||
|
+ c2p = grub_efi_open_protocol(grub_c2p_handle, &c2p_guid,
|
||||||
|
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||||
|
+ if (c2p)
|
||||||
|
+ {
|
||||||
|
+ verify_enable = c2p->verify_is_enabled (c2p);
|
||||||
|
+ if (verify_enable)
|
||||||
|
+ {
|
||||||
|
+ struct addr_range range;
|
||||||
|
+ grub_efi_status_t status = 0;
|
||||||
|
+ grub_uint32_t stage = STAGE_INVALID;
|
||||||
|
+
|
||||||
|
+ range.start = addr;
|
||||||
|
+ range.length = size;
|
||||||
|
+
|
||||||
|
+ stage = get_tpcm_stage();
|
||||||
|
+ if (stage != STAGE_INVALID)
|
||||||
|
+ {
|
||||||
|
+ desc_len = grub_strlen(desc) + 1;
|
||||||
|
+ status = c2p->verify_raw (c2p, stage, (grub_uint64_t)desc, desc_len, 1, &range, &measure_result, &control_result);
|
||||||
|
+ if ((!status) && ((control_result & MEASURE_ACTION_MASK) == 0) )
|
||||||
|
+ {
|
||||||
|
+ grub_dprintf("tpcm_hygon", "verify_raw success. stage[%d]desc:[%s]\n", stage, desc);
|
||||||
|
+ test_c2p_err = GRUB_ERR_NONE;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ grub_dprintf("tpcm_hygon", "verify_raw error\n");
|
||||||
|
+ while(1)
|
||||||
|
+ {
|
||||||
|
+ grub_error(GRUB_ERR_TPCM_VERIFY, "tpcm verify error. stage[%d]desc[%s]\n", stage, desc);
|
||||||
|
+ asm volatile ("hlt");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ grub_dprintf ("tpcm_hygon", "invalid stage\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ update_measured_id();
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ grub_dprintf ("tpcm_hygon", "image verify not enabled\n");
|
||||||
|
+ test_c2p_err = GRUB_ERR_NONE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ grub_dprintf ("tpcm_hygon", "open c2p protocol failed\n");
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ // keep compatible with non-measurement-support bios.
|
||||||
|
+ grub_dprintf("tpcm_hygon", "not found C2P protocol\n");
|
||||||
|
+ test_c2p_err = GRUB_ERR_NONE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return test_c2p_err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ grub_tpcm_measure_memory:
|
||||||
|
+ */
|
||||||
|
+grub_err_t grub_tpcm_measure_memory(void *context, grub_addr_t buf, grub_size_t size)
|
||||||
|
+{
|
||||||
|
+ char *p_context = (char *)context;
|
||||||
|
+ char *p, *p_desc;
|
||||||
|
+ char tmp[TPCM_MAX_BUF_SIZE] = {'0'};
|
||||||
|
+ enum grub_file_type type;
|
||||||
|
+
|
||||||
|
+ if (!p_context)
|
||||||
|
+ return GRUB_ERR_BUG;
|
||||||
|
+
|
||||||
|
+ p = grub_strchr(p_context, '|');
|
||||||
|
+ p_desc = p + 1;
|
||||||
|
+ grub_memcpy(tmp, p_context, (p-p_context));
|
||||||
|
+ type = grub_strtoul(tmp, 0, 10);
|
||||||
|
+
|
||||||
|
+ return measure_memory(type, p_desc, buf, size);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
diff --git a/grub-core/commands/tpcm_hygon.c b/grub-core/commands/tpcm_hygon.c
|
||||||
|
new file mode 100755
|
||||||
|
index 0000000..564ab85
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/grub-core/commands/tpcm_hygon.c
|
||||||
|
@@ -0,0 +1,100 @@
|
||||||
|
+/*
|
||||||
|
+ * GRUB -- GRand Unified Bootloader
|
||||||
|
+ * Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
+ *
|
||||||
|
+ * GRUB is free software: you can redistribute it and/or modify
|
||||||
|
+ * it under the terms of the GNU General Public License as published by
|
||||||
|
+ * the Free Software Foundation, either version 3 of the License, or
|
||||||
|
+ * (at your option) any later version.
|
||||||
|
+ *
|
||||||
|
+ * GRUB is distributed in the hope that it will be useful,
|
||||||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
+ * GNU General Public License for more details.
|
||||||
|
+ *
|
||||||
|
+ * You should have received a copy of the GNU General Public License
|
||||||
|
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
+ *
|
||||||
|
+ * Core TPCM support code.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#include <grub/err.h>
|
||||||
|
+#include <grub/verify.h>
|
||||||
|
+#include <grub/dl.h>
|
||||||
|
+#include <grub/efi/tpcm_hygon.h>
|
||||||
|
+
|
||||||
|
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
+
|
||||||
|
+static char context_buf[TPCM_MAX_BUF_SIZE];
|
||||||
|
+
|
||||||
|
+static grub_err_t grub_tpcm_verify_init(grub_file_t io,
|
||||||
|
+ enum grub_file_type type,
|
||||||
|
+ void **context,
|
||||||
|
+ enum grub_verify_flags *flags)
|
||||||
|
+{
|
||||||
|
+ grub_memset(context_buf, 0, TPCM_MAX_BUF_SIZE);
|
||||||
|
+ grub_snprintf(context_buf, TPCM_MAX_BUF_SIZE, "%d|%s", (type & GRUB_FILE_TYPE_MASK), io->name);
|
||||||
|
+ *context = context_buf;
|
||||||
|
+ *flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
|
||||||
|
+
|
||||||
|
+ return GRUB_ERR_NONE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static grub_err_t grub_tpcm_verify_write(void *context, void *buf , grub_size_t size )
|
||||||
|
+{
|
||||||
|
+ return grub_tpcm_measure_memory(context, (grub_addr_t)buf, size);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static grub_err_t grub_tpcm_verify_string (char *str, enum grub_verify_string_type type)
|
||||||
|
+{
|
||||||
|
+ const char *prefix = NULL;
|
||||||
|
+ char *description, *context;
|
||||||
|
+ grub_err_t status;
|
||||||
|
+
|
||||||
|
+ switch (type)
|
||||||
|
+ {
|
||||||
|
+ case GRUB_VERIFY_KERNEL_CMDLINE:
|
||||||
|
+ prefix = "kernel_cmdline: ";
|
||||||
|
+ break;
|
||||||
|
+ case GRUB_VERIFY_MODULE_CMDLINE:
|
||||||
|
+ prefix = "module_cmdline: ";
|
||||||
|
+ break;
|
||||||
|
+ case GRUB_VERIFY_COMMAND:
|
||||||
|
+ prefix = "grub_cmd: ";
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ context = grub_zalloc(grub_strlen (str) + grub_strlen (prefix) + 1 + 4); //4 for type
|
||||||
|
+ if (!context)
|
||||||
|
+ return grub_errno;
|
||||||
|
+
|
||||||
|
+ grub_snprintf(context, 4, "%d|", (type & GRUB_FILE_TYPE_MASK));
|
||||||
|
+ description = context + grub_strlen(context);
|
||||||
|
+ grub_memcpy(description, prefix, grub_strlen (prefix));
|
||||||
|
+ grub_memcpy(description + grub_strlen (prefix), str, grub_strlen (str) + 1);
|
||||||
|
+
|
||||||
|
+ status = grub_tpcm_measure_memory(context, (grub_addr_t)str, grub_strlen(str));
|
||||||
|
+
|
||||||
|
+ grub_free(context);
|
||||||
|
+
|
||||||
|
+ return status;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct grub_file_verifier grub_tpcm_verifier = {
|
||||||
|
+ .name = "tpcm_hygon",
|
||||||
|
+ .init = grub_tpcm_verify_init,
|
||||||
|
+ .write = grub_tpcm_verify_write,
|
||||||
|
+ .verify_string = grub_tpcm_verify_string,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+GRUB_MOD_INIT (tpcm_hygon)
|
||||||
|
+{
|
||||||
|
+ grub_verifier_register(&grub_tpcm_verifier);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+GRUB_MOD_FINI (tpcm_hygon)
|
||||||
|
+{
|
||||||
|
+ grub_verifier_unregister(&grub_tpcm_verifier);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
diff --git a/include/grub/efi/tpcm_hygon.h b/include/grub/efi/tpcm_hygon.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..523d19c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/include/grub/efi/tpcm_hygon.h
|
||||||
|
@@ -0,0 +1,42 @@
|
||||||
|
+#ifndef GRUB_EFI_TPCM_HEADER
|
||||||
|
+#define GRUB_EFI_TPCM_HEADER 1
|
||||||
|
+
|
||||||
|
+#include <grub/file.h>
|
||||||
|
+#include <grub/efi/api.h>
|
||||||
|
+#include <grub/efi/efi.h>
|
||||||
|
+
|
||||||
|
+#define C2PGUID {0xf89ab5cd, 0x2829, 0x422f, {0xa5, 0xf3, 0x03, 0x28, 0xe0, 0x6c, 0xfc, 0xbb}}
|
||||||
|
+#define MEASURE_RESULT_MASK (0xff00)
|
||||||
|
+#define MEASURE_RESULT_SHIFT (16)
|
||||||
|
+#define MEASURE_ACTION_MASK (0x1)
|
||||||
|
+#define TPCM_MAX_BUF_SIZE 128
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ stage layout:
|
||||||
|
+ 2000~2999: +1 every time
|
||||||
|
+*/
|
||||||
|
+
|
||||||
|
+#define STAGE_START 2000
|
||||||
|
+#define STAGE_END 2999
|
||||||
|
+#define STAGE_INVALID 3000
|
||||||
|
+
|
||||||
|
+struct addr_range {
|
||||||
|
+ grub_uint64_t start;
|
||||||
|
+ grub_uint64_t length;
|
||||||
|
+};
|
||||||
|
+struct c2p_protocol {
|
||||||
|
+ grub_efi_status_t (__grub_efi_api *verify_raw) (struct c2p_protocol *this,
|
||||||
|
+ grub_uint32_t measure_stage,
|
||||||
|
+ grub_uint64_t image_info,
|
||||||
|
+ grub_uint32_t image_info_size,
|
||||||
|
+ grub_uint32_t num_addr_range,
|
||||||
|
+ struct addr_range ranges[],
|
||||||
|
+ grub_uint32_t *measure_result,
|
||||||
|
+ grub_uint32_t *control_result);
|
||||||
|
+ grub_efi_boolean_t (__grub_efi_api *verify_is_enabled)(struct c2p_protocol *this);
|
||||||
|
+};
|
||||||
|
+typedef struct c2p_protocol c2p_protocol_t;
|
||||||
|
+
|
||||||
|
+grub_err_t grub_tpcm_measure_memory(void *context, grub_addr_t buf, grub_size_t size);
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff --git a/include/grub/err.h b/include/grub/err.h
|
||||||
|
index b68bbec..2f10ac0 100644
|
||||||
|
--- a/include/grub/err.h
|
||||||
|
+++ b/include/grub/err.h
|
||||||
|
@@ -73,7 +73,8 @@ typedef enum
|
||||||
|
GRUB_ERR_NET_NO_DOMAIN,
|
||||||
|
GRUB_ERR_EOF,
|
||||||
|
GRUB_ERR_BAD_SIGNATURE,
|
||||||
|
- GRUB_ERR_BAD_FIRMWARE
|
||||||
|
+ GRUB_ERR_BAD_FIRMWARE,
|
||||||
|
+ GRUB_ERR_TPCM_VERIFY
|
||||||
|
}
|
||||||
|
grub_err_t;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.27.0
|
||||||
|
|
||||||
@ -454,6 +454,9 @@ GRUB_MODULES=" all_video boot blscfg btrfs \\\
|
|||||||
search_label serial sleep test tftp \\\
|
search_label serial sleep test tftp \\\
|
||||||
video xfs " \
|
video xfs " \
|
||||||
GRUB_MODULES+=%{efi_modules} \
|
GRUB_MODULES+=%{efi_modules} \
|
||||||
|
%if "%{1}" == "x86_64-efi" \
|
||||||
|
GRUB_MODULES+=" tpcm_hygon " \
|
||||||
|
%endif \
|
||||||
%{expand:%%{mkimage %{1} %{2} %{3} %{4}}} \
|
%{expand:%%{mkimage %{1} %{2} %{3} %{4}}} \
|
||||||
%{nil}
|
%{nil}
|
||||||
|
|
||||||
|
|||||||
@ -239,3 +239,4 @@ Patch238: grub2-ppc64le-fix-bug-about-petitboot-doesn-t-ignore-EFI-entries
|
|||||||
Patch239: 0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch
|
Patch239: 0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch
|
||||||
Patch240: 0061-Add-BLS-support-to-grub-mkconfig.patch
|
Patch240: 0061-Add-BLS-support-to-grub-mkconfig.patch
|
||||||
Patch241: 0064-Add-grub2-switch-to-blscfg.patch
|
Patch241: 0064-Add-grub2-switch-to-blscfg.patch
|
||||||
|
Patch242: 0001-newfeature-tpcm-add-hygon-tpcm-support.patch
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
Name: grub2
|
Name: grub2
|
||||||
Epoch: 1
|
Epoch: 1
|
||||||
Version: 2.12
|
Version: 2.12
|
||||||
Release: 23
|
Release: 24
|
||||||
Summary: Bootloader with support for Linux, Multiboot and more
|
Summary: Bootloader with support for Linux, Multiboot and more
|
||||||
License: GPLv3+
|
License: GPLv3+
|
||||||
URL: http://www.gnu.org/software/grub/
|
URL: http://www.gnu.org/software/grub/
|
||||||
@ -456,6 +456,12 @@ fi
|
|||||||
%{_datadir}/man/man*
|
%{_datadir}/man/man*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Aug 2 2024 chench <chench@hygon.cn> - 1:2.12-24
|
||||||
|
- Type:requirement
|
||||||
|
- CVE:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:add support for hygon tpcm
|
||||||
|
|
||||||
* Wed Jul 24 2024 wangyueliang <wangyueliang@kylinos.cn> - 1:2.12-23
|
* Wed Jul 24 2024 wangyueliang <wangyueliang@kylinos.cn> - 1:2.12-23
|
||||||
- Type:requirement
|
- Type:requirement
|
||||||
- CVE:NA
|
- CVE:NA
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user