On 8/28/19 10:05 AM, Michael Ellerman wrote: > From: Claudio Carvalho <cclau...@linux.ibm.com> > > The ultravisor (UV) provides an in-memory console which follows the > OPAL in-memory console structure. > > This patch extends the OPAL msglog code to initialize the UV memory > console and provide the "/sys/firmware/ultravisor/msglog" interface > for userspace to view the UV message log.
Tested-by: Claudio Carvalho <cclau...@linux.ibm.com> Thanks, Claudio > > Signed-off-by: Claudio Carvalho <cclau...@linux.ibm.com> > Signed-off-by: Michael Ellerman <m...@ellerman.id.au> > --- > v4: mpe: Move all the code into ultravisor.c. > Consistently use "uv_" as the prefix not "ultra_". > Use powernv.h for routines that are shared within the platform. > Rather than bloating the kernel with strings for every rare error > case, return error codes from the init routine which can be > seen with initcall_debug. > --- > arch/powerpc/platforms/powernv/powernv.h | 5 +++ > arch/powerpc/platforms/powernv/ultravisor.c | 45 +++++++++++++++++++++ > 2 files changed, 50 insertions(+) > > diff --git a/arch/powerpc/platforms/powernv/powernv.h > b/arch/powerpc/platforms/powernv/powernv.h > index fd4a1c5a6369..1aa51c4fa904 100644 > --- a/arch/powerpc/platforms/powernv/powernv.h > +++ b/arch/powerpc/platforms/powernv/powernv.h > @@ -30,4 +30,9 @@ extern void opal_event_shutdown(void); > > bool cpu_core_split_required(void); > > +struct memcons; > +ssize_t memcons_copy(struct memcons *mc, char *to, loff_t pos, size_t count); > +u32 memcons_get_size(struct memcons *mc); > +struct memcons *memcons_init(struct device_node *node, const char > *mc_prop_name); > + > #endif /* _POWERNV_H */ > diff --git a/arch/powerpc/platforms/powernv/ultravisor.c > b/arch/powerpc/platforms/powernv/ultravisor.c > index 02ac57b4bded..e4a00ad06f9d 100644 > --- a/arch/powerpc/platforms/powernv/ultravisor.c > +++ b/arch/powerpc/platforms/powernv/ultravisor.c > @@ -8,9 +8,15 @@ > #include <linux/init.h> > #include <linux/printk.h> > #include <linux/of_fdt.h> > +#include <linux/of.h> > > #include <asm/ultravisor.h> > #include <asm/firmware.h> > +#include <asm/machdep.h> > + > +#include "powernv.h" > + > +static struct kobject *ultravisor_kobj; > > int __init early_init_dt_scan_ultravisor(unsigned long node, const char > *uname, > int depth, void *data) > @@ -22,3 +28,42 @@ int __init early_init_dt_scan_ultravisor(unsigned long > node, const char *uname, > pr_debug("Ultravisor detected!\n"); > return 1; > } > + > +static struct memcons *uv_memcons; > + > +static ssize_t uv_msglog_read(struct file *file, struct kobject *kobj, > + struct bin_attribute *bin_attr, char *to, > + loff_t pos, size_t count) > +{ > + return memcons_copy(uv_memcons, to, pos, count); > +} > + > +static struct bin_attribute uv_msglog_attr = { > + .attr = {.name = "msglog", .mode = 0400}, > + .read = uv_msglog_read > +}; > + > +static int __init uv_init(void) > +{ > + struct device_node *node; > + > + if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR)) > + return 0; > + > + node = of_find_compatible_node(NULL, NULL, "ibm,uv-firmware"); > + if (!node) > + return -ENODEV; > + > + uv_memcons = memcons_init(node, "memcons"); > + if (!uv_memcons) > + return -ENOENT; > + > + uv_msglog_attr.size = memcons_get_size(uv_memcons); > + > + ultravisor_kobj = kobject_create_and_add("ultravisor", firmware_kobj); > + if (!ultravisor_kobj) > + return -ENOMEM; > + > + return sysfs_create_bin_file(ultravisor_kobj, &uv_msglog_attr); > +} > +machine_subsys_initcall(powernv, uv_init);