mirror of
https://src.fedoraproject.org/rpms/grub2.git
synced 2024-11-24 06:22:43 +00:00
ppc64le: CAS improvements, prefix detection, and vTPM support
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
This commit is contained in:
parent
ac52d21d8a
commit
d15d46b0e4
5 changed files with 424 additions and 1 deletions
110
0215-powerpc-do-CAS-in-a-more-compatible-way.patch
Normal file
110
0215-powerpc-do-CAS-in-a-more-compatible-way.patch
Normal file
|
@ -0,0 +1,110 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Fri, 8 Apr 2022 12:35:28 +1000
|
||||
Subject: [PATCH] powerpc: do CAS in a more compatible way
|
||||
|
||||
I wrongly assumed that the most compatible way to perform CAS
|
||||
negotiation was to only set the minimum number of vectors required
|
||||
to ask for more memory. It turns out that this messes up booting
|
||||
if the minimum VP capacity would be less than the default 10% in
|
||||
vector 4.
|
||||
|
||||
Linux configures the minimum capacity to be 1%, so copy it for that
|
||||
and for vector 3 which we now need to specify as well.
|
||||
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
---
|
||||
grub-core/kern/ieee1275/init.c | 54 ++++++++++++++++++++++++------------------
|
||||
1 file changed, 31 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index 9704715c83..ef55107467 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -298,33 +298,37 @@ grub_ieee1275_total_mem (grub_uint64_t *total)
|
||||
|
||||
/* Based on linux - arch/powerpc/kernel/prom_init.c */
|
||||
struct option_vector2 {
|
||||
- grub_uint8_t byte1;
|
||||
- grub_uint16_t reserved;
|
||||
- grub_uint32_t real_base;
|
||||
- grub_uint32_t real_size;
|
||||
- grub_uint32_t virt_base;
|
||||
- grub_uint32_t virt_size;
|
||||
- grub_uint32_t load_base;
|
||||
- grub_uint32_t min_rma;
|
||||
- grub_uint32_t min_load;
|
||||
- grub_uint8_t min_rma_percent;
|
||||
- grub_uint8_t max_pft_size;
|
||||
+ grub_uint8_t byte1;
|
||||
+ grub_uint16_t reserved;
|
||||
+ grub_uint32_t real_base;
|
||||
+ grub_uint32_t real_size;
|
||||
+ grub_uint32_t virt_base;
|
||||
+ grub_uint32_t virt_size;
|
||||
+ grub_uint32_t load_base;
|
||||
+ grub_uint32_t min_rma;
|
||||
+ grub_uint32_t min_load;
|
||||
+ grub_uint8_t min_rma_percent;
|
||||
+ grub_uint8_t max_pft_size;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct pvr_entry {
|
||||
- grub_uint32_t mask;
|
||||
- grub_uint32_t entry;
|
||||
+ grub_uint32_t mask;
|
||||
+ grub_uint32_t entry;
|
||||
};
|
||||
|
||||
struct cas_vector {
|
||||
- struct {
|
||||
- struct pvr_entry terminal;
|
||||
- } pvr_list;
|
||||
- grub_uint8_t num_vecs;
|
||||
- grub_uint8_t vec1_size;
|
||||
- grub_uint8_t vec1;
|
||||
- grub_uint8_t vec2_size;
|
||||
- struct option_vector2 vec2;
|
||||
+ struct {
|
||||
+ struct pvr_entry terminal;
|
||||
+ } pvr_list;
|
||||
+ grub_uint8_t num_vecs;
|
||||
+ grub_uint8_t vec1_size;
|
||||
+ grub_uint8_t vec1;
|
||||
+ grub_uint8_t vec2_size;
|
||||
+ struct option_vector2 vec2;
|
||||
+ grub_uint8_t vec3_size;
|
||||
+ grub_uint16_t vec3;
|
||||
+ grub_uint8_t vec4_size;
|
||||
+ grub_uint16_t vec4;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Call ibm,client-architecture-support to try to get more RMA.
|
||||
@@ -345,13 +349,17 @@ grub_ieee1275_ibm_cas (void)
|
||||
} args;
|
||||
struct cas_vector vector = {
|
||||
.pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */
|
||||
- .num_vecs = 2 - 1,
|
||||
+ .num_vecs = 4 - 1,
|
||||
.vec1_size = 0,
|
||||
.vec1 = 0x80, /* ignore */
|
||||
.vec2_size = 1 + sizeof(struct option_vector2) - 2,
|
||||
.vec2 = {
|
||||
0, 0, -1, -1, -1, -1, -1, 512, -1, 0, 48
|
||||
},
|
||||
+ .vec3_size = 2 - 1,
|
||||
+ .vec3 = 0x00e0, // ask for FP + VMX + DFP but don't halt if unsatisfied
|
||||
+ .vec4_size = 2 - 1,
|
||||
+ .vec4 = 0x0001, // set required minimum capacity % to the lowest value
|
||||
};
|
||||
|
||||
INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2);
|
||||
@@ -364,7 +372,7 @@ grub_ieee1275_ibm_cas (void)
|
||||
args.ihandle = root;
|
||||
args.cas_addr = (grub_ieee1275_cell_t)&vector;
|
||||
|
||||
- grub_printf("Calling ibm,client-architecture-support...");
|
||||
+ grub_printf("Calling ibm,client-architecture-support from grub...");
|
||||
IEEE1275_CALL_ENTRY_FN (&args);
|
||||
grub_printf("done\n");
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Thu, 24 Mar 2022 14:34:32 +1100
|
||||
Subject: [PATCH] powerpc: prefix detection: support device names with commas
|
||||
|
||||
Frustratingly, the device name itself can contain an embedded comma:
|
||||
e.g /pci@800000020000015/pci1014,034A@0/sas/disk@5000c50098a0ee8b
|
||||
|
||||
So my previous approach was wrong: we cannot rely upon the presence
|
||||
of a comma to say that a partition has been specified!
|
||||
|
||||
It turns out for prefixes like (,gpt2)/grub2 we really want to make
|
||||
up a full (device,partition)/patch prefix, because root discovery code
|
||||
in 10_linux will reset the root variable and use search to fill it again.
|
||||
If you have run grub-install, you probably don't have search built in,
|
||||
and if you don't have prefix containing (device,partition), grub will
|
||||
construct ($root)$prefix/powerpc-ieee1275/search.mod - but because $root
|
||||
has just been changed, this will no longer work, and the boot will fail!
|
||||
|
||||
Retain the gist of the logic, but instead of looking for a comma, look for
|
||||
a leading '('. This matches the earlier code better anyway.
|
||||
|
||||
There's certainly a better fix to be had. But any time you chose to build
|
||||
with a bare prefix like '/grub2', you're almost certainly going to build in
|
||||
search anyway, so this will do.
|
||||
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
---
|
||||
grub-core/kern/main.c | 27 +++++++++++++++++++++------
|
||||
1 file changed, 21 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index 993b8a8598..e94a2f78fb 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -242,14 +242,29 @@ grub_set_prefix_and_root (void)
|
||||
what sorts of paths represent disks with partition tables and those
|
||||
without partition tables.
|
||||
|
||||
- So we act unless there is a comma in the device, which would indicate
|
||||
- a partition has already been specified.
|
||||
+ - Frustratingly, the device name itself can contain an embedded comma:
|
||||
+ /pci@800000020000015/pci1014,034A@0/sas/disk@5000c50098a0ee8b
|
||||
+ So we cannot even rely upon the presence of a comma to say that a
|
||||
+ partition has been specified!
|
||||
|
||||
- (If we only have a path, the code in normal to discover config files
|
||||
- will try both without partitions and then with any partitions so we
|
||||
- will cover both CDs and HDs.)
|
||||
+ If we only have a path in $prefix, the code in normal to discover
|
||||
+ config files will try all disks, both without partitions and then with
|
||||
+ any partitions so we will cover both CDs and HDs.
|
||||
+
|
||||
+ However, it doesn't then set the prefix to be something like
|
||||
+ (discovered partition)/path, and so it is fragile against runtime
|
||||
+ changes to $root. For example some of the stuff done in 10_linux to
|
||||
+ reload $root sets root differently and then uses search to find it
|
||||
+ again. If the search module is not built in, when we change root, grub
|
||||
+ will look in (new root)/path/powerpc-ieee1275, that won't work, and we
|
||||
+ will not be able to load the search module and the boot will fail.
|
||||
+
|
||||
+ This is particularly likely to hit us in the grub-install
|
||||
+ (,msdos2)/grub2 case, so we act unless the supplied prefix starts with
|
||||
+ '(', which would likely indicate a partition has already been
|
||||
+ specified.
|
||||
*/
|
||||
- if (grub_strchr (device, ',') == NULL)
|
||||
+ if (prefix && prefix[0] != '(')
|
||||
grub_env_set ("prefix", path);
|
||||
else
|
||||
#endif
|
236
0217-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch
Normal file
236
0217-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch
Normal file
|
@ -0,0 +1,236 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Date: Sun, 15 Mar 2020 12:37:10 -0400
|
||||
Subject: [PATCH] ibmvtpm: Add support for trusted boot using a vTPM 2.0
|
||||
|
||||
Add support for trusted boot using a vTPM 2.0 on the IBM IEEE1275
|
||||
PowerPC platform. With this patch grub now measures text and binary data
|
||||
into the TPM's PCRs 8 and 9 in the same way as the x86_64 platform
|
||||
does.
|
||||
|
||||
This patch requires Daniel Axtens's patches for claiming more memory.
|
||||
|
||||
For vTPM support to work on PowerVM, system driver levels 1010.30
|
||||
or 1020.00 are required.
|
||||
|
||||
Note: Previous versions of firmware levels with the 2hash-ext-log
|
||||
API call have a bug that, once this API call is invoked, has the
|
||||
effect of disabling the vTPM driver under Linux causing an error
|
||||
message to be displayed in the Linux kernel log. Those users will
|
||||
have to update their machines to the firmware levels mentioned
|
||||
above.
|
||||
|
||||
Cc: Eric Snowberg <eric.snowberg@oracle.com>
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 7 ++
|
||||
grub-core/commands/ieee1275/ibmvtpm.c | 152 ++++++++++++++++++++++++++++++++++
|
||||
include/grub/ieee1275/ieee1275.h | 3 +
|
||||
docs/grub.texi | 3 +-
|
||||
4 files changed, 164 insertions(+), 1 deletion(-)
|
||||
create mode 100644 grub-core/commands/ieee1275/ibmvtpm.c
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 3c0ac3b7bd..2c1608bca4 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1175,6 +1175,13 @@ module = {
|
||||
enable = powerpc_ieee1275;
|
||||
};
|
||||
|
||||
+module = {
|
||||
+ name = tpm;
|
||||
+ common = commands/tpm.c;
|
||||
+ ieee1275 = commands/ieee1275/ibmvtpm.c;
|
||||
+ enable = powerpc_ieee1275;
|
||||
+};
|
||||
+
|
||||
module = {
|
||||
name = terminal;
|
||||
common = commands/terminal.c;
|
||||
diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
new file mode 100644
|
||||
index 0000000000..e68b8448bc
|
||||
--- /dev/null
|
||||
+++ b/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
@@ -0,0 +1,152 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ * Copyright (C) 2021 IBM Corporation
|
||||
+ *
|
||||
+ * 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/>.
|
||||
+ *
|
||||
+ * IBM vTPM support code.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/tpm.h>
|
||||
+#include <grub/ieee1275/ieee1275.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/misc.h>
|
||||
+
|
||||
+static grub_ieee1275_ihandle_t tpm_ihandle;
|
||||
+static grub_uint8_t tpm_version;
|
||||
+
|
||||
+#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t)0)
|
||||
+
|
||||
+static void
|
||||
+tpm_get_tpm_version (void)
|
||||
+{
|
||||
+ grub_ieee1275_phandle_t vtpm;
|
||||
+ char buffer[20];
|
||||
+
|
||||
+ if (!grub_ieee1275_finddevice ("/vdevice/vtpm", &vtpm) &&
|
||||
+ !grub_ieee1275_get_property (vtpm, "compatible", buffer,
|
||||
+ sizeof (buffer), NULL) &&
|
||||
+ !grub_strcmp (buffer, "IBM,vtpm20"))
|
||||
+ tpm_version = 2;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+tpm_init (void)
|
||||
+{
|
||||
+ static int init_success = 0;
|
||||
+
|
||||
+ if (!init_success)
|
||||
+ {
|
||||
+ if (grub_ieee1275_open ("/vdevice/vtpm", &tpm_ihandle) < 0) {
|
||||
+ tpm_ihandle = IEEE1275_IHANDLE_INVALID;
|
||||
+ return GRUB_ERR_UNKNOWN_DEVICE;
|
||||
+ }
|
||||
+
|
||||
+ init_success = 1;
|
||||
+
|
||||
+ tpm_get_tpm_version ();
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ibmvtpm_2hash_ext_log (grub_uint8_t pcrindex,
|
||||
+ grub_uint32_t eventtype,
|
||||
+ const char *description,
|
||||
+ grub_size_t description_size,
|
||||
+ void *buf, grub_size_t size)
|
||||
+{
|
||||
+ struct tpm_2hash_ext_log
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t method;
|
||||
+ grub_ieee1275_cell_t ihandle;
|
||||
+ grub_ieee1275_cell_t size;
|
||||
+ grub_ieee1275_cell_t buf;
|
||||
+ grub_ieee1275_cell_t description_size;
|
||||
+ grub_ieee1275_cell_t description;
|
||||
+ grub_ieee1275_cell_t eventtype;
|
||||
+ grub_ieee1275_cell_t pcrindex;
|
||||
+ grub_ieee1275_cell_t catch_result;
|
||||
+ grub_ieee1275_cell_t rc;
|
||||
+ }
|
||||
+ args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 2);
|
||||
+ args.method = (grub_ieee1275_cell_t) "2hash-ext-log";
|
||||
+ args.ihandle = tpm_ihandle;
|
||||
+ args.pcrindex = pcrindex;
|
||||
+ args.eventtype = eventtype;
|
||||
+ args.description = (grub_ieee1275_cell_t) description;
|
||||
+ args.description_size = description_size;
|
||||
+ args.buf = (grub_ieee1275_cell_t) buf;
|
||||
+ args.size = (grub_ieee1275_cell_t) size;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ /*
|
||||
+ * catch_result is set if firmware does not support 2hash-ext-log
|
||||
+ * rc is GRUB_IEEE1275_CELL_FALSE (0) on failure
|
||||
+ */
|
||||
+ if ((args.catch_result) || args.rc == GRUB_IEEE1275_CELL_FALSE)
|
||||
+ return -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+tpm2_log_event (unsigned char *buf,
|
||||
+ grub_size_t size, grub_uint8_t pcr,
|
||||
+ const char *description)
|
||||
+{
|
||||
+ static int error_displayed = 0;
|
||||
+ int err;
|
||||
+
|
||||
+ err = ibmvtpm_2hash_ext_log (pcr, EV_IPL,
|
||||
+ description,
|
||||
+ grub_strlen(description) + 1,
|
||||
+ buf, size);
|
||||
+ if (err && !error_displayed)
|
||||
+ {
|
||||
+ error_displayed++;
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ "2HASH-EXT-LOG failed: Firmware is likely too old.\n");
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||
+ const char *description)
|
||||
+{
|
||||
+ grub_err_t err = tpm_init();
|
||||
+
|
||||
+ /* Absence of a TPM isn't a failure. */
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n",
|
||||
+ pcr, size, description);
|
||||
+
|
||||
+ if (tpm_version == 2)
|
||||
+ return tpm2_log_event (buf, size, pcr, description);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
|
||||
index e0a6c2ce1e..f4c85265fe 100644
|
||||
--- a/include/grub/ieee1275/ieee1275.h
|
||||
+++ b/include/grub/ieee1275/ieee1275.h
|
||||
@@ -24,6 +24,9 @@
|
||||
#include <grub/types.h>
|
||||
#include <grub/machine/ieee1275.h>
|
||||
|
||||
+#define GRUB_IEEE1275_CELL_FALSE ((grub_ieee1275_cell_t) 0)
|
||||
+#define GRUB_IEEE1275_CELL_TRUE ((grub_ieee1275_cell_t) -1)
|
||||
+
|
||||
struct grub_ieee1275_mem_region
|
||||
{
|
||||
unsigned int start;
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index a4da9c2a1b..c433240f34 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -6221,7 +6221,8 @@ tpm module is loaded. As such it is recommended that the tpm module be built
|
||||
into @file{core.img} in order to avoid a potential gap in measurement between
|
||||
@file{core.img} being loaded and the tpm module being loaded.
|
||||
|
||||
-Measured boot is currently only supported on EFI platforms.
|
||||
+Measured boot is currently only supported on EFI and IBM IEEE1275 PowerPC
|
||||
+platforms.
|
||||
|
||||
@node Lockdown
|
||||
@section Lockdown when booting on a secure setup
|
|
@ -212,3 +212,6 @@ Patch0211: 0211-grub-core-loader-i386-efi-linux.c-do-not-validate-ke.patch
|
|||
Patch0212: 0212-grub-core-loader-arm64-linux.c-do-not-validate-kerne.patch
|
||||
Patch0213: 0213-grub-core-loader-efi-chainloader.c-do-not-validate-c.patch
|
||||
Patch0214: 0214-grub-core-loader-efi-linux.c-drop-now-unused-grub_li.patch
|
||||
Patch0215: 0215-powerpc-do-CAS-in-a-more-compatible-way.patch
|
||||
Patch0216: 0216-powerpc-prefix-detection-support-device-names-with-c.patch
|
||||
Patch0217: 0217-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
Name: grub2
|
||||
Epoch: 1
|
||||
Version: 2.06
|
||||
Release: 38%{?dist}
|
||||
Release: 39%{?dist}
|
||||
Summary: Bootloader with support for Linux, Multiboot and more
|
||||
License: GPLv3+
|
||||
URL: http://www.gnu.org/software/grub/
|
||||
|
@ -530,6 +530,9 @@ mv ${EFI_HOME}/grub.cfg.stb ${EFI_HOME}/grub.cfg
|
|||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed May 04 2022 Robbie Harwood <rharwood@redhat.com> - 1:2.06-39
|
||||
- ppc64le: CAS improvements, prefix detection, and vTPM support
|
||||
|
||||
* Tue Apr 19 2022 Dominik Mierzejewski <dominik@greysector.net> - 1:2.06-38
|
||||
- fix "grub2-mkrescue: error: `mformat` invocation failed"
|
||||
|
||||
|
|
Loading…
Reference in a new issue