Message ID | 20190920135823.471-6-grimm@linux.ibm.com |
---|---|
State | RFC |
Headers | show |
Series | PEF support in skiboot | expand |
Context | Check | Description |
---|---|---|
snowpatch_ozlabs/apply_patch | warning | Failed to apply on branch master (470ffb5f29d741c3bed600f7bb7bf0cbb270e05a) |
snowpatch_ozlabs/apply_patch | fail | Failed to apply to any branch |
On Sat, Sep 21, 2019 at 12:02 AM Ryan Grimm <grimm@linux.ibm.com> wrote: > > From: Madhavan Srinivasan <maddy@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@linux.vnet.ibm.com> > Signed-off-by: Santosh Sivaraj <santosh@fossix.org> > [ linuxram: Set uv_present just after starting UV ] > Signed-off-by: Ram Pai <linuxram@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@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/skiboot
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 + 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()); +} + +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);