[Skiboot] [PATCH v8 07/11] Load the ultravisor from flash and decompress

Ryan Grimm grimm at linux.vnet.ibm.com
Wed Sep 9 06:19:16 AEST 2020


On Fri, 2020-08-28 at 14:54 +1000, Oliver O'Halloran wrote:
> 
> > +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?
> 

Oh, oops, indents fixed. 

Well, the comment in xz_start_decompress show this:

 * The `status` value will be OPAL_PARTIAL till the job completes
(successfully
 * or not)

The code seems to work that way and it's a job queue so we need to
check for both since it might not complete right?

-Ryan


> > +                       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



More information about the Skiboot mailing list