From mboxrd@z Thu Jan 1 00:00:00 1970 From: Claudio Carvalho Date: Wed, 28 Aug 2019 03:56:46 +0000 Subject: [PATCH v3 2/2] powerpc/powernv: Add ultravisor message log interface Message-Id: <20190828035646.907-2-cclaudio@linux.ibm.com> List-Id: References: <20190828035646.907-1-cclaudio@linux.ibm.com> In-Reply-To: <20190828035646.907-1-cclaudio@linux.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: linuxppc-dev@ozlabs.org Cc: Madhavan Srinivasan , Michael Anderson , Ram Pai , Claudio Carvalho , kvm-ppc@vger.kernel.org, Ryan Grimm 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. Signed-off-by: Claudio Carvalho --- This patch applies on top of the "kvmppc: Paravirtualize KVM to support ultravisor" patch series submitted by Claudio Carvalho. --- arch/powerpc/include/asm/ultravisor.h | 8 ++++ arch/powerpc/platforms/powernv/opal-msglog.c | 36 ++++++++++++++++++ arch/powerpc/platforms/powernv/ultravisor.c | 40 ++++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/arch/powerpc/include/asm/ultravisor.h b/arch/powerpc/include/asm/ultravisor.h index d7aa97aa7834..62932d403847 100644 --- a/arch/powerpc/include/asm/ultravisor.h +++ b/arch/powerpc/include/asm/ultravisor.h @@ -12,6 +12,14 @@ #include #include +/* /sys/firmware/ultravisor */ +extern struct kobject *ultravisor_kobj; + +/* /ibm,ultravisor/ibm,uv-firmware */ +extern struct device_node *uv_firmware_node; + +void ultra_msglog_init(void); +void ultra_msglog_sysfs_init(void); int early_init_dt_scan_ultravisor(unsigned long node, const char *uname, int depth, void *data); diff --git a/arch/powerpc/platforms/powernv/opal-msglog.c b/arch/powerpc/platforms/powernv/opal-msglog.c index 0e8eb62c8afe..7c6b2001e62f 100644 --- a/arch/powerpc/platforms/powernv/opal-msglog.c +++ b/arch/powerpc/platforms/powernv/opal-msglog.c @@ -11,6 +11,7 @@ #include #include #include +#include /* OPAL in-memory console. Defined in OPAL source at core/console.c */ struct memcons { @@ -28,6 +29,7 @@ struct memcons { }; static struct memcons *opal_memcons = NULL; +static struct memcons *ultra_memcons; static ssize_t memcons_copy(struct memcons *mc, char *to, loff_t pos, size_t count) @@ -104,6 +106,18 @@ static struct bin_attribute opal_msglog_attr = { .read = opal_msglog_read }; +static ssize_t ultra_msglog_read(struct file *file, struct kobject *kobj, + struct bin_attribute *bin_attr, char *to, + loff_t pos, size_t count) +{ + return memcons_copy(ultra_memcons, to, pos, count); +} + +static struct bin_attribute ultra_msglog_attr = { + .attr = {.name = "msglog", .mode = 0400}, + .read = ultra_msglog_read +}; + static struct memcons *memcons_load_from_dt(struct device_node *node, const char *mc_prop_name) { @@ -159,3 +173,25 @@ void __init opal_msglog_sysfs_init(void) if (sysfs_create_bin_file(opal_kobj, &opal_msglog_attr) != 0) pr_warn("OPAL: sysfs file creation failed\n"); } + +void __init ultra_msglog_init(void) +{ + ultra_memcons = memcons_load_from_dt(uv_firmware_node, "memcons"); + if (!ultra_memcons) { + pr_warn("Ultravisor: memcons failed to load from DT\n"); + return; + } + + ultra_msglog_attr.size = memcons_get_size(ultra_memcons); +} + +void __init ultra_msglog_sysfs_init(void) +{ + if (!ultra_memcons) { + pr_warn("Ultravisor: msglog initialisation failed, not creating sysfs entry\n"); + return; + } + + if (sysfs_create_bin_file(ultravisor_kobj, &ultra_msglog_attr) != 0) + pr_warn("Ultravisor: sysfs msglog file creation failed\n"); +} diff --git a/arch/powerpc/platforms/powernv/ultravisor.c b/arch/powerpc/platforms/powernv/ultravisor.c index 02ac57b4bded..4ec63b7c0c78 100644 --- a/arch/powerpc/platforms/powernv/ultravisor.c +++ b/arch/powerpc/platforms/powernv/ultravisor.c @@ -8,9 +8,14 @@ #include #include #include +#include #include #include +#include + +struct kobject *ultravisor_kobj; +struct device_node *uv_firmware_node; int __init early_init_dt_scan_ultravisor(unsigned long node, const char *uname, int depth, void *data) @@ -22,3 +27,38 @@ int __init early_init_dt_scan_ultravisor(unsigned long node, const char *uname, pr_debug("Ultravisor detected!\n"); return 1; } + +static int __init ultra_sysfs_init(void) +{ + ultravisor_kobj = kobject_create_and_add("ultravisor", firmware_kobj); + if (!ultravisor_kobj) { + pr_warn("kobject_create_and_add ultravisor failed\n"); + return -ENOMEM; + } + + return 0; +} + +static int __init ultra_init(void) +{ + int rc; + + if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR)) + goto out; + + uv_firmware_node = of_find_compatible_node(NULL, NULL, + "ibm,uv-firmware"); + if (!uv_firmware_node) { + pr_err("ibm,uv-firmware node not found\n"); + return -ENODEV; + } + + ultra_msglog_init(); + + rc = ultra_sysfs_init(); + if (rc = 0) + ultra_msglog_sysfs_init(); +out: + return 0; +} +machine_subsys_initcall(powernv, ultra_init); -- 2.20.1