From 61a62ea9894f41d9f6971db792870252042fc490693a056ea32577159c721d68 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Tue, 1 Nov 2022 04:59:50 +0000 Subject: [PATCH] Accepting request 1032365 from home:michael-chang:15sp5 - NVMeoFC support on grub (jsc#PED-996) * 0001-ieee1275-add-support-for-NVMeoFC.patch * 0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch * 0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch * 0004-ofpath-controller-name-update.patch - TDX: Enhance grub2 measurement to TD RTMR (jsc#PED-1265) * 0001-commands-efi-tpm-Refine-the-status-of-log-event.patch * 0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch * 0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch - Measure the kernel on POWER10 and extend TPM PCRs (PED-1990) * 0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch * 0002-ieee1275-implement-vec5-for-cas-negotiation.patch - Fix efi pcr snapshot related funtion is defined but not used on powerpc platform. * safe_tpm_pcr_snapshot.patch OBS-URL: https://build.opensuse.org/request/show/1032365 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=424 --- ...i-tpm-Refine-the-status-of-log-event.patch | 39 ++ ...ort-for-trusted-boot-using-a-vTPM-2..patch | 239 +++++++++++ 0001-ieee1275-add-support-for-NVMeoFC.patch | 250 ++++++++++++ ...-Use-grub_strcpy-instead-of-grub_mem.patch | 40 ++ ...5-implement-vec5-for-cas-negotiation.patch | 73 ++++ ...enable-NVMeoF-logical-device-transla.patch | 373 ++++++++++++++++++ ...-EFI_CC_MEASUREMENT_PROTOCOL-support.patch | 260 ++++++++++++ ...ge-the-logic-of-ieee1275_get_devargs.patch | 62 +++ 0004-ofpath-controller-name-update.patch | 28 ++ grub2.changes | 19 + grub2.spec | 12 + safe_tpm_pcr_snapshot.patch | 58 ++- 12 files changed, 1442 insertions(+), 11 deletions(-) create mode 100644 0001-commands-efi-tpm-Refine-the-status-of-log-event.patch create mode 100644 0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch create mode 100644 0001-ieee1275-add-support-for-NVMeoFC.patch create mode 100644 0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch create mode 100644 0002-ieee1275-implement-vec5-for-cas-negotiation.patch create mode 100644 0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch create mode 100644 0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch create mode 100644 0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch create mode 100644 0004-ofpath-controller-name-update.patch diff --git a/0001-commands-efi-tpm-Refine-the-status-of-log-event.patch b/0001-commands-efi-tpm-Refine-the-status-of-log-event.patch new file mode 100644 index 0000000..c284274 --- /dev/null +++ b/0001-commands-efi-tpm-Refine-the-status-of-log-event.patch @@ -0,0 +1,39 @@ +From d2c0426b3f0f91b941037263c83859a46ebb0c4f Mon Sep 17 00:00:00 2001 +From: Lu Ken +Date: Wed, 13 Jul 2022 10:06:10 +0800 +Subject: [PATCH 1/3] commands/efi/tpm: Refine the status of log event + +1. Use macro GRUB_ERR_NONE instead of hard code 0. +2. Keep lowercase of the first char for the status string of log event. + +Signed-off-by: Lu Ken +Reviewed-by: Daniel Kiper +--- + grub-core/commands/efi/tpm.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c +index f296b8698..19737b462 100644 +--- a/grub-core/commands/efi/tpm.c ++++ b/grub-core/commands/efi/tpm.c +@@ -136,13 +136,13 @@ grub_efi_log_event_status (grub_efi_status_t status) + switch (status) + { + case GRUB_EFI_SUCCESS: +- return 0; ++ return GRUB_ERR_NONE; + case GRUB_EFI_DEVICE_ERROR: +- return grub_error (GRUB_ERR_IO, N_("Command failed")); ++ return grub_error (GRUB_ERR_IO, N_("command failed")); + case GRUB_EFI_INVALID_PARAMETER: +- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid parameter")); + case GRUB_EFI_BUFFER_TOO_SMALL: +- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("output buffer too small")); + case GRUB_EFI_NOT_FOUND: + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); + default: +-- +2.35.3 + diff --git a/0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch b/0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch new file mode 100644 index 0000000..f3f26ea --- /dev/null +++ b/0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch @@ -0,0 +1,239 @@ +From f86bd28391e6d92f8084f0b789ba4a8f6d789dfa Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Sun, 15 Mar 2020 12:37:10 -0400 +Subject: [PATCH 1/2] 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 +Signed-off-by: Stefan Berger +--- + docs/grub.texi | 3 +- + grub-core/Makefile.core.def | 7 ++ + grub-core/commands/ieee1275/ibmvtpm.c | 152 ++++++++++++++++++++++++++ + include/grub/ieee1275/ieee1275.h | 3 + + 4 files changed, 164 insertions(+), 1 deletion(-) + create mode 100644 grub-core/commands/ieee1275/ibmvtpm.c + +diff --git a/docs/grub.texi b/docs/grub.texi +index 4504bcabe..026aacacf 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -6204,7 +6204,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 +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index cee596872..54733425c 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1141,6 +1141,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 000000000..e68b8448b +--- /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 . ++ * ++ * IBM vTPM support code. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 591f4f12c..8a621af7c 100644 +--- a/include/grub/ieee1275/ieee1275.h ++++ b/include/grub/ieee1275/ieee1275.h +@@ -24,6 +24,9 @@ + #include + #include + ++#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; +-- +2.35.3 + diff --git a/0001-ieee1275-add-support-for-NVMeoFC.patch b/0001-ieee1275-add-support-for-NVMeoFC.patch new file mode 100644 index 0000000..f9cbc98 --- /dev/null +++ b/0001-ieee1275-add-support-for-NVMeoFC.patch @@ -0,0 +1,250 @@ +From c125cb45a7885d7bf168a05cfa4da3e681244649 Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Tue, 15 Feb 2022 13:11:48 -0500 +Subject: [PATCH 1/4] ieee1275: add support for NVMeoFC + +Implements the functions to scan and discovery of NVMeoFC. +--- + grub-core/disk/ieee1275/ofdisk.c | 217 ++++++++++++++++++++++++++++++- + 1 file changed, 213 insertions(+), 4 deletions(-) + +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c +index 410f4b849..852bb95be 100644 +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -206,12 +206,10 @@ dev_iterate_real (const char *name, const char *path) + return; + } + ++ + static void +-dev_iterate (const struct grub_ieee1275_devalias *alias) ++dev_iterate_fcp_disks(const struct grub_ieee1275_devalias *alias) + { +- if (grub_strcmp (alias->type, "fcp") == 0) +- { +- + /* If we are dealing with fcp devices, we need + * to find the WWPNs and LUNs to iterate them */ + grub_ieee1275_ihandle_t ihandle; +@@ -323,6 +321,217 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) + grub_free (buf); + return; + ++} ++ ++static void ++dev_iterate_fcp_nvmeof (const struct grub_ieee1275_devalias *alias) ++{ ++ ++ ++ char *bufptr; ++ grub_ieee1275_ihandle_t ihandle; ++ ++ ++ // Create the structs for the parameters passing to PFW ++ struct nvme_args_ ++ { ++ struct grub_ieee1275_common_hdr common; ++ grub_ieee1275_cell_t method; ++ grub_ieee1275_cell_t ihandle; ++ grub_ieee1275_cell_t catch_result; ++ grub_ieee1275_cell_t nentries; ++ grub_ieee1275_cell_t table; ++ } nvme_discovery_controllers_args, nvme_controllers_args, nvme_namespaces_args; ++ ++ ++ // Create the structs for the results from PFW ++ ++ struct discovery_controllers_table_struct_ ++ { ++ grub_uint64_t table[256]; ++ grub_uint32_t len; ++ } discovery_controllers_table; ++ ++ /* struct nvme_controllers_table_entry ++ * this the return of nvme-controllers method tables, containing: ++ * - 2-byte controller ID ++ * - 256-byte transport address string ++ * - 256-byte field containing null-terminated NVM subsystem NQN string up to 223 characters ++ */ ++ struct nvme_controllers_table_entry_ ++ { ++ grub_uint16_t id; ++ char wwpn[256]; ++ char nqn[256]; ++ }; ++ ++ struct nvme_controllers_table_entry_* nvme_controllers_table = grub_malloc(sizeof(struct nvme_controllers_table_entry_)*256); ++ ++ grub_uint32_t nvme_controllers_table_entries; ++ ++ struct nvme_controllers_table_entry_real ++ { ++ grub_uint16_t id; ++ char wwpn[256]; ++ char nqn[256]; ++ }; ++ ++ /* Allocate memory for building the NVMeoF path */ ++ char *buf = grub_malloc (grub_strlen (alias->path) + 512); ++ if (!buf) ++ { ++ grub_ieee1275_close(ihandle); ++ return; ++ } ++ ++ /* Copy the alias->path to buf so we can work with */ ++ bufptr = grub_stpcpy (buf, alias->path); ++ grub_snprintf (bufptr, 32, "/nvme-of"); ++ ++ /* ++ * Open the nvme-of layer ++ * Ex. /pci@bus/fibre-channel@@dev,func/nvme-of ++ */ ++ if(grub_ieee1275_open (buf, &ihandle)) ++ { ++ grub_dprintf("disk", "failed to open the disk while iterating FCP disk path=%s\n", buf); ++ return; ++ } ++ ++ /* ++ * Call to nvme-discovery-controllers method from the nvme-of layer ++ * to get a list of the NVMe discovery controllers per the binding ++ */ ++ ++ INIT_IEEE1275_COMMON (&nvme_discovery_controllers_args.common, "call-method", 2, 2); ++ nvme_discovery_controllers_args.method = (grub_ieee1275_cell_t) "nvme-discovery-controllers"; ++ nvme_discovery_controllers_args.ihandle = ihandle; ++ ++ if (IEEE1275_CALL_ENTRY_FN (&nvme_discovery_controllers_args) == -1) ++ { ++ grub_dprintf("disk", "failed to get the targets while iterating FCP disk path=%s\n", buf); ++ grub_ieee1275_close(ihandle); ++ return; ++ } ++ ++ /* After closing the device, the info is lost. So lets copy each buffer in the buffers table */ ++ ++ discovery_controllers_table.len = (grub_uint32_t) nvme_discovery_controllers_args.nentries; ++ ++ unsigned int i=0; ++ for(i = 0; i < discovery_controllers_table.len; i++){ ++ discovery_controllers_table.table[i] = ((grub_uint64_t*)nvme_discovery_controllers_args.table)[i]; ++ } ++ ++ grub_ieee1275_close(ihandle); ++ ++ grub_dprintf("ofdisk","NVMeoF: Found %d discovery controllers\n",discovery_controllers_table.len); ++ ++ /* For each nvme discovery controller */ ++ int current_buffer_index; ++ for(current_buffer_index = 0; current_buffer_index < (int) discovery_controllers_table.len; current_buffer_index++){ ++ ++ ++ grub_snprintf (bufptr, 64, "/nvme-of/controller@%" PRIxGRUB_UINT64_T ",ffff", ++ discovery_controllers_table.table[current_buffer_index]); ++ ++ grub_dprintf("ofdisk","nvmeof controller=%s\n",buf); ++ ++ if(grub_ieee1275_open (buf, &ihandle)) ++ { ++ grub_dprintf("ofdisk", "failed to open the disk while getting nvme-controllers path=%s\n", buf); ++ continue; ++ } ++ ++ ++ INIT_IEEE1275_COMMON (&nvme_controllers_args.common, "call-method", 2, 2); ++ nvme_controllers_args.method = (grub_ieee1275_cell_t) "nvme-controllers"; ++ nvme_controllers_args.ihandle = ihandle; ++ nvme_controllers_args.catch_result = 0; ++ ++ ++ if (IEEE1275_CALL_ENTRY_FN (&nvme_controllers_args) == -1) ++ { ++ grub_dprintf("ofdisk", "failed to get the nvme-controllers while iterating FCP disk path\n"); ++ grub_ieee1275_close(ihandle); ++ continue; ++ } ++ ++ ++ /* Copy the buffer list to nvme_controllers_table */ ++ nvme_controllers_table_entries = ((grub_uint32_t) nvme_controllers_args.nentries); ++ struct nvme_controllers_table_entry_* nvme_controllers_table_ = (struct nvme_controllers_table_entry_*) nvme_controllers_args.table; ++ ++ for(i = 0; i < nvme_controllers_table_entries; i++){ ++ nvme_controllers_table[i].id = (grub_uint16_t) nvme_controllers_table_[i].id; ++ grub_strcpy(nvme_controllers_table[i].wwpn, nvme_controllers_table_[i].wwpn); ++ grub_strcpy(nvme_controllers_table[i].nqn, nvme_controllers_table_[i].nqn); ++ } ++ ++ grub_ieee1275_close(ihandle); ++ ++ int nvme_controller_index; ++ int bufptr_pos2; ++ grub_dprintf("ofdisk","NVMeoF: found %d nvme controllers\n",(int) nvme_controllers_args.nentries); ++ ++ /* For each nvme controller */ ++ for(nvme_controller_index = 0; nvme_controller_index < (int) nvme_controllers_args.nentries; nvme_controller_index++){ ++ /* Open the nvme controller ++ * /pci@bus/fibre-channel@dev,func/nvme-of/controller@transport-addr,ctlr-id:nqn=tgt-subsystem-nqn ++ */ ++ ++ bufptr_pos2 = grub_snprintf (bufptr, 512, "/nvme-of/controller@%s,ffff:nqn=%s", ++ nvme_controllers_table[nvme_controller_index].wwpn, nvme_controllers_table[nvme_controller_index].nqn); ++ ++ grub_dprintf("ofdisk","NVMeoF: nvmeof controller=%s\n",buf); ++ ++ if(grub_ieee1275_open (buf, &ihandle)){ ++ grub_dprintf("ofdisk","failed to open the path=%s\n",buf); ++ continue; ++ } ++ ++ INIT_IEEE1275_COMMON (&nvme_namespaces_args.common, "call-method", 2, 2); ++ nvme_namespaces_args.method = (grub_ieee1275_cell_t) "get-namespace-list"; ++ nvme_namespaces_args.ihandle = ihandle; ++ nvme_namespaces_args.catch_result = 0; ++ ++ if (IEEE1275_CALL_ENTRY_FN (&nvme_namespaces_args) == -1) ++ { ++ grub_dprintf("ofdisk", "failed to get the nvme-namespace-list while iterating FCP disk path\n"); ++ grub_ieee1275_close(ihandle); ++ continue; ++ } ++ ++ grub_uint32_t *namespaces = (grub_uint32_t*) nvme_namespaces_args.table; ++ grub_dprintf("ofdisk","NVMeoF: found %d namespaces\n",(int)nvme_namespaces_args.nentries); ++ ++ grub_ieee1275_close(ihandle); ++ ++ grub_uint32_t namespace_index = 0; ++ for(namespace_index=0; namespace_index < nvme_namespaces_args.nentries; namespace_index++){ ++ grub_snprintf (bufptr+bufptr_pos2, 512, "/namespace@%"PRIxGRUB_UINT32_T,namespaces[namespace_index]); ++ grub_dprintf("ofdisk","NVMeoF: namespace=%s\n",buf); ++ dev_iterate_real(buf,buf); ++ } ++ ++ dev_iterate_real(buf,buf); ++ } ++ } ++ grub_free(buf); ++ return; ++} ++ ++static void ++dev_iterate (const struct grub_ieee1275_devalias *alias) ++{ ++ if (grub_strcmp (alias->type, "fcp") == 0) ++ { ++ // Iterate disks ++ dev_iterate_fcp_disks(alias); ++ ++ // Iterate NVMeoF ++ dev_iterate_fcp_nvmeof(alias); ++ + } + else if (grub_strcmp (alias->type, "vscsi") == 0) + { +-- +2.35.3 + diff --git a/0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch b/0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch new file mode 100644 index 0000000..77b5555 --- /dev/null +++ b/0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch @@ -0,0 +1,40 @@ +From 1f41f020f73131574cd7aee4e0e09d4c56277d1e Mon Sep 17 00:00:00 2001 +From: Lu Ken +Date: Wed, 13 Jul 2022 10:06:11 +0800 +Subject: [PATCH 2/3] commands/efi/tpm: Use grub_strcpy() instead of + grub_memcpy() + +The event description is a string, so using grub_strcpy() is cleaner than +using grub_memcpy(). + +Signed-off-by: Lu Ken +Reviewed-by: Daniel Kiper +--- + grub-core/commands/efi/tpm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c +index 19737b462..e032617d8 100644 +--- a/grub-core/commands/efi/tpm.c ++++ b/grub-core/commands/efi/tpm.c +@@ -177,7 +177,7 @@ grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, + event->PCRIndex = pcr; + event->EventType = EV_IPL; + event->EventSize = grub_strlen (description) + 1; +- grub_memcpy (event->Event, description, event->EventSize); ++ grub_strcpy ((char *) event->Event, description); + + algorithm = TCG_ALG_SHA; + status = efi_call_7 (tpm->log_extend_event, tpm, (grub_addr_t) buf, (grub_uint64_t) size, +@@ -299,7 +299,7 @@ grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, + event->Header.EventType = EV_IPL; + event->Size = + sizeof (*event) - sizeof (event->Event) + grub_strlen (description) + 1; +- grub_memcpy (event->Event, description, grub_strlen (description) + 1); ++ grub_strcpy ((char *) event->Event, description); + + status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, (grub_addr_t) buf, + (grub_uint64_t) size, event); +-- +2.35.3 + diff --git a/0002-ieee1275-implement-vec5-for-cas-negotiation.patch b/0002-ieee1275-implement-vec5-for-cas-negotiation.patch new file mode 100644 index 0000000..27e05ab --- /dev/null +++ b/0002-ieee1275-implement-vec5-for-cas-negotiation.patch @@ -0,0 +1,73 @@ +From 6c7c4007ad621029295797b439158d36d0f62487 Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Thu, 25 Aug 2022 11:37:56 -0400 +Subject: [PATCH 2/2] ieee1275: implement vec5 for cas negotiation + +As a legacy support, if the vector 5 is not implemented, Power +Hypervisor will consider the max CPUs as 64 instead 256 currently +supported during client-architecture-support negotiation. + +This patch implements the vector 5 and set the MAX CPUs to 256 while +setting the others values to 0 (default). + +Signed-off-by: Diego Domingos +Signed-off-by: Robbie Harwood +--- + grub-core/kern/ieee1275/init.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index 7d7178d3e..3aa40313f 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -311,6 +311,18 @@ struct option_vector2 { + grub_uint8_t max_pft_size; + } __attribute__((packed)); + ++struct option_vector5 { ++ grub_uint8_t byte1; ++ grub_uint8_t byte2; ++ grub_uint8_t byte3; ++ grub_uint8_t cmo; ++ grub_uint8_t associativity; ++ grub_uint8_t bin_opts; ++ grub_uint8_t micro_checkpoint; ++ grub_uint8_t reserved0; ++ grub_uint32_t max_cpus; ++} __attribute__((packed)); ++ + struct pvr_entry { + grub_uint32_t mask; + grub_uint32_t entry; +@@ -329,6 +341,8 @@ struct cas_vector { + grub_uint16_t vec3; + grub_uint8_t vec4_size; + grub_uint16_t vec4; ++ grub_uint8_t vec5_size; ++ struct option_vector5 vec5; + } __attribute__((packed)); + + /* Call ibm,client-architecture-support to try to get more RMA. +@@ -349,7 +363,7 @@ grub_ieee1275_ibm_cas (void) + } args; + struct cas_vector vector = { + .pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */ +- .num_vecs = 4 - 1, ++ .num_vecs = 5 - 1, + .vec1_size = 0, + .vec1 = 0x80, /* ignore */ + .vec2_size = 1 + sizeof(struct option_vector2) - 2, +@@ -360,6 +374,10 @@ grub_ieee1275_ibm_cas (void) + .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 ++ .vec5_size = 1 + sizeof(struct option_vector5) - 2, ++ .vec5 = { ++ 0, 0, 0, 0, 0, 0, 0, 0, 256 ++ } + }; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2); +-- +2.35.3 + diff --git a/0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch b/0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch new file mode 100644 index 0000000..19a1527 --- /dev/null +++ b/0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch @@ -0,0 +1,373 @@ +From 9e61624db77e5073961126457f599bc70e877fd1 Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Tue, 15 Mar 2022 15:59:41 -0400 +Subject: [PATCH 2/4] ieee1275/ofpath: enable NVMeoF logical device translation + +This patch add code to enable the translation of logical devices to the of NVMeoFC paths. +--- + grub-core/osdep/linux/ofpath.c | 260 +++++++++++++++++++++++++++++++-- + include/grub/util/ofpath.h | 29 ++++ + 2 files changed, 280 insertions(+), 9 deletions(-) + +diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c +index 89beceef4..212782d3f 100644 +--- a/grub-core/osdep/linux/ofpath.c ++++ b/grub-core/osdep/linux/ofpath.c +@@ -137,7 +137,7 @@ trim_newline (char *path) + *end-- = '\0'; + } + +-#define MAX_DISK_CAT 64 ++#define MAX_DISK_CAT 512 + + static char * + find_obppath (const char *sysfs_path_orig) +@@ -313,6 +313,69 @@ get_basename(char *p) + return ret; + } + ++ ++void ++add_filename_to_pile(char *filename, struct ofpath_files_list_root* root){ ++ struct ofpath_files_list_node* file; ++ ++ file = malloc(sizeof(struct ofpath_files_list_node)); ++ ++ file->filename = filename; ++ ++ if(root->first == NULL){ ++ root->items = 1; ++ root->first = file; ++ file->next = NULL; ++ } else { ++ root->items++; ++ file->next = root->first; ++ root->first = file; ++ } ++} ++ ++ ++void ++find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth){ ++ struct dirent *ep; ++ struct stat statbuf; ++ DIR *dp; ++ ++ if(depth > max_depth){ ++ return; ++ } ++ ++ if((dp = opendir(directory)) == NULL){ ++ ++ return; ++ } ++ ++ while((ep = readdir(dp)) != NULL){ ++ ++ char* full_path = malloc(1024*sizeof(char)); ++ snprintf(full_path,1024,"%s/%s",directory,ep->d_name); ++ ++ lstat(full_path,&statbuf); ++ ++ if(S_ISLNK(statbuf.st_mode)){ ++ ++ continue; ++ } ++ ++ if(!strcmp(ep->d_name,".") || !strcmp(ep->d_name,"..")){ ++ continue; ++ } ++ ++ if(!strcmp(ep->d_name,filename)){ ++ add_filename_to_pile(full_path, root); ++ } ++ ++ find_file(filename, full_path, root, max_depth, depth+1); ++ ++ } ++ closedir(dp); ++} ++ ++ + static char * + of_path_of_vdisk(const char *sys_devname __attribute__((unused)), + const char *device, +@@ -351,7 +414,142 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi + return ret; + } + +-#ifdef __sparc__ ++char* ++of_find_fc_host(char* host_wwpn){ ++ ++ FILE* fp; ++ char *buf; ++ char portname_filename[sizeof("port_name")] = "port_name"; ++ char devices_path[sizeof("/sys/devices")] = "/sys/devices"; ++ ++ struct ofpath_files_list_root* portnames_file_list; ++ ++ portnames_file_list=malloc(sizeof(portnames_file_list)); ++ portnames_file_list->items=0; ++ portnames_file_list->first=NULL; ++ ++ find_file(portname_filename, devices_path, portnames_file_list, 10, 0); ++ ++ struct ofpath_files_list_node* node = portnames_file_list->first; ++ while(node != NULL){ ++ fp = fopen(node->filename,"r"); ++ buf = malloc(sizeof(char)*512); ++ fscanf(fp, "%s", buf); ++ fclose(fp); ++ if((strcmp(buf,host_wwpn) == 0) && grub_strstr(node->filename, "fc_host")){ ++ return node->filename; ++ } ++ node = node->next; ++ } ++ ++ return NULL; ++} ++ ++void ++of_path_get_nvmeof_adapter_info(char* sysfs_path, ++ struct ofpath_nvmeof_info* nvmeof_info){ ++ ++ FILE *fp; ++ char *buf, *buf2, *buf3; ++ ++ nvmeof_info->host_wwpn = malloc(sizeof(char)*256); ++ nvmeof_info->target_wwpn = malloc(sizeof(char)*256); ++ nvmeof_info->nqn = malloc(sizeof(char)*256); ++ ++ buf = malloc(sizeof(char)*512); ++ snprintf(buf,512,"%s/subsysnqn",sysfs_path); ++ fp = fopen(buf,"r"); ++ fscanf(fp, "%s", nvmeof_info->nqn); ++ fclose(fp); ++ ++ snprintf(buf,512,"%s/cntlid",sysfs_path); ++ fp = fopen(buf,"r"); ++ fscanf(fp, "%u", &(nvmeof_info->cntlid)); ++ fclose(fp); ++ ++ //snprintf(buf,512,"%s/nsid",sysfs_path); ++ //fp = fopen(buf,"r"); ++ //fscanf(fp, "%u", &(nvmeof_info->nsid)); ++ //fclose(fp); ++ ++ snprintf(buf,512,"%s/address",sysfs_path); ++ fp = fopen(buf,"r"); ++ buf2 = malloc(sizeof(char)*512); ++ fscanf(fp, "%s", buf2); ++ fclose(fp); ++ ++ nvmeof_info->host_wwpn = strrchr(buf2,'-')+1; ++ ++ buf3=strchr(buf2,'-')+1; ++ buf3=strchr(buf3,'-')+1; ++ nvmeof_info->target_wwpn = buf3; ++ buf3 = strchr(nvmeof_info->target_wwpn,','); ++ *buf3 = '\0'; ++ ++ ++ free(buf); ++ ++ return; ++} ++ ++#define MAX_NVME_NSID_DIGITS 6 ++ ++static char * ++of_path_get_nvme_controller_name_node(const char* devname) ++{ ++ char *controller_node, *end; ++ ++ controller_node = strdup(devname); ++ ++ end = grub_strchr(controller_node+1, 'n'); ++ ++ if(end != NULL){ ++ *end = '\0'; ++ } ++ ++ return controller_node; ++} ++ ++unsigned int ++of_path_get_nvme_nsid(const char* devname) ++{ ++ unsigned int nsid; ++ char *sysfs_path, *buf; ++ FILE *fp; ++ ++ buf=malloc(sizeof(char)*512); ++ ++ sysfs_path = block_device_get_sysfs_path_and_link (devname); ++ ++ snprintf(buf,512,"%s/%s/nsid",sysfs_path,devname); ++ fp = fopen(buf,"r"); ++ fscanf(fp, "%u", &(nsid)); ++ fclose(fp); ++ ++ free(sysfs_path); ++ free(buf); ++ ++ return nsid; ++ ++} ++ ++static char * ++nvme_get_syspath(const char *nvmedev) ++{ ++ char *sysfs_path, *controller_node; ++ sysfs_path = block_device_get_sysfs_path_and_link (nvmedev); ++ ++ if(strstr(sysfs_path,"nvme-subsystem")){ ++ controller_node = of_path_get_nvme_controller_name_node(nvmedev); ++ strcat(sysfs_path,"/"); ++ strcat(sysfs_path,controller_node); ++ sysfs_path = xrealpath(sysfs_path); ++ } ++ ++ return sysfs_path; ++} ++ ++ + static char * + of_path_of_nvme(const char *sys_devname __attribute__((unused)), + const char *device, +@@ -360,6 +558,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)), + { + char *sysfs_path, *of_path, disk[MAX_DISK_CAT]; + const char *digit_string, *part_end; ++ int chars_written; + + digit_string = trailing_digits (device); + part_end = devicenode + strlen (devicenode) - 1; +@@ -379,15 +578,61 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)), + /* Remove the p. */ + *end = '\0'; + sscanf (digit_string, "%d", &part); +- snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1)); +- sysfs_path = block_device_get_sysfs_path_and_link (nvmedev); ++ ++ sysfs_path = nvme_get_syspath(nvmedev); ++ ++ /* If is a NVMeoF */ ++ if(strstr(sysfs_path,"nvme-fabrics")){ ++ struct ofpath_nvmeof_info* nvmeof_info; ++ nvmeof_info = malloc(sizeof(nvmeof_info)); ++ ++ of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info); ++ ++ sysfs_path = of_find_fc_host(nvmeof_info->host_wwpn); ++ ++ chars_written = snprintf(disk,sizeof(disk),"/nvme-of/controller@%s,%x:nqn=%s", ++ nvmeof_info->target_wwpn, ++ 0xffff, ++ nvmeof_info->nqn); ++ ++ unsigned int nsid = of_path_get_nvme_nsid(nvmedev); ++ ++ if(nsid){ ++ snprintf(disk+chars_written,sizeof(disk) - chars_written, ++ "/namespace@%x:%d",nsid, part); ++ } ++ ++ } else { ++ snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1)); ++ } + free (nvmedev); + } + else + { + /* We do not have the parition. */ +- snprintf (disk, sizeof (disk), "/disk@1"); +- sysfs_path = block_device_get_sysfs_path_and_link (device); ++ sysfs_path = nvme_get_syspath (device); ++ if(strstr(sysfs_path,"nvme-fabrics")){ ++ struct ofpath_nvmeof_info* nvmeof_info; ++ nvmeof_info = malloc(sizeof(nvmeof_info)); ++ ++ of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info); ++ ++ sysfs_path = of_find_fc_host(nvmeof_info->host_wwpn); ++ ++ chars_written = snprintf(disk,sizeof(disk),"/nvme-of/controller@%s,%x:nqn=%s", ++ nvmeof_info->target_wwpn, ++ 0xffff, ++ nvmeof_info->nqn); ++ ++ unsigned int nsid = of_path_get_nvme_nsid(device); ++ if(nsid){ ++ snprintf(disk+chars_written,sizeof(disk) - chars_written, ++ "/namespace@%x",nsid); ++ } ++ } else { ++ snprintf (disk, sizeof (disk), "/disk@1"); ++ } ++ + } + + of_path = find_obppath (sysfs_path); +@@ -398,7 +643,6 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)), + free (sysfs_path); + return of_path; + } +-#endif + + static void + of_fc_port_name(const char *path, const char *subpath, char *port_name) +@@ -840,11 +1084,9 @@ grub_util_devname_to_ofpath (const char *sys_devname) + /* All the models I've seen have a devalias "floppy". + New models have no floppy at all. */ + ofpath = xstrdup ("floppy"); +-#ifdef __sparc__ + else if (device[0] == 'n' && device[1] == 'v' && device[2] == 'm' + && device[3] == 'e') + ofpath = of_path_of_nvme (name_buf, device, devnode, devicenode); +-#endif + else + { + grub_util_warn (_("unknown device type %s"), device); +diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h +index b43c523cb..a0ec30620 100644 +--- a/include/grub/util/ofpath.h ++++ b/include/grub/util/ofpath.h +@@ -3,4 +3,33 @@ + + char *grub_util_devname_to_ofpath (const char *devname); + ++struct ofpath_files_list_node { ++ char* filename; ++ struct ofpath_files_list_node* next; ++}; ++ ++struct ofpath_files_list_root { ++ int items; ++ struct ofpath_files_list_node* first; ++}; ++ ++struct ofpath_nvmeof_info { ++ char* host_wwpn; ++ char* target_wwpn; ++ char* nqn; ++ int cntlid; ++ int nsid; ++}; ++ ++void of_path_get_nvmeof_adapter_info(char* sysfs_path, ++ struct ofpath_nvmeof_info* nvmeof_info); ++ ++unsigned int of_path_get_nvme_nsid(const char* devname); ++ ++void add_filename_to_pile(char *filename, struct ofpath_files_list_root* root); ++ ++void find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth); ++ ++char* of_find_fc_host(char* host_wwpn); ++ + #endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */ +-- +2.35.3 + diff --git a/0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch b/0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch new file mode 100644 index 0000000..ffe842f --- /dev/null +++ b/0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch @@ -0,0 +1,260 @@ +From 029c952f37dedb086c85bfb5fbc0de15cd4dbf0f Mon Sep 17 00:00:00 2001 +From: Lu Ken +Date: Wed, 13 Jul 2022 10:06:12 +0800 +Subject: [PATCH 3/3] efi/tpm: Add EFI_CC_MEASUREMENT_PROTOCOL support + +The EFI_CC_MEASUREMENT_PROTOCOL abstracts the measurement for virtual firmware +in confidential computing environment. It is similar to the EFI_TCG2_PROTOCOL. +It was proposed by Intel and ARM and approved by UEFI organization. + +It is defined in Intel GHCI specification: https://cdrdv2.intel.com/v1/dl/getContent/726790 . +The EDKII header file is available at https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Protocol/CcMeasurement.h . + +Signed-off-by: Lu Ken +Reviewed-by: Daniel Kiper +--- + grub-core/commands/efi/tpm.c | 48 +++++++++++ + include/grub/efi/cc.h | 151 +++++++++++++++++++++++++++++++++++ + 2 files changed, 199 insertions(+) + create mode 100644 include/grub/efi/cc.h + +diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c +index e032617d8..630fd8a82 100644 +--- a/grub-core/commands/efi/tpm.c ++++ b/grub-core/commands/efi/tpm.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -32,6 +33,7 @@ typedef TCG_PCR_EVENT grub_tpm_event_t; + + static grub_efi_guid_t tpm_guid = EFI_TPM_GUID; + static grub_efi_guid_t tpm2_guid = EFI_TPM2_GUID; ++static grub_efi_guid_t cc_measurement_guid = GRUB_EFI_CC_MEASUREMENT_PROTOCOL_GUID; + + static grub_efi_handle_t *grub_tpm_handle; + static grub_uint8_t grub_tpm_version; +@@ -308,6 +310,50 @@ grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, + return grub_efi_log_event_status (status); + } + ++static void ++grub_cc_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, ++ const char *description) ++{ ++ grub_efi_cc_event_t *event; ++ grub_efi_status_t status; ++ grub_efi_cc_protocol_t *cc; ++ grub_efi_cc_mr_index_t mr; ++ ++ cc = grub_efi_locate_protocol (&cc_measurement_guid, NULL); ++ if (cc == NULL) ++ return; ++ ++ status = efi_call_3 (cc->map_pcr_to_mr_index, cc, pcr, &mr); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ grub_efi_log_event_status (status); ++ return; ++ } ++ ++ event = grub_zalloc (sizeof (grub_efi_cc_event_t) + ++ grub_strlen (description) + 1); ++ if (event == NULL) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate CC event buffer")); ++ return; ++ } ++ ++ event->Header.HeaderSize = sizeof (grub_efi_cc_event_header_t); ++ event->Header.HeaderVersion = GRUB_EFI_CC_EVENT_HEADER_VERSION; ++ event->Header.MrIndex = mr; ++ event->Header.EventType = EV_IPL; ++ event->Size = sizeof (*event) + grub_strlen (description) + 1; ++ grub_strcpy ((char *) event->Event, description); ++ ++ status = efi_call_5 (cc->hash_log_extend_event, cc, 0, ++ (grub_efi_physical_address_t)(grub_addr_t) buf, ++ (grub_efi_uint64_t) size, event); ++ grub_free (event); ++ ++ if (status != GRUB_EFI_SUCCESS) ++ grub_efi_log_event_status (status); ++} ++ + grub_err_t + grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, + const char *description) +@@ -315,6 +361,8 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, + grub_efi_handle_t tpm_handle; + grub_efi_uint8_t protocol_version; + ++ grub_cc_log_event(buf, size, pcr, description); ++ + if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) + return 0; + +diff --git a/include/grub/efi/cc.h b/include/grub/efi/cc.h +new file mode 100644 +index 000000000..896030689 +--- /dev/null ++++ b/include/grub/efi/cc.h +@@ -0,0 +1,151 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 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 . ++ */ ++ ++#ifndef GRUB_EFI_CC_H ++#define GRUB_EFI_CC_H 1 ++ ++#include ++#include ++#include ++ ++#define GRUB_EFI_CC_MEASUREMENT_PROTOCOL_GUID \ ++ { 0x96751a3d, 0x72f4, 0x41a6, \ ++ { 0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b } \ ++ }; ++ ++struct grub_efi_cc_version ++{ ++ grub_efi_uint8_t Major; ++ grub_efi_uint8_t Minor; ++}; ++typedef struct grub_efi_cc_version grub_efi_cc_version_t; ++ ++/* EFI_CC Type/SubType definition. */ ++#define GRUB_EFI_CC_TYPE_NONE 0 ++#define GRUB_EFI_CC_TYPE_SEV 1 ++#define GRUB_EFI_CC_TYPE_TDX 2 ++ ++struct grub_efi_cc_type ++{ ++ grub_efi_uint8_t Type; ++ grub_efi_uint8_t SubType; ++}; ++typedef struct grub_efi_cc_type grub_efi_cc_type_t; ++ ++typedef grub_efi_uint32_t grub_efi_cc_event_log_bitmap_t; ++typedef grub_efi_uint32_t grub_efi_cc_event_log_format_t; ++typedef grub_efi_uint32_t grub_efi_cc_event_algorithm_bitmap_t; ++typedef grub_efi_uint32_t grub_efi_cc_mr_index_t; ++ ++/* Intel TDX measure register index. */ ++#define GRUB_TDX_MR_INDEX_MRTD 0 ++#define GRUB_TDX_MR_INDEX_RTMR0 1 ++#define GRUB_TDX_MR_INDEX_RTMR1 2 ++#define GRUB_TDX_MR_INDEX_RTMR2 3 ++#define GRUB_TDX_MR_INDEX_RTMR3 4 ++ ++#define GRUB_EFI_CC_EVENT_LOG_FORMAT_TCG_2 0x00000002 ++#define GRUB_EFI_CC_BOOT_HASH_ALG_SHA384 0x00000004 ++#define GRUB_EFI_CC_EVENT_HEADER_VERSION 1 ++ ++struct grub_efi_cc_event_header ++{ ++ /* Size of the event header itself (sizeof(EFI_TD_EVENT_HEADER)). */ ++ grub_efi_uint32_t HeaderSize; ++ ++ /* ++ * Header version. For this version of this specification, ++ * the value shall be 1. ++ */ ++ grub_efi_uint16_t HeaderVersion; ++ ++ /* Index of the MR that shall be extended. */ ++ grub_efi_cc_mr_index_t MrIndex; ++ ++ /* Type of the event that shall be extended (and optionally logged). */ ++ grub_efi_uint32_t EventType; ++} GRUB_PACKED; ++typedef struct grub_efi_cc_event_header grub_efi_cc_event_header_t; ++ ++struct grub_efi_cc_event ++{ ++ /* Total size of the event including the Size component, the header and the Event data. */ ++ grub_efi_uint32_t Size; ++ grub_efi_cc_event_header_t Header; ++ grub_efi_uint8_t Event[0]; ++} GRUB_PACKED; ++typedef struct grub_efi_cc_event grub_efi_cc_event_t; ++ ++struct grub_efi_cc_boot_service_capability ++{ ++ /* Allocated size of the structure. */ ++ grub_efi_uint8_t Size; ++ ++ /* ++ * Version of the grub_efi_cc_boot_service_capability_t structure itself. ++ * For this version of the protocol, the Major version shall be set to 1 ++ * and the Minor version shall be set to 1. ++ */ ++ grub_efi_cc_version_t StructureVersion; ++ ++ /* ++ * Version of the EFI TD protocol. ++ * For this version of the protocol, the Major version shall be set to 1 ++ * and the Minor version shall be set to 1. ++ */ ++ grub_efi_cc_version_t ProtocolVersion; ++ ++ /* Supported hash algorithms. */ ++ grub_efi_cc_event_algorithm_bitmap_t HashAlgorithmBitmap; ++ ++ /* Bitmap of supported event log formats. */ ++ grub_efi_cc_event_log_bitmap_t SupportedEventLogs; ++ ++ /* Indicates the CC type. */ ++ grub_efi_cc_type_t CcType; ++}; ++typedef struct grub_efi_cc_boot_service_capability grub_efi_cc_boot_service_capability_t; ++ ++struct grub_efi_cc_protocol ++{ ++ grub_efi_status_t ++ (*get_capability) (struct grub_efi_cc_protocol *this, ++ grub_efi_cc_boot_service_capability_t *ProtocolCapability); ++ ++ grub_efi_status_t ++ (*get_event_log) (struct grub_efi_cc_protocol *this, ++ grub_efi_cc_event_log_format_t EventLogFormat, ++ grub_efi_physical_address_t *EventLogLocation, ++ grub_efi_physical_address_t *EventLogLastEntry, ++ grub_efi_boolean_t *EventLogTruncated); ++ ++ grub_efi_status_t ++ (*hash_log_extend_event) (struct grub_efi_cc_protocol *this, ++ grub_efi_uint64_t Flags, ++ grub_efi_physical_address_t DataToHash, ++ grub_efi_uint64_t DataToHashLen, ++ grub_efi_cc_event_t *EfiCcEvent); ++ ++ grub_efi_status_t ++ (*map_pcr_to_mr_index) (struct grub_efi_cc_protocol *this, ++ grub_efi_uint32_t PcrIndex, ++ grub_efi_cc_mr_index_t *MrIndex); ++}; ++typedef struct grub_efi_cc_protocol grub_efi_cc_protocol_t; ++ ++#endif +-- +2.35.3 + diff --git a/0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch b/0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch new file mode 100644 index 0000000..bc89763 --- /dev/null +++ b/0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch @@ -0,0 +1,62 @@ +From 1729400ab816804a28ebf50cb1310607b2c4b75e Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Fri, 25 Feb 2022 12:49:51 -0500 +Subject: [PATCH 3/4] ieee1275: change the logic of ieee1275_get_devargs() + +Usually grub will parse the PFW arguments by searching for the first occurence of the character ':'. +However, we can have this char more than once on NQN. +This patch changes the logic to find the last occurence of this char so we can get the proper values +for NVMeoFC +--- + grub-core/kern/ieee1275/openfw.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c +index f819bd106..655a71310 100644 +--- a/grub-core/kern/ieee1275/openfw.c ++++ b/grub-core/kern/ieee1275/openfw.c +@@ -354,6 +354,13 @@ static char * + grub_ieee1275_get_devargs (const char *path) + { + char *colon = grub_strchr (path, ':'); ++ char *colon_check = colon; ++ ++ /* Find the last occurence of colon */ ++ while(colon_check){ ++ colon = colon_check; ++ colon_check = grub_strchr (colon+1, ':'); ++ } + + if (! colon) + return 0; +@@ -368,6 +375,18 @@ grub_ieee1275_get_devname (const char *path) + char *colon = grub_strchr (path, ':'); + int pathlen = grub_strlen (path); + struct grub_ieee1275_devalias curalias; ++ ++ /* Check some special cases */ ++ if(grub_strstr(path, "nvme-of")){ ++ char *namespace_split = grub_strstr(path,"/namespace@"); ++ if(namespace_split){ ++ colon = grub_strchr (namespace_split, ':'); ++ } else { ++ colon = NULL; ++ } ++ ++ } ++ + if (colon) + pathlen = (int)(colon - path); + +@@ -693,7 +712,7 @@ grub_ieee1275_get_boot_dev (void) + return NULL; + } + +- bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); ++ bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64 + 256); + if (! bootpath) + { + grub_print_error (); +-- +2.35.3 + diff --git a/0004-ofpath-controller-name-update.patch b/0004-ofpath-controller-name-update.patch new file mode 100644 index 0000000..3ab01e5 --- /dev/null +++ b/0004-ofpath-controller-name-update.patch @@ -0,0 +1,28 @@ +From 7717cd9c27f18703287403af1a955588e3d0261f Mon Sep 17 00:00:00 2001 +From: mamatha +Date: Sat, 24 Sep 2022 11:22:39 +0530 +Subject: [PATCH 4/4] ofpath controller name update + +patch to update ofpath controller name + +Signed-off-by: mamatha +--- + grub-core/osdep/linux/ofpath.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c +index 212782d3f..7d31cfd0f 100644 +--- a/grub-core/osdep/linux/ofpath.c ++++ b/grub-core/osdep/linux/ofpath.c +@@ -483,6 +483,8 @@ of_path_get_nvmeof_adapter_info(char* sysfs_path, + buf3=strchr(buf2,'-')+1; + buf3=strchr(buf3,'-')+1; + nvmeof_info->target_wwpn = buf3; ++ buf3=strchr(buf3,'x')+1; ++ nvmeof_info->target_wwpn = buf3; + buf3 = strchr(nvmeof_info->target_wwpn,','); + *buf3 = '\0'; + +-- +2.35.3 + diff --git a/grub2.changes b/grub2.changes index c9a1830..985e158 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,22 @@ +------------------------------------------------------------------- +Fri Oct 28 04:58:28 UTC 2022 - Michael Chang + +- NVMeoFC support on grub (jsc#PED-996) + * 0001-ieee1275-add-support-for-NVMeoFC.patch + * 0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch + * 0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch + * 0004-ofpath-controller-name-update.patch +- TDX: Enhance grub2 measurement to TD RTMR (jsc#PED-1265) + * 0001-commands-efi-tpm-Refine-the-status-of-log-event.patch + * 0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch + * 0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch +- Measure the kernel on POWER10 and extend TPM PCRs (PED-1990) + * 0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch + * 0002-ieee1275-implement-vec5-for-cas-negotiation.patch +- Fix efi pcr snapshot related funtion is defined but not used on powerpc + platform. + * safe_tpm_pcr_snapshot.patch + ------------------------------------------------------------------- Mon Oct 24 01:58:08 UTC 2022 - Michael Chang diff --git a/grub2.spec b/grub2.spec index 153dfb6..fe4793b 100644 --- a/grub2.spec +++ b/grub2.spec @@ -454,6 +454,18 @@ Patch925: 0002-mm-Defer-the-disk-cache-invalidation.patch Patch926: 0001-grub-install-set-point-of-no-return-for-powerpc-ieee1275.patch Patch927: safe_tpm_pcr_snapshot.patch Patch928: 0001-linux-fix-efi_relocate_kernel-failure.patch +# (PED-996) NVMeoFC support on Grub (grub2) +Patch929: 0001-ieee1275-add-support-for-NVMeoFC.patch +Patch930: 0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch +Patch931: 0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch +Patch932: 0004-ofpath-controller-name-update.patch +# (PED-1265) TDX: Enhance grub2 measurement to TD RTMR +Patch933: 0001-commands-efi-tpm-Refine-the-status-of-log-event.patch +Patch934: 0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch +Patch935: 0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch +# (PED-1990) GRUB2: Measure the kernel on POWER10 and extend TPM PCRs +Patch936: 0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch +Patch937: 0002-ieee1275-implement-vec5-for-cas-negotiation.patch Requires: gettext-runtime %if 0%{?suse_version} >= 1140 diff --git a/safe_tpm_pcr_snapshot.patch b/safe_tpm_pcr_snapshot.patch index 1a79db8..40f729e 100644 --- a/safe_tpm_pcr_snapshot.patch +++ b/safe_tpm_pcr_snapshot.patch @@ -1,20 +1,50 @@ --- - grub-core/commands/tpm.c | 28 ++++++++++++++++++++++------ + grub-core/commands/tpm.c | 46 ++++++++++++++++++++++++++++++++++++---------- util/grub-install.c | 6 ++++-- - 2 files changed, 26 insertions(+), 8 deletions(-) + 2 files changed, 40 insertions(+), 12 deletions(-) --- a/grub-core/commands/tpm.c +++ b/grub-core/commands/tpm.c -@@ -249,6 +249,8 @@ - return GRUB_ERR_NONE; - } +@@ -27,8 +27,10 @@ + #include + #include + #include ++#ifdef GRUB_MACHINE_EFI + #include + #include ++#endif + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -87,12 +89,6 @@ + .verify_string = grub_tpm_verify_string, + }; + +-/* +- * Preserve current PCR values and record them to an EFI variable +- */ +-#define GRUB2_PCR_BITMASK_DEFAULT ((1 << 16) - 1) +-#define GRUB2_PCR_BITMASK_ALL ((1 << 24) - 1) +- + static const struct grub_arg_option grub_tpm_record_pcrs_options[] = + { + { +@@ -108,6 +104,14 @@ + {0, 0, 0, 0, 0, 0} + }; +#ifdef GRUB_MACHINE_EFI ++ ++/* ++ * Preserve current PCR values and record them to an EFI variable ++ */ ++#define GRUB2_PCR_BITMASK_DEFAULT ((1 << 16) - 1) ++#define GRUB2_PCR_BITMASK_ALL ((1 << 24) - 1) + static grub_err_t - grub_tpm_record_pcrs (grub_extcmd_context_t ctxt, int argc, char **args) + grub_tpm_parse_pcr_index (const char *word, const char **end_ret, unsigned int *index) { -@@ -259,6 +261,10 @@ +@@ -259,6 +263,10 @@ grub_size_t size = 0; int n, rv = 1; @@ -25,7 +55,7 @@ if (argc == 0) pcr_bitmask = GRUB2_PCR_BITMASK_DEFAULT; else -@@ -287,13 +293,24 @@ +@@ -287,13 +295,28 @@ return rv; } @@ -47,21 +77,27 @@ { - if (!grub_tpm_present()) - return; -- grub_verifier_register (&grub_tpm_verifier); ++#ifdef GRUB_MACHINE_EFI + if (grub_tpm_present()) + grub_verifier_register (&grub_tpm_verifier); ++#else + grub_verifier_register (&grub_tpm_verifier); ++#endif cmd = grub_register_extcmd ("tpm_record_pcrs", grub_tpm_record_pcrs, 0, N_("LIST_OF_PCRS"), -@@ -303,8 +320,7 @@ +@@ -303,8 +326,11 @@ GRUB_MOD_FINI (tpm) { - if (!grub_tpm_present()) - return; -- grub_verifier_unregister (&grub_tpm_verifier); ++#ifdef GRUB_MACHINE_EFI + if (grub_tpm_present()) + grub_verifier_unregister (&grub_tpm_verifier); ++#else + grub_verifier_unregister (&grub_tpm_verifier); ++#endif grub_unregister_extcmd (cmd); } --- a/util/grub-install.c