[Skiboot] [RFC PATCH v2 5/8] xscoms: read/write xscoms using ucall

Oliver O'Halloran oohall at gmail.com
Mon Nov 18 10:55:37 AEDT 2019


On Sat, Sep 21, 2019 at 12:02 AM Ryan Grimm <grimm at linux.ibm.com> wrote:
>
> From: Madhavan Srinivasan <maddy at linux.vnet.ibm.com>
>
> xscom registers are in the secure memory area when secure mode is
> enabled. These registers cannot be accessed directly and need to use
> ultravisor services using ultracall.
>
> Signed-off-by: Madhavan Srinivasan <maddy at linux.vnet.ibm.com>
> Signed-off-by: Santosh Sivaraj <santosh at fossix.org>
> [ linuxram: Set uv_present just after starting UV ]
> Signed-off-by: Ram Pai <linuxram at us.ibm.com>
> ---
>  hw/ultravisor.c      |  8 ++++++++
>  include/ultravisor.h | 28 ++++++++++++++++++++++++++++
>  include/xscom.h      | 11 +++++++++--
>  3 files changed, 45 insertions(+), 2 deletions(-)
>
> diff --git a/hw/ultravisor.c b/hw/ultravisor.c
> index c9e837ac..63629de2 100644
> --- a/hw/ultravisor.c
> +++ b/hw/ultravisor.c
> @@ -16,6 +16,7 @@
>  #include <ultravisor-api.h>
>  #include <libfdt/libfdt.h>
>
> +bool uv_present = false;
>  static char *uv_image = NULL;
>  static size_t uv_image_size;
>  struct xz_decompress *uv_xz = NULL;
> @@ -163,6 +164,7 @@ static void cpu_start_ultravisor(void *data)
>
>  int start_ultravisor(void)
>  {
> +       struct proc_chip *chip = get_chip(this_cpu()->chip_id);
>         struct cpu_thread *cpu;
>         struct cpu_job **jobs;
>         int i=0;
> @@ -182,6 +184,12 @@ int start_ultravisor(void)
>
>         cpu_start_ultravisor((void *)uv_opal);
>
> +       /*
> +        * From now on XSCOM must go through Ultravisor via ucall, indicate that
> +        */
> +       if (chip->xscom_base & UV_ACCESS_BIT)
> +               uv_present = true;
> +
>         /* wait for everyone to sync back */
>         while (i > 0) {
>                 cpu_wait_job(jobs[--i], true);
> diff --git a/include/ultravisor.h b/include/ultravisor.h
> index 67be743f..7e403c8c 100644
> --- a/include/ultravisor.h
> +++ b/include/ultravisor.h
> @@ -10,6 +10,9 @@
>   * for the secure virtual machines */
>  #define UV_SECURE_MEM_BIT              (PPC_BIT(15))
>  #define MAX_COMPRESSED_UV_IMAGE_SIZE 0x40000 /* 256 Kilobytes */
> +#define UV_READ_SCOM  0xF114
> +#define UV_WRITE_SCOM 0xF118
> +#define UCALL_BUFSIZE 4
>  #define UV_ACCESS_BIT          0x1ULL << 48
>  /* Address at which the Ultravisor is loaded for BML and Mambo */
>  #define UV_LOAD_BASE           0xC0000000
> @@ -17,6 +20,9 @@
>  #define UV_FDT_MAX_SIZE                0x100000
>  #define UV_HB_RESERVE_SIZE     0x4000000;
>

> +extern bool uv_present;
> +#define is_uv_present() uv_present
why?

> +
>  extern int start_uv(uint64_t entry, struct uv_opal *uv_opal);
>  extern bool uv_add_mem_range(__be64 start, __be64 end);
>  extern void uv_preload_image(void);
> @@ -25,4 +31,26 @@ extern void init_uv(void);
>  extern int start_ultravisor(void);
>  extern long ucall(unsigned long opcode, unsigned long *retbuf, ...);
>
> +static inline bool can_access_xscom(void)
> +{
> +       return (is_msr_bit_set(MSR_S) || !is_uv_present());

I'd prefer we didn't open-code MSR checks since it makes testing
awkward. Check if we can do XSCOMs directly in xscom_init() and clear
that flag after we've started the UV.

> +}
> +
> +static inline int uv_xscom_read(u64 partid, u64 pcb_addr, u64 *val)
> +{
> +       long rc;
> +       unsigned long retbuf[UCALL_BUFSIZE];
> +
> +       rc = ucall(UV_READ_SCOM, retbuf, partid, pcb_addr);
> +       *val = retbuf[0];
> +       return rc;
> +}
> +
> +static inline int uv_xscom_write(u64 partid, u64 pcb_addr, u64 val)
> +{
> +       unsigned long retbuf[UCALL_BUFSIZE];
> +
> +       return ucall(UV_WRITE_SCOM, retbuf, partid, pcb_addr, val);
> +}
> +
>  #endif /* __ULTRAVISOR_H */
> diff --git a/include/xscom.h b/include/xscom.h
> index 1f89ba9b..595161c5 100644
> --- a/include/xscom.h
> +++ b/include/xscom.h
> @@ -7,6 +7,7 @@
>  #include <stdint.h>
>  #include <processor.h>
>  #include <cpu.h>
> +#include <ultravisor.h>
>
>  /*
>   * SCOM "partID" definitions:
> @@ -215,10 +216,16 @@ extern void _xscom_unlock(void);
>  /* Targeted SCOM access */
>  static inline int xscom_read(uint32_t partid, uint64_t pcb_addr, uint64_t *val)
>  {
> -       return _xscom_read(partid, pcb_addr, val, true);
> +       if (can_access_xscom())
> +               return _xscom_read(partid, pcb_addr, val, true);
> +
> +       return uv_xscom_read(partid, pcb_addr, val);
>  }
>  static inline int xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val) {
> -       return _xscom_write(partid, pcb_addr, val, true);
> +       if (can_access_xscom())
> +               return _xscom_write(partid, pcb_addr, val, true);
> +
> +       return uv_xscom_write(partid, pcb_addr, val);
>  }
>  extern int xscom_write_mask(uint32_t partid, uint64_t pcb_addr, uint64_t val, uint64_t mask);
>
> --
> 2.21.0
>
> _______________________________________________
> Skiboot mailing list
> Skiboot at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/skiboot


More information about the Skiboot mailing list