From patchwork Sat Jul 20 01:29:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 1134342 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45r9Qq4mYHz9s8m for ; Sat, 20 Jul 2019 11:34:43 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ozlabs.ru Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 45r9Qq3Vj9zDr09 for ; Sat, 20 Jul 2019 11:34:43 +1000 (AEST) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=ozlabs.ru (client-ip=107.173.13.209; helo=ozlabs.ru; envelope-from=aik@ozlabs.ru; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=ozlabs.ru Received: from ozlabs.ru (ozlabs.ru [107.173.13.209]) by lists.ozlabs.org (Postfix) with ESMTP id 45r9KP205QzDqws for ; Sat, 20 Jul 2019 11:30:01 +1000 (AEST) Received: from fstn1-p1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 024A8AE807F6; Fri, 19 Jul 2019 21:29:22 -0400 (EDT) From: Alexey Kardashevskiy To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH kernel RFC 1/2] powerpc/pseries: Call RTAS directly Date: Sat, 20 Jul 2019 11:29:18 +1000 Message-Id: <20190720012919.14417-2-aik@ozlabs.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190720012919.14417-1-aik@ozlabs.ru> References: <20190720012919.14417-1-aik@ozlabs.ru> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , kvm-ppc@vger.kernel.org, David Gibson Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" The pseries guests call RTAS via a RTAS entry point which is a firmware image under powernv and simple HCALL wrapper under QEMU. For the latter, we can skip the binary image and do HCALL directly, eliminating the need in the RTAS blob entirely. This checks the DT whether the new method is supported and use it if it is. This removes few checks as QEMU might decide not to keen RTAS around at all (might be the case for secure VMs). Note that kexec still checks for the linux,rtas-xxx properties which has to be fixed. Signed-off-by: Alexey Kardashevskiy --- arch/powerpc/include/asm/rtas.h | 1 + arch/powerpc/kernel/rtas.c | 47 +++++++++++++++------------------ 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 3c1887351c71..60cd528806c1 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h @@ -59,6 +59,7 @@ struct rtas_t { arch_spinlock_t lock; struct rtas_args args; struct device_node *dev; /* virtual address pointer */ + bool hcall; }; struct rtas_suspend_me_data { diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 5faf0a64c92b..0651291ab5ff 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -49,6 +49,14 @@ struct rtas_t rtas = { }; EXPORT_SYMBOL(rtas); +static void __enter_rtas(unsigned long pa) +{ + if (rtas.hcall) + plpar_hcall_norets(H_RTAS, pa); + else + enter_rtas(pa); +} + DEFINE_SPINLOCK(rtas_data_buf_lock); EXPORT_SYMBOL(rtas_data_buf_lock); @@ -95,9 +103,6 @@ static void call_rtas_display_status(unsigned char c) { unsigned long s; - if (!rtas.base) - return; - s = lock_rtas(); rtas_call_unlocked(&rtas.args, 10, 1, 1, NULL, c); unlock_rtas(s); @@ -145,9 +150,6 @@ static void udbg_rtascon_putc(char c) { int tries; - if (!rtas.base) - return; - /* Add CRs before LFs */ if (c == '\n') udbg_rtascon_putc('\r'); @@ -164,9 +166,6 @@ static int udbg_rtascon_getc_poll(void) { int c; - if (!rtas.base) - return -1; - if (rtas_call(rtas_getchar_token, 0, 2, &c)) return -1; @@ -205,9 +204,6 @@ void rtas_progress(char *s, unsigned short hex) static int current_line; static int pending_newline = 0; /* did last write end with unprinted newline? */ - if (!rtas.base) - return; - if (display_width == 0) { display_width = 0x10; if ((root = of_find_node_by_path("/rtas"))) { @@ -382,7 +378,7 @@ static char *__fetch_rtas_last_error(char *altbuf) save_args = rtas.args; rtas.args = err_args; - enter_rtas(__pa(&rtas.args)); + __enter_rtas(__pa(&rtas.args)); err_args = rtas.args; rtas.args = save_args; @@ -428,7 +424,7 @@ va_rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int nret, for (i = 0; i < nret; ++i) args->rets[i] = 0; - enter_rtas(__pa(args)); + __enter_rtas(__pa(args)); } void rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int nret, ...) @@ -449,7 +445,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) char *buff_copy = NULL; int ret; - if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE) + if (token == RTAS_UNKNOWN_SERVICE) return -1; s = lock_rtas(); @@ -1064,9 +1060,6 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs) if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!rtas.entry) - return -EINVAL; - if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0) return -EFAULT; @@ -1115,7 +1108,7 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs) flags = lock_rtas(); rtas.args = args; - enter_rtas(__pa(&rtas.args)); + __enter_rtas(__pa(&rtas.args)); args = rtas.args; /* A -1 return code indicates that the last command couldn't @@ -1149,8 +1142,8 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs) void __init rtas_initialize(void) { unsigned long rtas_region = RTAS_INSTANTIATE_MAX; - u32 base, size, entry; - int no_base, no_size, no_entry; + u32 base = 0, size = 0, entry = 0, do_h_rtas = 0; + int no_base, no_size, no_entry, ret; /* Get RTAS dev node and fill up our "rtas" structure with infos * about it. @@ -1161,17 +1154,15 @@ void __init rtas_initialize(void) no_base = of_property_read_u32(rtas.dev, "linux,rtas-base", &base); no_size = of_property_read_u32(rtas.dev, "rtas-size", &size); - if (no_base || no_size) { - of_node_put(rtas.dev); - rtas.dev = NULL; - return; - } rtas.base = base; rtas.size = size; no_entry = of_property_read_u32(rtas.dev, "linux,rtas-entry", &entry); rtas.entry = no_entry ? rtas.base : entry; + ret = of_property_read_u32(of_chosen, "qemu,h_rtas", &do_h_rtas); + rtas.hcall = !ret && do_h_rtas; + /* If RTAS was found, allocate the RMO buffer for it and look for * the stop-self token if any */ @@ -1208,6 +1199,10 @@ int __init early_init_dt_scan_rtas(unsigned long node, rtas.base = *basep; rtas.entry = *entryp; rtas.size = *sizep; + } else { + rtas.base = 0; + rtas.entry = 0; + rtas.size = 0; } #ifdef CONFIG_UDBG_RTAS_CONSOLE From patchwork Sat Jul 20 01:29:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 1134340 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45r9M667lpz9s8m for ; Sat, 20 Jul 2019 11:31:30 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ozlabs.ru Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 45r9M64N98zDqww for ; Sat, 20 Jul 2019 11:31:30 +1000 (AEST) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=ozlabs.ru (client-ip=107.173.13.209; helo=ozlabs.ru; envelope-from=aik@ozlabs.ru; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=ozlabs.ru Received: from ozlabs.ru (ozlabs.ru [107.173.13.209]) by lists.ozlabs.org (Postfix) with ESMTP id 45r9Js4zDtzDqwL for ; Sat, 20 Jul 2019 11:29:33 +1000 (AEST) Received: from fstn1-p1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 506A6AE807F9; Fri, 19 Jul 2019 21:29:25 -0400 (EDT) From: Alexey Kardashevskiy To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH kernel RFC 2/2] powerpc/pseries: Kexec style ibm, client-architecture-support support Date: Sat, 20 Jul 2019 11:29:19 +1000 Message-Id: <20190720012919.14417-3-aik@ozlabs.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190720012919.14417-1-aik@ozlabs.ru> References: <20190720012919.14417-1-aik@ozlabs.ru> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , kvm-ppc@vger.kernel.org, David Gibson Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" This checks the FDT for "/chosen/qemu,h_cas" and calls H_CAS when present. The H_CAS hcall is implemented in QEMU for ages and currently returns an FDT with a diff to the initial FDT which SLOF updates and returns to the OS. For this patch to work, QEMU needs to provide the full tree instead, so when QEMU is run with the "-machine pseries,bios=no", it reads the existing FDT from the OS, updats it and writes back on top. This changes prom_check_platform_support() not to call the client interface's prom_getproplen() as the kexec-style boot does not provide the client interface services. Signed-off-by: Alexey Kardashevskiy --- arch/powerpc/kernel/prom_init.c | 12 ++++++---- arch/powerpc/kernel/setup_64.c | 41 +++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 514707ef6779..6d8e35cb3c57 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1261,7 +1261,7 @@ static void __init prom_parse_platform_support(u8 index, u8 val, } } -static void __init prom_check_platform_support(void) +struct ibm_arch_vec __init *prom_check_platform_support(int prop_len) { struct platform_support supported = { .hash_mmu = false, @@ -1269,8 +1269,6 @@ static void __init prom_check_platform_support(void) .radix_gtse = false, .xive = false }; - int prop_len = prom_getproplen(prom.chosen, - "ibm,arch-vec-5-platform-support"); /* * First copy the architecture vec template @@ -1319,7 +1317,12 @@ static void __init prom_check_platform_support(void) prom_debug("Asking for XIVE\n"); ibm_architecture_vec.vec5.intarch = OV5_FEAT(OV5_XIVE_EXPLOIT); } + + ibm_architecture_vec.vec5.max_cpus = cpu_to_be32(NR_CPUS); + + return &ibm_architecture_vec; } +EXPORT_SYMBOL_GPL(prom_check_platform_support); static void __init prom_send_capabilities(void) { @@ -1328,7 +1331,8 @@ static void __init prom_send_capabilities(void) u32 cores; /* Check ibm,arch-vec-5-platform-support and fixup vec5 if required */ - prom_check_platform_support(); + prom_check_platform_support(prom_getproplen(prom.chosen, + "ibm,arch-vec-5-platform-support")); root = call_prom("open", 1, 1, ADDR("/")); if (root != 0) { diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 44b4c432a273..6fa384278180 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -284,12 +284,53 @@ void __init record_spr_defaults(void) * device-tree is not accessible via normal means at this point. */ +/* + * The architecture vector has an array of PVR mask/value pairs, + * followed by # option vectors - 1, followed by the option vectors. + * + * See prom.h for the definition of the bits specified in the + * architecture vector. + */ + +extern struct ibm_arch_vec __init *prom_check_platform_support( + int vec5_prop_len); + +int __init early_init_dt_scan_chosen_h_cas(unsigned long node, + const char *uname, int depth, void *data) +{ + int l; + const char *p; + + if (depth != 1 || !data || + (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) + return 0; + p = of_get_flat_dt_prop(node, "qemu,h_cas", &l); + if (p != NULL && l > 0) + *(bool *) data = be32_to_cpu(*(uint32_t *) p) != 0; + + return 1; +} + void __init early_setup(unsigned long dt_ptr) { static __initdata struct paca_struct boot_paca; + struct ibm_arch_vec *vec = prom_check_platform_support(0); /* -------- printk is _NOT_ safe to use here ! ------- */ + /* ibm,client-architecture-support support */ +#define KVMPPC_HCALL_BASE 0xf000 +#define KVMPPC_H_CAS (KVMPPC_HCALL_BASE + 0x2) +#define FDT_MAX_SIZE 0x100000 + bool do_h_cas = false; + + if (early_init_dt_verify(__va(dt_ptr))) { + of_scan_flat_dt(early_init_dt_scan_chosen_h_cas, &do_h_cas); + if (do_h_cas) + plpar_hcall_norets(KVMPPC_H_CAS, vec, dt_ptr, + FDT_MAX_SIZE); + } + /* Try new device tree based feature discovery ... */ if (!dt_cpu_ftrs_init(__va(dt_ptr))) /* Otherwise use the old style CPU table */