[Skiboot] [PATCH 04/19] hdata/tpmrel.c: register CVC services during HDAT parsing

Vasant Hegde hegdevasant at linux.vnet.ibm.com
Tue Nov 28 17:54:17 AEDT 2017


On 11/11/2017 10:58 PM, Claudio Carvalho 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/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)
> +{
> +

May be we should add another property inside reserved-memory to identify 
reserved-memory type and use it here. Because today its just secureboot. 
Tomorrow someone else may want to use type field.


> +	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);
> +	cvc_register(start_addr, end_addr);
> +	/*
> +	 * Initialize each service provided by the container verification code
> +	 */
> +	count = HDIF_get_iarray_size(hdif_hdr, TPMREL_IDATA_HASH_VERIF_OFFSETS);
> +	if (count <= 0 ) {
> +		prlog(PR_ERR, "no CVC service found\n");
> +		return;
> +	}
> +
> +	for (i = 0; i < count; i++) {
> +
> +		hv = HDIF_get_iarray_item(hdif_hdr,
> +					  TPMREL_IDATA_HASH_VERIF_OFFSETS,
> +					  i, NULL);
> +		type = be32_to_cpu(hv->type);
> +		version = be32_to_cpu(hv->version);
> +		offset = be32_to_cpu(hv->offset);

Like Oliver mentioned you can add these properties to DT, and then call 
cvc_service_register outside hdata parsing.


-Vasant



More information about the Skiboot mailing list