[Skiboot] [PATCH v8 07/11] Load the ultravisor from flash and decompress
Santosh S
santosh at fossix.org
Sat Aug 29 01:28:24 AEST 2020
On Friday, 28 August, 2020 10:24:50 AM IST Oliver O'Halloran wrote:
> On Thu, Aug 27, 2020 at 4:41 AM Ryan Grimm <grimm at linux.ibm.com> wrote:
> > The ultravisor, labeled UVISOR is preloaded from the PNOR in
> > main_cpu_entry after the kernel is preloaded. This also works on
> > FSP-based systems with an ultra.lid on the FSP.
> >
> > Skiboot decompresses it later in init_uv.
> >
> > Signed-off-by: Santosh Sivaraj <santosh at linux.ibm.com>
> > Signed-off-by: Ryan Grimm <grimm at linux.ibm.com>
> > ---
> >
> > core/flash.c | 1 +
> > core/init.c | 1 +
> > hw/fsp/fsp.c | 2 +
> > hw/ultravisor.c | 95 +++++++++++++++++++++++++++++++++++++++-----
> > include/platform.h | 1 +
> > include/ultravisor.h | 3 ++
> > 6 files changed, 93 insertions(+), 10 deletions(-)
> >
> > diff --git a/core/flash.c b/core/flash.c
> > index de748641..bc44a4e5 100644
> > --- a/core/flash.c
> > +++ b/core/flash.c
> > @@ -45,6 +45,7 @@ static struct {
> >
> > { RESOURCE_ID_INITRAMFS,RESOURCE_SUBID_NONE, "ROOTFS"
> > },
> > { RESOURCE_ID_CAPP, RESOURCE_SUBID_SUPPORTED, "CAPP" },
> > { RESOURCE_ID_IMA_CATALOG, RESOURCE_SUBID_SUPPORTED,
> > "IMA_CATALOG" },
> >
> > + { RESOURCE_ID_UV_IMAGE, RESOURCE_SUBID_NONE, "UVISOR"
> > },
> >
> > { RESOURCE_ID_VERSION, RESOURCE_SUBID_NONE, "VERSION"
> > },
> > { RESOURCE_ID_KERNEL_FW, RESOURCE_SUBID_NONE,
> > "BOOTKERNFW" },>
> > };
> >
> > diff --git a/core/init.c b/core/init.c
> > index 91754962..77dfb36f 100644
> > --- a/core/init.c
> > +++ b/core/init.c
> > @@ -1319,6 +1319,7 @@ void __noreturn __nomcount main_cpu_entry(const
void
> > *fdt)>
> > preload_capp_ucode();
> > start_preload_kernel();
> >
> > + uv_preload_image();
> >
> > /* Catalog decompression routine */
> > imc_decompress_catalog();
> >
> > diff --git a/hw/fsp/fsp.c b/hw/fsp/fsp.c
> > index 70452cf9..7b564f93 100644
> > --- a/hw/fsp/fsp.c
> > +++ b/hw/fsp/fsp.c
> > @@ -114,6 +114,7 @@ static u64 fsp_hir_timeout;
> >
> > #define KERNEL_LID_PHYP 0x80a00701
> > #define KERNEL_LID_OPAL 0x80f00101
> > #define INITRAMFS_LID_OPAL 0x80f00102
> >
> > +#define ULTRA_LID_OPAL 0x80f00105
> >
> > /*
> >
> > * We keep track on last logged values for some things to print only on
> >
> > @@ -2381,6 +2382,7 @@ static struct {
> >
> > } fsp_lid_map[] = {
> >
> > { RESOURCE_ID_KERNEL, RESOURCE_SUBID_NONE, KERNEL_LID_OPAL
},
> > { RESOURCE_ID_INITRAMFS,RESOURCE_SUBID_NONE,
INITRAMFS_LID_OPAL
> > },
> >
> > + { RESOURCE_ID_UV_IMAGE, RESOURCE_SUBID_NONE, ULTRA_LID_OPAL },
> >
> > { RESOURCE_ID_IMA_CATALOG,IMA_CATALOG_NIMBUS, 0x80f00103 },
> > { RESOURCE_ID_CAPP, CAPP_IDX_MURANO_DD20, 0x80a02002 },
> > { RESOURCE_ID_CAPP, CAPP_IDX_MURANO_DD21, 0x80a02001 },
> >
> > diff --git a/hw/ultravisor.c b/hw/ultravisor.c
> > index 467f0ca6..34c16404 100644
> > --- a/hw/ultravisor.c
> > +++ b/hw/ultravisor.c
> > @@ -10,11 +10,16 @@
> >
> > #include <cpu.h>
> > #include <debug_descriptor.h>
> > #include <console.h>
> >
> > +#include <chip.h>
> > +#include <libstb/container.h>
> >
> > static struct dt_node *uv_fw_node;
> > static uint64_t uv_base_addr;
> > bool uv_present;
> >
> > +static char *uv_image = NULL;
> > +static size_t uv_image_size;
> > +
> >
> > struct memcons uv_memcons __section(".data.memcons") = {
> >
> > .magic = MEMCONS_MAGIC,
> > .obuf_phys = INMEM_UV_CON_START,
> >
> > @@ -70,10 +75,44 @@ int start_ultravisor(void *fdt)
> >
> > return OPAL_SUCCESS;
> >
> > }
> >
> > +static int uv_decompress_image(void)
> > +{
> > + struct xz_decompress uv_xz;
> > + uint64_t uv_fw_size;
> > +
> > + if (!uv_image) {
> > + prerror("UV: Preload hasn't started yet! Aborting.\n");
> > + return OPAL_INTERNAL_ERROR;
> > + }
> > +
> > + if (wait_for_resource_loaded(RESOURCE_ID_UV_IMAGE,
> > + RESOURCE_SUBID_NONE) !=
OPAL_SUCCESS)
> > { + prerror("UV: Ultravisor image load failed\n");
> > + return OPAL_INTERNAL_ERROR;
> > + }
> > +
> > + uv_xz.dst = (void *)dt_get_address(uv_fw_node, 0, &uv_fw_size);
> > + uv_xz.dst_size = uv_fw_size;
> > + uv_xz.src_size = uv_image_size;
> > + uv_xz.src = uv_image;
> > +
> > + if (stb_is_container((void*)uv_xz.src, uv_xz.src_size))
> > + uv_xz.src = uv_xz.src + SECURE_BOOT_HEADERS_SIZE;
> > +
> > + xz_start_decompress(&uv_xz);
> > + if ((uv_xz.status != OPAL_PARTIAL) && (uv_xz.status !=
> > OPAL_SUCCESS)) {
> Weird indentation and why would we get OPAL_PARTIAL here?
xz_decompress sets the status partial as the default error, but that itself
is not needed. status is updated in the same thread anyway. But in this case,
probably what I meant was OPAL_PARAMETER.
Thanks,
Santosh
>
> > + prerror("UV: XZ decompression failed status
> > 0x%x\n", uv_xz.status); + return OPAL_INTERNAL_ERROR;
> > + }
> > +
> > + return OPAL_SUCCESS;
> > +}
> > +
> >
> > void init_uv()
> > {
> >
> > uint64_t uv_dt_src, uv_fw_sz;
> > struct dt_node *reserved_mem;
> >
> > + int ret;
> >
> > if (!is_msr_bit_set(MSR_S)) {
> >
> > prlog(PR_DEBUG, "UV: S bit not set\n");
> >
> > @@ -84,23 +123,59 @@ void init_uv()
> >
> > if (!uv_fw_node) {
> >
> > prlog(PR_DEBUG, "UV: No ibm,uv-firmware node found,
> > disabling pef\n");
> > cpu_disable_pef();
> >
> > - return;
> > + goto err;
> >
> > }
> >
> > - reserved_mem = dt_find_by_path(dt_root,
> > "/reserved-memory/ibm,uv-firmware"); - if (!reserved_mem) {
> > - prerror("UV: No reserved memory for ibm,uv-firmware
> > found\n"); - return;
> > - }
> > + /* If decompress fails, look for reserved memory by Mambo tcl or
> > cronus BML */ + ret = uv_decompress_image();
> > + if (ret) {
> > + reserved_mem = dt_find_by_path(dt_root,
> > "/reserved-memory/ibm,uv-firmware"); + if (!reserved_mem) {
> > + prerror("UV: No reserved memory for
> > ibm,uv-firmware found\n"); + return;
> > + }
> >
> > - uv_dt_src = dt_get_address(reserved_mem, 0, &uv_fw_sz);
> > - uv_base_addr = dt_get_address(uv_fw_node, 0, NULL);
> > + uv_dt_src = dt_get_address(reserved_mem, 0, &uv_fw_sz);
> > + uv_base_addr = dt_get_address(uv_fw_node, 0, NULL);
> >
> > - prlog(PR_INFO, "UV: Copying 0x%llx bytes to protected memory
> > 0x%llx from 0x%llx\n", + prlog(PR_INFO, "UV: Copying 0x%llx
> > bytes to protected memory 0x%llx from 0x%llx\n",>
> > uv_fw_sz, uv_base_addr,
> > uv_dt_src);
> >
> > - memcpy((void *)uv_base_addr, (void *)uv_dt_src, uv_fw_sz);
> > + memcpy((void *)uv_base_addr, (void *)uv_dt_src,
uv_fw_sz);
> > + }
> >
> > dt_add_property_u64(uv_fw_node, "memcons", (u64)&uv_memcons);
> > debug_descriptor.uv_memcons_phys = (u64)&uv_memcons;
> >
> > +err:
> > + local_free(uv_image);
> > +}
> > +
> > +/*
> > + * Preload the UV image from PNOR partition
> > + *
> > + * uv_image is allocated locally to the chip and freed here if preload
> > fails + * or free in init_uv
> > + */
> > +void uv_preload_image(void)
> > +{
> > + struct proc_chip *chip = next_chip(NULL);
> > + int ret;
> > +
> > + prlog(PR_DEBUG, "UV: Preload starting\n");
> > +
> > + uv_image_size = MAX_COMPRESSED_UV_IMAGE_SIZE;
> > + uv_image = local_alloc(chip->id, uv_image_size, uv_image_size);
> > + if (!uv_image) {
> > + prerror("UV: Memory allocation failed\n");
> > + return;
> > + }
> > + memset(uv_image, 0, uv_image_size);
> > +
> > + ret = start_preload_resource(RESOURCE_ID_UV_IMAGE,
> > RESOURCE_SUBID_NONE, + uv_image,
> > &uv_image_size);
> > +
> > + if (ret != OPAL_SUCCESS) {
> > + local_free(uv_image);
> > + prerror("UV: platform load failed: %d\n", ret);
> > + }
> >
> > }
> >
> > diff --git a/include/platform.h b/include/platform.h
> > index ef93278b..57b2eeef 100644
> > --- a/include/platform.h
> > +++ b/include/platform.h
> > @@ -17,6 +17,7 @@ enum resource_id {
> >
> > RESOURCE_ID_INITRAMFS,
> > RESOURCE_ID_CAPP,
> > RESOURCE_ID_IMA_CATALOG,
> >
> > + RESOURCE_ID_UV_IMAGE,
> >
> > RESOURCE_ID_VERSION,
> > RESOURCE_ID_KERNEL_FW,
> >
> > };
> >
> > diff --git a/include/ultravisor.h b/include/ultravisor.h
> > index 84217d66..8048cb76 100644
> > --- a/include/ultravisor.h
> > +++ b/include/ultravisor.h
> > @@ -64,4 +64,7 @@ static inline int uv_xscom_write(u64 partid, u64
> > pcb_addr, u64 val)>
> > return ucall(UV_WRITE_SCOM, retbuf, partid, pcb_addr, val);
> >
> > }
> >
> > +#define MAX_COMPRESSED_UV_IMAGE_SIZE 0x40000 /* 256 Kilobytes */
> > +void uv_preload_image(void);
> > +
> >
> > #endif /* __ULTRAVISOR_H */
> >
> > --
> > 2.18.4
> >
> > _______________________________________________
> > Skiboot mailing list
> > Skiboot at lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/skiboot
>
> _______________________________________________
> Skiboot mailing list
> Skiboot at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/skiboot
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.ozlabs.org/pipermail/skiboot/attachments/20200828/3248f10f/attachment-0001.sig>
More information about the Skiboot
mailing list