[Skiboot] [PATCH 04/19] hdata/tpmrel.c: register CVC services during HDAT parsing
Stewart Smith
stewart at linux.vnet.ibm.com
Wed Nov 22 12:06:36 AEDT 2017
Oliver <oohall at gmail.com> writes:
> On Sun, Nov 12, 2017 at 4:28 AM, Claudio Carvalho
> <cclaudio at linux.vnet.ibm.com> wrote:
>> This registers the address range of the Container-Verification-Code
>> (CVC) and then registers each CVC service provided. The offset of
>> each service is checked to make sure that it is not out of the CVC
>> address range.
>>
>> The hostboot reserved memory that stores the CVC is identified by
>> parsing the msvpd_hb_reserved_mem HDAT structure. In order to register
>> its address range, we call the cvc_register() libstb function.
>>
>> The CVC services provided are identified by parsing the hash_and_verify
>> HDAT structure. In order to register them, we call the
>> cvc_service_register() libstb function.
>>
>> This also updates the hdat_to_dt unit test adding one stub for each
>> libstb function called.
>>
>> Since skiboot is the only consumer for the CVC services, this patch
>> doesn't add them to the device tree.
>>
>> Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
>> ---
>> hdata/spira.h | 12 ++++++
>> hdata/test/stubs.c | 2 +
>> hdata/tpmrel.c | 90 +++++++++++++++++++++++++++++++++++++++++
>> libstb/Makefile.inc | 2 +-
>> libstb/cvc.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>> libstb/cvc.h | 29 +++++++++++++
>> 6 files changed, 248 insertions(+), 1 deletion(-)
>> create mode 100644 libstb/cvc.c
>> create mode 100644 libstb/cvc.h
>>
>> diff --git a/hdata/spira.h b/hdata/spira.h
>> index 88fd2bf..328fb8d 100644
>> --- a/hdata/spira.h
>> +++ b/hdata/spira.h
>> @@ -528,6 +528,8 @@ struct msvpd_trace {
>> /* Idata index 5: Hostboot reserved memory address range */
>> #define MSVPD_IDATA_HB_RESERVED_MEM 5
>> struct msvpd_hb_reserved_mem {
>> +#define MSVPD_HBRMEM_RANGE_TYPE PPC_BITMASK32(0,7)
>> +#define HBRMEM_CONTAINER_VERIFICATION_CODE 0x3
>> __be32 type_instance;
>> __be64 start_addr;
>> __be64 end_addr;
>> @@ -1258,6 +1260,16 @@ struct secureboot_tpm_info {
>> __be32 drtm_log_size;
>> } __packed;
>>
>> +/* Idata index 2: Hash and Verification Function Offsets Array */
>> +#define TPMREL_IDATA_HASH_VERIF_OFFSETS 2
>> +
>> +struct hash_and_verification {
>> + __be32 type;
>> + __be32 version;
>> + __be32 dbob_id;
>> + __be32 offset;
>> +} __packed;
>> +
>> static inline const char *cpu_state(u32 flags)
>> {
>> switch ((flags & CPU_ID_VERIFY_MASK) >> CPU_ID_VERIFY_SHIFT) {
>> diff --git a/hdata/test/stubs.c b/hdata/test/stubs.c
>> index abeb832..ce1384d 100644
>> --- a/hdata/test/stubs.c
>> +++ b/hdata/test/stubs.c
>> @@ -117,4 +117,6 @@ NOOP_STUB(mem_reserve_hwbuf);
>> NOOP_STUB(add_chip_dev_associativity);
>> NOOP_STUB(enable_mambo_console);
>> NOOP_STUB(backtrace);
>> +NOOP_STUB(cvc_register);
>> +NOOP_STUB(cvc_service_register);
>>
>> diff --git a/hdata/tpmrel.c b/hdata/tpmrel.c
>> index 0aaa70b..11ed3ce 100644
>> --- a/hdata/tpmrel.c
>> +++ b/hdata/tpmrel.c
>> @@ -20,6 +20,8 @@
>>
>> #include <skiboot.h>
>> #include <device.h>
>> +#include <inttypes.h>
>> +#include <libstb/cvc.h>
>>
>> #include "spira.h"
>> #include "hdata.h"
>> @@ -72,6 +74,93 @@ static void tpmrel_add_firmware_event_log(const struct HDIF_common_hdr *hdif_hdr
>> }
>> }
>>
>> +static const struct msvpd_hb_reserved_mem *get_cvc_reserved_memory(void)
>> +{
>> +
>> + const struct msvpd_hb_reserved_mem *hb_resv_mem;
>> + const struct HDIF_common_hdr *ms_vpd;
>> + uint32_t type;
>> + int count, i;
>> +
>> + ms_vpd = get_hdif(&spira.ntuples.ms_vpd, MSVPD_HDIF_SIG);
>> +
>> + if (!ms_vpd) {
>> + prlog(PR_ERR, "MS VPD invalid\n");
>> + return NULL;
>> + }
>> +
>> + count = HDIF_get_iarray_size(ms_vpd, MSVPD_IDATA_HB_RESERVED_MEM);
>> + if (count <= 0) {
>> + prlog(PR_ERR, "no hostboot reserved memory found\n");
>> + return NULL;
>> + }
>> +
>> + for (i = 0; i < count; i++) {
>> + hb_resv_mem = HDIF_get_iarray_item(ms_vpd,
>> + MSVPD_IDATA_HB_RESERVED_MEM,
>> + i, NULL);
>> + if (!CHECK_SPPTR(hb_resv_mem))
>> + continue;
>> +
>> + type = be32_to_cpu(hb_resv_mem->type_instance);
>> + type = GETFIELD(MSVPD_HBRMEM_RANGE_TYPE, type);
>> +
>> + /* Reserved memory for the Container Verification Code? */
>> + if (type == HBRMEM_CONTAINER_VERIFICATION_CODE)
>> + return hb_resv_mem;
>> + }
>> +
>> + return NULL;
>> +}
>> +
>> +#define HRMOR_BIT (1ul << 63)
>> +
>> +static void tpmrel_cvc_init(struct HDIF_common_hdr *hdif_hdr)
>> +{
>> + const struct hash_and_verification *hv;
>> + const struct msvpd_hb_reserved_mem *cvc_resv_mem;
>> + uint32_t type, version, offset;
>> + uint64_t start_addr, end_addr;
>> + int count, i;
>> +
>> + cvc_resv_mem = get_cvc_reserved_memory();
>> +
>> + if (!cvc_resv_mem) {
>> + prlog(PR_ERR, "CVC reserved memory not found\n");
>> + return;
>> + }
>> +
>> + start_addr = be64_to_cpu(cvc_resv_mem->start_addr);
>> + start_addr &= ~HRMOR_BIT;
>> + end_addr = be64_to_cpu(cvc_resv_mem->end_addr);
>> + end_addr &= ~HRMOR_BIT;
>> + prlog(PR_DEBUG, "Found CVC at 0x%"PRIx64"...0x%"PRIx64"\n",
>> + start_addr, end_addr);
>
> The parsing here seems to be a duplicate of what's in memory.c. At
> this point it should have already been parsed into
> /ibm,hostboot/reserved-memory/ in the device-tree, so why not look it
> up there?
I'd prefer that too, If the label isn't there for CVC code, then we
should probably just create one based off the ID.
>> + cvc_register(start_addr, end_addr);
>
> As an aside we try to keep this sort of thing out of the HDAT parser.
> In theory we should be able to boot off just a device-tree and have
> everything work. The main application of that is allowing cronus
> booting. Granted secure cronus booting doesn't make a whole lot of
> sense it's not really a problem here, but it's something to keep in
> mind.
and we may not always go via HDAT too.
--
Stewart Smith
OPAL Architect, IBM.
More information about the Skiboot
mailing list