[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