All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 00/10] OPAL V4
@ 2020-05-02 11:19 Nicholas Piggin
  2020-05-02 11:19 ` [RFC PATCH 01/10] kallsyms: architecture specific symbol lookups Nicholas Piggin
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Nicholas Piggin @ 2020-05-02 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

"OPAL V4" is a proposed new approach to running and calling PowerNV
OPAL firmware.

OPAL calls use the caller's (kernel) stack, which vastly simplifies
re-entrancy concerns around doing things like idle and machine check
OPAL drivers.

The OS can get at symbol and assert metadata to help with debugging
firmware.

OPAL may be called (and will run in) virtual mode in its own address
space.

And the operating system provides some services to the firmware,
message logging, for example.

This fairly close to the point where we could run OPAL in user-mode
with a few services (scv could be used to call back to the OS) for
privileged instructions, we may yet do this, but one thing that's
stopped me is it would require a slower API. As it is now with LE
skiboot and LE Linux, the OPAL call is basically a shared-library
function call, which is fast enough that it's feasible to
implement a performant CPU idle driver, which is a significant
motivation.

Anyway this is up and running, coming together pretty well just needs
a bit of polishing and more documentation. I'll post the skiboot
patches on the skiboot list.

Nicholas Piggin (10):
  kallsyms: architecture specific symbol lookups
  powerpc/powernv: Wire up OPAL address lookups
  powerpc/powernv: Use OPAL_REPORT_TRAP to cope with trap interrupts
    from OPAL
  powerpc/powernv: avoid polling in opal_get_chars
  powerpc/powernv: Don't translate kernel addresses to real addresses
    for OPAL
  powerpc/powernv: opal use new opal call entry point if it exists
  powerpc/powernv: Add OPAL_FIND_VM_AREA API
  powerpc/powernv: Set up an mm context to call OPAL in
  powerpc/powernv: OPAL V4 OS services
  powerpc/powernv: OPAL V4 Implement vm_map/unmap service

 arch/powerpc/Kconfig                          |   1 +
 arch/powerpc/boot/opal.c                      |   5 +
 arch/powerpc/include/asm/opal-api.h           |  29 +-
 arch/powerpc/include/asm/opal.h               |   8 +
 arch/powerpc/kernel/traps.c                   |  39 ++-
 arch/powerpc/perf/imc-pmu.c                   |   4 +-
 arch/powerpc/platforms/powernv/npu-dma.c      |   2 +-
 arch/powerpc/platforms/powernv/opal-call.c    |  58 ++++
 arch/powerpc/platforms/powernv/opal-dump.c    |   2 +-
 arch/powerpc/platforms/powernv/opal-elog.c    |   4 +-
 arch/powerpc/platforms/powernv/opal-flash.c   |   6 +-
 arch/powerpc/platforms/powernv/opal-hmi.c     |   2 +-
 arch/powerpc/platforms/powernv/opal-nvram.c   |   4 +-
 .../powerpc/platforms/powernv/opal-powercap.c |   2 +-
 arch/powerpc/platforms/powernv/opal-psr.c     |   2 +-
 arch/powerpc/platforms/powernv/opal-xscom.c   |   2 +-
 arch/powerpc/platforms/powernv/opal.c         | 289 ++++++++++++++++--
 arch/powerpc/platforms/powernv/pci-ioda.c     |   2 +-
 arch/powerpc/sysdev/xive/native.c             |   2 +-
 drivers/char/powernv-op-panel.c               |   3 +-
 drivers/i2c/busses/i2c-opal.c                 |  12 +-
 drivers/mtd/devices/powernv_flash.c           |   4 +-
 include/linux/kallsyms.h                      |  20 ++
 kernel/kallsyms.c                             |  13 +-
 lib/Kconfig                                   |   3 +
 25 files changed, 461 insertions(+), 57 deletions(-)

-- 
2.23.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFC PATCH 01/10] kallsyms: architecture specific symbol lookups
  2020-05-02 11:19 [RFC PATCH 00/10] OPAL V4 Nicholas Piggin
@ 2020-05-02 11:19 ` Nicholas Piggin
  2020-05-02 11:19 ` [RFC PATCH 02/10] powerpc/powernv: Wire up OPAL address lookups Nicholas Piggin
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Nicholas Piggin @ 2020-05-02 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

Provide CONFIG_ARCH_HAS_SYMBOL_LOOKUP which allows architectures to
do their own symbol/address lookup if kernel and module lookups miss.

powerpc will use this to deal with firmware symbols.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 include/linux/kallsyms.h | 20 ++++++++++++++++++++
 kernel/kallsyms.c        | 13 ++++++++++++-
 lib/Kconfig              |  3 +++
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index 657a83b943f0..e17c1e7c01c0 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -83,6 +83,26 @@ extern int kallsyms_lookup_size_offset(unsigned long addr,
 				  unsigned long *symbolsize,
 				  unsigned long *offset);
 
+#ifdef CONFIG_ARCH_HAS_SYMBOL_LOOKUP
+const char *arch_symbol_lookup_address(unsigned long addr,
+			    unsigned long *symbolsize,
+			    unsigned long *offset,
+			    char **modname, char *namebuf);
+unsigned long arch_symbol_lookup_name(const char *name);
+#else
+static inline const char *arch_symbol_lookup_address(unsigned long addr,
+			    unsigned long *symbolsize,
+			    unsigned long *offset,
+			    char **modname, char *namebuf)
+{
+	return NULL;
+}
+static inline unsigned long arch_symbol_lookup_name(const char *name)
+{
+	return 0;
+}
+#endif
+
 /* Lookup an address.  modname is set to NULL if it's in the kernel. */
 const char *kallsyms_lookup(unsigned long addr,
 			    unsigned long *symbolsize,
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 16c8c605f4b0..1e403e616126 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -164,6 +164,7 @@ static unsigned long kallsyms_sym_address(int idx)
 unsigned long kallsyms_lookup_name(const char *name)
 {
 	char namebuf[KSYM_NAME_LEN];
+	unsigned long ret;
 	unsigned long i;
 	unsigned int off;
 
@@ -173,7 +174,12 @@ unsigned long kallsyms_lookup_name(const char *name)
 		if (strcmp(namebuf, name) == 0)
 			return kallsyms_sym_address(i);
 	}
-	return module_kallsyms_lookup_name(name);
+
+	ret = module_kallsyms_lookup_name(name);
+	if (ret)
+		return ret;
+
+	return arch_symbol_lookup_name(name);
 }
 
 int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
@@ -309,6 +315,11 @@ const char *kallsyms_lookup(unsigned long addr,
 	if (!ret)
 		ret = ftrace_mod_address_lookup(addr, symbolsize,
 						offset, modname, namebuf);
+
+	if (!ret)
+		ret = arch_symbol_lookup_address(addr, symbolsize,
+						offset, modname, namebuf);
+
 	return ret;
 }
 
diff --git a/lib/Kconfig b/lib/Kconfig
index 5d53f9609c25..9f86f649a712 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -80,6 +80,9 @@ config ARCH_USE_CMPXCHG_LOCKREF
 config ARCH_HAS_FAST_MULTIPLIER
 	bool
 
+config ARCH_HAS_SYMBOL_LOOKUP
+	bool
+
 config INDIRECT_PIO
 	bool "Access I/O in non-MMIO mode"
 	depends on ARM64
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 02/10] powerpc/powernv: Wire up OPAL address lookups
  2020-05-02 11:19 [RFC PATCH 00/10] OPAL V4 Nicholas Piggin
  2020-05-02 11:19 ` [RFC PATCH 01/10] kallsyms: architecture specific symbol lookups Nicholas Piggin
@ 2020-05-02 11:19 ` Nicholas Piggin
  2020-05-02 11:19 ` [RFC PATCH 03/10] powerpc/powernv: Use OPAL_REPORT_TRAP to cope with trap interrupts from OPAL Nicholas Piggin
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Nicholas Piggin @ 2020-05-02 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

Use ARCH_HAS_SYMBOL_LOOKUP to look up the opal symbol table. This
allows crashes and xmon debugging to print firmware symbols.

  Oops: System Reset, sig: 6 [#1]
  LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV
  Modules linked in:
  CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.6.0-rc2-dirty #903
  NIP:  0000000030020434 LR: 000000003000378c CTR: 0000000030020414
  REGS: c0000000fffc3d70 TRAP: 0100   Not tainted  (5.6.0-rc2-dirty)
  MSR:  9000000002101002 <SF,HV,VEC,ME,RI>  CR: 28022284  XER: 20040000
  CFAR: 0000000030003788 IRQMASK: 3
  GPR00: 000000003000378c 0000000031c13c90 0000000030136200 c0000000012cfa10
  GPR04: c0000000012cfa10 0000000000000010 0000000000000000 0000000031c10060
  GPR08: c0000000012cfaaf 0000000030003640 0000000000000000 0000000000000001
  GPR12: 00000000300e0000 c000000001490000 0000000000000000 c00000000139c588
  GPR16: 0000000031c10000 c00000000125a900 0000000000000000 c0000000012076a8
  GPR20: c0000000012a3950 0000000000000001 0000000031c10060 c0000000012cfaaf
  GPR24: 0000000000000019 0000000030003640 0000000000000000 0000000000000000
  GPR28: 0000000000000010 c0000000012cfa10 0000000000000000 0000000000000000
  NIP [0000000030020434] .dummy_console_write_buffer_space+0x20/0x64 [OPAL]
  LR [000000003000378c] opal_entry+0x14c/0x17c [OPAL]

This won't unwind the firmware stack (or its Linux caller) properly if
firmware and kernel endians don't match, but that problem could be solved
in powerpc's unwinder.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/Kconfig                       |  1 +
 arch/powerpc/include/asm/opal-api.h        |  4 ++-
 arch/powerpc/include/asm/opal.h            |  3 ++
 arch/powerpc/platforms/powernv/opal-call.c |  2 ++
 arch/powerpc/platforms/powernv/opal.c      | 40 ++++++++++++++++++++++
 5 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 924c541a9260..0be717291e38 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -115,6 +115,7 @@ config PPC
 	# Please keep this list sorted alphabetically.
 	#
 	select ARCH_32BIT_OFF_T if PPC32
+	select ARCH_HAS_SYMBOL_LOOKUP		if PPC_POWERNV
 	select ARCH_HAS_DEBUG_VIRTUAL
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_ELF_RANDOMIZE
diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index 1dffa3cb16ba..8eb31b9aeb27 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -214,7 +214,9 @@
 #define OPAL_SECVAR_GET				176
 #define OPAL_SECVAR_GET_NEXT			177
 #define OPAL_SECVAR_ENQUEUE_UPDATE		178
-#define OPAL_LAST				178
+#define OPAL_ADDR_TO_SYM			181
+#define OPAL_SYM_TO_ADDR			182
+#define OPAL_LAST				182
 
 #define QUIESCE_HOLD			1 /* Spin all calls at entry */
 #define QUIESCE_REJECT			2 /* Fail all calls with OPAL_BUSY */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 9986ac34b8e2..56b6994aefb7 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -312,6 +312,9 @@ s64 opal_mpipl_query_tag(enum opal_mpipl_tags tag, u64 *addr);
 s64 opal_signal_system_reset(s32 cpu);
 s64 opal_quiesce(u64 shutdown_type, s32 cpu);
 
+int64_t opal_addr_to_sym(uint64_t addr, __be64 *symaddr, __be64 *symsize, char *namebuf, uint64_t buflen);
+int64_t opal_sym_to_addr(const char *name, __be64 *symaddr, __be64 *symsize);
+
 /* Internal functions */
 extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
 				   int depth, void *data);
diff --git a/arch/powerpc/platforms/powernv/opal-call.c b/arch/powerpc/platforms/powernv/opal-call.c
index 5cd0f52d258f..2233a58924cb 100644
--- a/arch/powerpc/platforms/powernv/opal-call.c
+++ b/arch/powerpc/platforms/powernv/opal-call.c
@@ -293,3 +293,5 @@ OPAL_CALL(opal_mpipl_query_tag,			OPAL_MPIPL_QUERY_TAG);
 OPAL_CALL(opal_secvar_get,			OPAL_SECVAR_GET);
 OPAL_CALL(opal_secvar_get_next,			OPAL_SECVAR_GET_NEXT);
 OPAL_CALL(opal_secvar_enqueue_update,		OPAL_SECVAR_ENQUEUE_UPDATE);
+OPAL_CALL(opal_addr_to_sym,			OPAL_ADDR_TO_SYM);
+OPAL_CALL(opal_sym_to_addr,			OPAL_SYM_TO_ADDR);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 2b3dfd0b6cdd..1bf2e0b31ecf 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -107,6 +107,46 @@ void opal_configure_cores(void)
 		cur_cpu_spec->cpu_restore();
 }
 
+const char *arch_symbol_lookup_address(unsigned long addr,
+			    unsigned long *symbolsize,
+			    unsigned long *offset,
+			    char **modname, char *namebuf)
+{
+	__be64 symaddr;
+	__be64 symsize;
+
+	if (!firmware_has_feature(FW_FEATURE_OPAL))
+		return NULL;
+
+	if (opal_addr_to_sym(addr, &symaddr, &symsize, namebuf,
+			cpu_to_be64(KSYM_NAME_LEN)) != OPAL_SUCCESS)
+		return NULL;
+
+	*symbolsize = be64_to_cpu(symsize);
+	*offset = addr - be64_to_cpu(symaddr);
+	*modname = "OPAL";
+
+	return namebuf;
+}
+
+unsigned long arch_symbol_lookup_name(const char *name)
+{
+	__be64 addr;
+	__be64 size;
+
+	if (!firmware_has_feature(FW_FEATURE_OPAL))
+		return 0;
+
+	/* opal: prefix allows lookup of symbols that clash with kernel */
+	if (!strncasecmp(name, "opal:", strlen("opal:")))
+		name += strlen("opal:");
+
+	if (opal_sym_to_addr(name, &addr, &size) != OPAL_SUCCESS)
+		return 0;
+
+	return be64_to_cpu(addr);
+}
+
 int __init early_init_dt_scan_opal(unsigned long node,
 				   const char *uname, int depth, void *data)
 {
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 03/10] powerpc/powernv: Use OPAL_REPORT_TRAP to cope with trap interrupts from OPAL
  2020-05-02 11:19 [RFC PATCH 00/10] OPAL V4 Nicholas Piggin
  2020-05-02 11:19 ` [RFC PATCH 01/10] kallsyms: architecture specific symbol lookups Nicholas Piggin
  2020-05-02 11:19 ` [RFC PATCH 02/10] powerpc/powernv: Wire up OPAL address lookups Nicholas Piggin
@ 2020-05-02 11:19 ` Nicholas Piggin
  2020-05-02 14:30   ` kbuild test robot
  2020-05-02 11:19 ` [RFC PATCH 04/10] powerpc/powernv: avoid polling in opal_get_chars Nicholas Piggin
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Nicholas Piggin @ 2020-05-02 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

This isn't used yet, because OPAL is nice enough not to cause unexpected
program check interrupts to the OS. A future patch will allow OPAL to
start using traps. Like so.

  [OPAL] < assert failed at core/opal.c:814 >
  [OPAL]     .
  [OPAL]      .
  [OPAL]       .
  [OPAL]         OO__)
  [OPAL]        <"__/
  [OPAL]         ^ ^
   cpu 0x0: Vector: 700 (Program Check) at [c000000080287770]
       pc: 000000003002f360: opal_poll_events+0x54/0x174 [OPAL]
       lr: 000000003002f344: opal_poll_events+0x38/0x174 [OPAL]
       sp: c000000080287a00
      msr: 9000000000021033
     current = 0xc0000000016fa100
     paca    = 0xc0000000012c0000^I irqmask: 0x03^I irq_happened: 0x01
       pid   = 19, comm = kopald
   Linux version 5.7.0-rc3-00053-g2d9c3c965178-dirty
   enter ? for help
   [c000000080287a80] 000000003002e6b8 opal_v4_le_entry+0x224/0x29c [OPAL]
   [c000000080287b50] c000000000096ce8 opal_call+0x1c8/0x580
   [c000000080287c90] c000000000097448 opal_poll_events+0x28/0x40
   [c000000080287d00] c0000000000a26e0 opal_handle_events+0x70/0x140
   [c000000080287d50] c00000000009a198 kopald+0x98/0x140
   [c000000080287db0] c00000000012139c kthread+0x18c/0x1a0
   [c000000080287e20] c00000000000cc28 ret_from_kernel_thread+0x5c/0x74

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/include/asm/opal-api.h        |  7 +++-
 arch/powerpc/include/asm/opal.h            |  2 ++
 arch/powerpc/kernel/traps.c                | 39 ++++++++++++++++------
 arch/powerpc/platforms/powernv/opal-call.c |  1 +
 4 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index 8eb31b9aeb27..018d4734c323 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -216,7 +216,8 @@
 #define OPAL_SECVAR_ENQUEUE_UPDATE		178
 #define OPAL_ADDR_TO_SYM			181
 #define OPAL_SYM_TO_ADDR			182
-#define OPAL_LAST				182
+#define OPAL_REPORT_TRAP			183
+#define OPAL_LAST				183
 
 #define QUIESCE_HOLD			1 /* Spin all calls at entry */
 #define QUIESCE_REJECT			2 /* Fail all calls with OPAL_BUSY */
@@ -1184,6 +1185,10 @@ struct opal_mpipl_fadump {
 	struct	opal_mpipl_region region[];
 } __packed;
 
+#define OPAL_TRAP_FATAL	1
+#define OPAL_TRAP_WARN	2
+#define OPAL_TRAP_PANIC	3
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 56b6994aefb7..dc77c2d5e036 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -314,6 +314,8 @@ s64 opal_quiesce(u64 shutdown_type, s32 cpu);
 
 int64_t opal_addr_to_sym(uint64_t addr, __be64 *symaddr, __be64 *symsize, char *namebuf, uint64_t buflen);
 int64_t opal_sym_to_addr(const char *name, __be64 *symaddr, __be64 *symsize);
+int64_t opal_report_trap(uint64_t nip);
+
 
 /* Internal functions */
 extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 3fca22276bb1..0274ae7b8a03 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -52,6 +52,7 @@
 #endif
 #ifdef CONFIG_PPC64
 #include <asm/firmware.h>
+#include <asm/opal.h>
 #include <asm/processor.h>
 #include <asm/tm.h>
 #endif
@@ -1471,7 +1472,6 @@ void program_check_exception(struct pt_regs *regs)
 		goto bail;
 	}
 	if (reason & REASON_TRAP) {
-		unsigned long bugaddr;
 		/* Debugger is first in line to stop recursive faults in
 		 * rcu_lock, notify_die, or atomic_notifier_call_chain */
 		if (debugger_bpt(regs))
@@ -1485,18 +1485,35 @@ void program_check_exception(struct pt_regs *regs)
 				== NOTIFY_STOP)
 			goto bail;
 
-		bugaddr = regs->nip;
-		/*
-		 * Fixup bugaddr for BUG_ON() in real mode
-		 */
-		if (!is_kernel_addr(bugaddr) && !(regs->msr & MSR_IR))
-			bugaddr += PAGE_OFFSET;
+		if (!(regs->msr & MSR_PR)) { /* not user-mode */
+			unsigned long bugaddr;
+			enum bug_trap_type t;
+
+			/*
+			 * Fixup bugaddr for BUG_ON() in real mode
+			 */
+			bugaddr = regs->nip;
+			if (!is_kernel_addr(bugaddr) && !(regs->msr & MSR_IR))
+				bugaddr += PAGE_OFFSET;
+			t = report_bug(bugaddr, regs);
+			if (t == BUG_TRAP_TYPE_WARN) {
+				regs->nip += 4;
+				goto bail;
+			}
+			if (t == BUG_TRAP_TYPE_BUG)
+				goto bug;
 
-		if (!(regs->msr & MSR_PR) &&  /* not user-mode */
-		    report_bug(bugaddr, regs) == BUG_TRAP_TYPE_WARN) {
-			regs->nip += 4;
-			goto bail;
+			if (firmware_has_feature(FW_FEATURE_OPAL)) {
+				int64_t ret;
+
+				ret = opal_report_trap(regs->nip);
+				if (ret == OPAL_TRAP_WARN) {
+					regs->nip += 4;
+					goto bail;
+				}
+			}
 		}
+bug:
 		_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
 		goto bail;
 	}
diff --git a/arch/powerpc/platforms/powernv/opal-call.c b/arch/powerpc/platforms/powernv/opal-call.c
index 2233a58924cb..506b1798081a 100644
--- a/arch/powerpc/platforms/powernv/opal-call.c
+++ b/arch/powerpc/platforms/powernv/opal-call.c
@@ -295,3 +295,4 @@ OPAL_CALL(opal_secvar_get_next,			OPAL_SECVAR_GET_NEXT);
 OPAL_CALL(opal_secvar_enqueue_update,		OPAL_SECVAR_ENQUEUE_UPDATE);
 OPAL_CALL(opal_addr_to_sym,			OPAL_ADDR_TO_SYM);
 OPAL_CALL(opal_sym_to_addr,			OPAL_SYM_TO_ADDR);
+OPAL_CALL(opal_report_trap,			OPAL_REPORT_TRAP);
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 04/10] powerpc/powernv: avoid polling in opal_get_chars
  2020-05-02 11:19 [RFC PATCH 00/10] OPAL V4 Nicholas Piggin
                   ` (2 preceding siblings ...)
  2020-05-02 11:19 ` [RFC PATCH 03/10] powerpc/powernv: Use OPAL_REPORT_TRAP to cope with trap interrupts from OPAL Nicholas Piggin
@ 2020-05-02 11:19 ` Nicholas Piggin
  2020-05-02 11:19 ` [RFC PATCH 05/10] powerpc/powernv: Don't translate kernel addresses to real addresses for OPAL Nicholas Piggin
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Nicholas Piggin @ 2020-05-02 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

OPAL console IO should avoid locks and complexity where possible, to
maximise the chance of it working if there are crashes or bugs. This
poll is not necessary, opal_console_read can handle no input.

In a future patch, Linux will provide a console service to OPAL via the
OPAL console, so it must avoid using any other OPAL calls in this path.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/platforms/powernv/opal.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 1bf2e0b31ecf..e8eba210a92d 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -467,13 +467,10 @@ static int __init opal_message_init(struct device_node *opal_node)
 int opal_get_chars(uint32_t vtermno, char *buf, int count)
 {
 	s64 rc;
-	__be64 evt, len;
+	__be64 len;
 
 	if (!opal.entry)
 		return -ENODEV;
-	opal_poll_events(&evt);
-	if ((be64_to_cpu(evt) & OPAL_EVENT_CONSOLE_INPUT) == 0)
-		return 0;
 	len = cpu_to_be64(count);
 	rc = opal_console_read(vtermno, &len, buf);
 	if (rc == OPAL_SUCCESS)
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 05/10] powerpc/powernv: Don't translate kernel addresses to real addresses for OPAL
  2020-05-02 11:19 [RFC PATCH 00/10] OPAL V4 Nicholas Piggin
                   ` (3 preceding siblings ...)
  2020-05-02 11:19 ` [RFC PATCH 04/10] powerpc/powernv: avoid polling in opal_get_chars Nicholas Piggin
@ 2020-05-02 11:19 ` Nicholas Piggin
  2020-05-02 11:19 ` [RFC PATCH 06/10] powerpc/powernv: opal use new opal call entry point if it exists Nicholas Piggin
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Nicholas Piggin @ 2020-05-02 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

A random assortment of OPAL callers use __pa() on pointers (others don't).

This is not required because __pa() behaves the same as __va() when
translation is off. In order to run OPAL with translation on, the
effective addresses have to be used.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/perf/imc-pmu.c                    |  4 ++--
 arch/powerpc/platforms/powernv/npu-dma.c       |  2 +-
 arch/powerpc/platforms/powernv/opal-dump.c     |  2 +-
 arch/powerpc/platforms/powernv/opal-elog.c     |  4 ++--
 arch/powerpc/platforms/powernv/opal-flash.c    |  6 +++---
 arch/powerpc/platforms/powernv/opal-hmi.c      |  2 +-
 arch/powerpc/platforms/powernv/opal-nvram.c    |  4 ++--
 arch/powerpc/platforms/powernv/opal-powercap.c |  2 +-
 arch/powerpc/platforms/powernv/opal-psr.c      |  2 +-
 arch/powerpc/platforms/powernv/opal-xscom.c    |  2 +-
 arch/powerpc/platforms/powernv/opal.c          |  6 +++---
 arch/powerpc/platforms/powernv/pci-ioda.c      |  2 +-
 arch/powerpc/sysdev/xive/native.c              |  2 +-
 drivers/char/powernv-op-panel.c                |  3 +--
 drivers/i2c/busses/i2c-opal.c                  | 12 ++++++------
 drivers/mtd/devices/powernv_flash.c            |  4 ++--
 16 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index eb82dda884e5..332c7a3398f3 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -610,7 +610,7 @@ static int core_imc_mem_init(int cpu, int size)
 	mutex_init(&core_imc_refc[core_id].lock);
 
 	rc = opal_imc_counters_init(OPAL_IMC_COUNTERS_CORE,
-				__pa((void *)mem_info->vbase),
+				(u64)mem_info->vbase,
 				get_hard_smp_processor_id(cpu));
 	if (rc) {
 		free_pages((u64)mem_info->vbase, get_order(size));
@@ -1209,7 +1209,7 @@ static int trace_imc_mem_alloc(int cpu_id, int size)
 		per_cpu(trace_imc_mem, cpu_id) = local_mem;
 
 		/* Initialise the counters for trace mode */
-		rc = opal_imc_counters_init(OPAL_IMC_COUNTERS_TRACE, __pa((void *)local_mem),
+		rc = opal_imc_counters_init(OPAL_IMC_COUNTERS_TRACE, (u64)local_mem,
 					    get_hard_smp_processor_id(cpu_id));
 		if (rc) {
 			pr_info("IMC:opal init failed for trace imc\n");
diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c
index b95b9e3c4c98..9d38a30cc27e 100644
--- a/arch/powerpc/platforms/powernv/npu-dma.c
+++ b/arch/powerpc/platforms/powernv/npu-dma.c
@@ -149,7 +149,7 @@ static long pnv_npu_set_window(struct iommu_table_group *table_group, int num,
 			npe->pe_number,
 			npe->pe_number,
 			tbl->it_indirect_levels + 1,
-			__pa(tbl->it_base),
+			__pa(tbl->it_base), /* XXX? */
 			size << 3,
 			IOMMU_PAGE_SIZE(tbl));
 	if (rc) {
diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c
index 543c816fa99e..94d5fb716a32 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -256,7 +256,7 @@ static int64_t dump_read_data(struct dump_obj *dump)
 	}
 
 	/* First entry address */
-	addr = __pa(list);
+	addr = (u64)list;
 
 	/* Fetch data */
 	rc = OPAL_BUSY_EVENT;
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c
index 62ef7ad995da..6af5ff892195 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -163,7 +163,7 @@ static ssize_t raw_attr_read(struct file *filep, struct kobject *kobj,
 		if (!elog->buffer)
 			return -EIO;
 
-		opal_rc = opal_read_elog(__pa(elog->buffer),
+		opal_rc = opal_read_elog((u64)elog->buffer,
 					 elog->size, elog->id);
 		if (opal_rc != OPAL_SUCCESS) {
 			pr_err("ELOG: log read failed for log-id=%llx\n",
@@ -206,7 +206,7 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type)
 	elog->buffer = kzalloc(elog->size, GFP_KERNEL);
 
 	if (elog->buffer) {
-		rc = opal_read_elog(__pa(elog->buffer),
+		rc = opal_read_elog((u64)elog->buffer,
 					 elog->size, elog->id);
 		if (rc != OPAL_SUCCESS) {
 			pr_err("ELOG: log read failed for log-id=%llx\n",
diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c
index 7e7d38b17420..46f02279d36a 100644
--- a/arch/powerpc/platforms/powernv/opal-flash.c
+++ b/arch/powerpc/platforms/powernv/opal-flash.c
@@ -130,11 +130,11 @@ static DEFINE_MUTEX(image_data_mutex);
 static inline void opal_flash_validate(void)
 {
 	long ret;
-	void *buf = validate_flash_data.buf;
+	u64 buf = (u64)validate_flash_data.buf;
 	__be32 size = cpu_to_be32(validate_flash_data.buf_size);
 	__be32 result;
 
-	ret = opal_validate_flash(__pa(buf), &size, &result);
+	ret = opal_validate_flash(buf, &size, &result);
 
 	validate_flash_data.status = ret;
 	validate_flash_data.buf_size = be32_to_cpu(size);
@@ -290,7 +290,7 @@ static int opal_flash_update(int op)
 		goto invalid_img;
 
 	/* First entry address */
-	addr = __pa(list);
+	addr = (u64)list;
 
 flash:
 	rc = opal_update_flash(addr);
diff --git a/arch/powerpc/platforms/powernv/opal-hmi.c b/arch/powerpc/platforms/powernv/opal-hmi.c
index 3e1f064a18db..7c51baeb62ff 100644
--- a/arch/powerpc/platforms/powernv/opal-hmi.c
+++ b/arch/powerpc/platforms/powernv/opal-hmi.c
@@ -298,7 +298,7 @@ static void hmi_event_handler(struct work_struct *work)
 
 	if (unrecoverable) {
 		/* Pull all HMI events from OPAL before we panic. */
-		while (opal_get_msg(__pa(&msg), sizeof(msg)) == OPAL_SUCCESS) {
+		while (opal_get_msg((u64)&msg, sizeof(msg)) == OPAL_SUCCESS) {
 			u32 type;
 
 			type = be32_to_cpu(msg.msg_type);
diff --git a/arch/powerpc/platforms/powernv/opal-nvram.c b/arch/powerpc/platforms/powernv/opal-nvram.c
index 380bc2d7ebbf..a7924dffee2b 100644
--- a/arch/powerpc/platforms/powernv/opal-nvram.c
+++ b/arch/powerpc/platforms/powernv/opal-nvram.c
@@ -33,7 +33,7 @@ static ssize_t opal_nvram_read(char *buf, size_t count, loff_t *index)
 	off = *index;
 	if ((off + count) > nvram_size)
 		count = nvram_size - off;
-	rc = opal_read_nvram(__pa(buf), count, off);
+	rc = opal_read_nvram((unsigned long)buf, count, off);
 	if (rc != OPAL_SUCCESS)
 		return -EIO;
 	*index += count;
@@ -56,7 +56,7 @@ static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index)
 		count = nvram_size - off;
 
 	while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
-		rc = opal_write_nvram(__pa(buf), count, off);
+		rc = opal_write_nvram((unsigned long)buf, count, off);
 		if (rc == OPAL_BUSY_EVENT) {
 			if (in_interrupt() || irqs_disabled())
 				mdelay(OPAL_BUSY_DELAY_MS);
diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c
index c16d44f6f1d1..a1167ecf9e43 100644
--- a/arch/powerpc/platforms/powernv/opal-powercap.c
+++ b/arch/powerpc/platforms/powernv/opal-powercap.c
@@ -46,7 +46,7 @@ static ssize_t powercap_show(struct kobject *kobj, struct kobj_attribute *attr,
 	if (ret)
 		goto out_token;
 
-	ret = opal_get_powercap(pcap_attr->handle, token, (u32 *)__pa(&pcap));
+	ret = opal_get_powercap(pcap_attr->handle, token, &pcap);
 	switch (ret) {
 	case OPAL_ASYNC_COMPLETION:
 		ret = opal_async_wait_response(token, &msg);
diff --git a/arch/powerpc/platforms/powernv/opal-psr.c b/arch/powerpc/platforms/powernv/opal-psr.c
index 69d7e75950d1..a3a68f53b1f8 100644
--- a/arch/powerpc/platforms/powernv/opal-psr.c
+++ b/arch/powerpc/platforms/powernv/opal-psr.c
@@ -40,7 +40,7 @@ static ssize_t psr_show(struct kobject *kobj, struct kobj_attribute *attr,
 		goto out_token;
 
 	ret = opal_get_power_shift_ratio(psr_attr->handle, token,
-					    (u32 *)__pa(&psr));
+					    (u32 *)&psr);
 	switch (ret) {
 	case OPAL_ASYNC_COMPLETION:
 		ret = opal_async_wait_response(token, &msg);
diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c
index fd510d961b8c..aef596997ad4 100644
--- a/arch/powerpc/platforms/powernv/opal-xscom.c
+++ b/arch/powerpc/platforms/powernv/opal-xscom.c
@@ -58,7 +58,7 @@ static int opal_scom_read(uint32_t chip, uint64_t addr, u64 reg, u64 *value)
 	__be64 v;
 
 	reg = opal_scom_unmangle(addr + reg);
-	rc = opal_xscom_read(chip, reg, (__be64 *)__pa(&v));
+	rc = opal_xscom_read(chip, reg, &v);
 	if (rc) {
 		*value = 0xfffffffffffffffful;
 		return -EIO;
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index e8eba210a92d..a0e9808237b2 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -397,7 +397,7 @@ static void opal_handle_message(void)
 	s64 ret;
 	u32 type;
 
-	ret = opal_get_msg(__pa(opal_msg), opal_msg_size);
+	ret = opal_get_msg((u64)opal_msg, opal_msg_size);
 	/* No opal message pending. */
 	if (ret == OPAL_RESOURCE)
 		return;
@@ -961,7 +961,7 @@ static void __init opal_dump_region_init(void)
 		return;
 
 	rc = opal_register_dump_region(OPAL_DUMP_REGION_LOG_BUF,
-				       __pa(addr), size);
+				       (u64)addr, size);
 	/* Don't warn if this is just an older OPAL that doesn't
 	 * know about that call
 	 */
@@ -1197,7 +1197,7 @@ struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
 			sg->length = cpu_to_be64(
 					i * sizeof(struct opal_sg_entry) + 16);
 			i = 0;
-			sg->next = cpu_to_be64(__pa(next));
+			sg->next = cpu_to_be64(next);
 			sg = next;
 		}
 
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 57d3a6af1d52..dc6caec7cb46 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1844,7 +1844,7 @@ static int pnv_pci_ioda_dma_64bit_bypass(struct pnv_ioda_pe *pe)
 					/* reconfigure window 0 */
 					(pe->pe_number << 1) + 0,
 					1,
-					__pa(tces),
+					__pa(tces), /* XXX? */
 					table_size,
 					1 << tce_order);
 	if (rc == OPAL_SUCCESS) {
diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c
index 5218fdc4b29a..a80960829bf0 100644
--- a/arch/powerpc/sysdev/xive/native.c
+++ b/arch/powerpc/sysdev/xive/native.c
@@ -647,7 +647,7 @@ static bool xive_native_provision_pages(void)
 			pr_err("Failed to allocate provisioning page\n");
 			return false;
 		}
-		opal_xive_donate_page(chip, __pa(p));
+		opal_xive_donate_page(chip, (u64)p);
 	}
 	return true;
 }
diff --git a/drivers/char/powernv-op-panel.c b/drivers/char/powernv-op-panel.c
index 027484ecfb0d..e7569f5025ef 100644
--- a/drivers/char/powernv-op-panel.c
+++ b/drivers/char/powernv-op-panel.c
@@ -175,8 +175,7 @@ static int oppanel_probe(struct platform_device *pdev)
 	memset(oppanel_data, ' ', oppanel_size);
 	for (i = 0; i < num_lines; i++) {
 		oppanel_lines[i].line_len = cpu_to_be64(line_len);
-		oppanel_lines[i].line = cpu_to_be64(__pa(&oppanel_data[i *
-						line_len]));
+		oppanel_lines[i].line = cpu_to_be64(&oppanel_data[i * line_len]);
 	}
 
 	rc = misc_register(&oppanel_dev);
diff --git a/drivers/i2c/busses/i2c-opal.c b/drivers/i2c/busses/i2c-opal.c
index 1c4c9bb06a0b..a2ea1e36d9aa 100644
--- a/drivers/i2c/busses/i2c-opal.c
+++ b/drivers/i2c/busses/i2c-opal.c
@@ -87,7 +87,7 @@ static int i2c_opal_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 			OPAL_I2C_RAW_READ : OPAL_I2C_RAW_WRITE;
 		req.addr = cpu_to_be16(msgs[0].addr);
 		req.size = cpu_to_be32(msgs[0].len);
-		req.buffer_ra = cpu_to_be64(__pa(msgs[0].buf));
+		req.buffer_ra = cpu_to_be64(msgs[0].buf);
 		break;
 	case 2:
 		req.type = (msgs[1].flags & I2C_M_RD) ?
@@ -98,7 +98,7 @@ static int i2c_opal_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 			req.subaddr = (req.subaddr << 8) | msgs[0].buf[i];
 		req.subaddr = cpu_to_be32(req.subaddr);
 		req.size = cpu_to_be32(msgs[1].len);
-		req.buffer_ra = cpu_to_be64(__pa(msgs[1].buf));
+		req.buffer_ra = cpu_to_be64(msgs[1].buf);
 		break;
 	}
 
@@ -123,7 +123,7 @@ static int i2c_opal_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 	req.addr = cpu_to_be16(addr);
 	switch (size) {
 	case I2C_SMBUS_BYTE:
-		req.buffer_ra = cpu_to_be64(__pa(&data->byte));
+		req.buffer_ra = cpu_to_be64(&data->byte);
 		req.size = cpu_to_be32(1);
 		/* Fall through */
 	case I2C_SMBUS_QUICK:
@@ -131,7 +131,7 @@ static int i2c_opal_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 			OPAL_I2C_RAW_READ : OPAL_I2C_RAW_WRITE;
 		break;
 	case I2C_SMBUS_BYTE_DATA:
-		req.buffer_ra = cpu_to_be64(__pa(&data->byte));
+		req.buffer_ra = cpu_to_be64(&data->byte);
 		req.size = cpu_to_be32(1);
 		req.subaddr = cpu_to_be32(command);
 		req.subaddr_sz = 1;
@@ -143,7 +143,7 @@ static int i2c_opal_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 			local[0] = data->word & 0xff;
 			local[1] = (data->word >> 8) & 0xff;
 		}
-		req.buffer_ra = cpu_to_be64(__pa(local));
+		req.buffer_ra = cpu_to_be64(local);
 		req.size = cpu_to_be32(2);
 		req.subaddr = cpu_to_be32(command);
 		req.subaddr_sz = 1;
@@ -151,7 +151,7 @@ static int i2c_opal_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 			OPAL_I2C_SM_READ : OPAL_I2C_SM_WRITE;
 		break;
 	case I2C_SMBUS_I2C_BLOCK_DATA:
-		req.buffer_ra = cpu_to_be64(__pa(&data->block[1]));
+		req.buffer_ra = cpu_to_be64(&data->block[1]);
 		req.size = cpu_to_be32(data->block[0]);
 		req.subaddr = cpu_to_be32(command);
 		req.subaddr_sz = 1;
diff --git a/drivers/mtd/devices/powernv_flash.c b/drivers/mtd/devices/powernv_flash.c
index 0b757d9ba2f6..86dbaae8808f 100644
--- a/drivers/mtd/devices/powernv_flash.c
+++ b/drivers/mtd/devices/powernv_flash.c
@@ -66,10 +66,10 @@ static int powernv_flash_async_op(struct mtd_info *mtd, enum flash_op op,
 
 	switch (op) {
 	case FLASH_OP_READ:
-		rc = opal_flash_read(info->id, offset, __pa(buf), len, token);
+		rc = opal_flash_read(info->id, offset, (u64)buf, len, token);
 		break;
 	case FLASH_OP_WRITE:
-		rc = opal_flash_write(info->id, offset, __pa(buf), len, token);
+		rc = opal_flash_write(info->id, offset, (u64)buf, len, token);
 		break;
 	case FLASH_OP_ERASE:
 		rc = opal_flash_erase(info->id, offset, len, token);
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 06/10] powerpc/powernv: opal use new opal call entry point if it exists
  2020-05-02 11:19 [RFC PATCH 00/10] OPAL V4 Nicholas Piggin
                   ` (4 preceding siblings ...)
  2020-05-02 11:19 ` [RFC PATCH 05/10] powerpc/powernv: Don't translate kernel addresses to real addresses for OPAL Nicholas Piggin
@ 2020-05-02 11:19 ` Nicholas Piggin
  2020-05-02 16:25   ` kbuild test robot
  2020-05-06  7:02   ` Gautham R Shenoy
  2020-05-02 11:19 ` [RFC PATCH 07/10] powerpc/powernv: Add OPAL_FIND_VM_AREA API Nicholas Piggin
                   ` (3 subsequent siblings)
  9 siblings, 2 replies; 14+ messages in thread
From: Nicholas Piggin @ 2020-05-02 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

OPAL may advertise new endian-specific entry point which has different
calling conventions including using the caller's stack, but otherwise
provides the standard OPAL call API without any changes required to
the OS.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/boot/opal.c                   |  5 +++
 arch/powerpc/platforms/powernv/opal-call.c | 36 ++++++++++++++++++++++
 arch/powerpc/platforms/powernv/opal.c      | 30 +++++++++++-------
 3 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/boot/opal.c b/arch/powerpc/boot/opal.c
index b69818ce592b..8b006a0282ac 100644
--- a/arch/powerpc/boot/opal.c
+++ b/arch/powerpc/boot/opal.c
@@ -13,6 +13,7 @@
 struct opal {
 	u64 base;
 	u64 entry;
+	u64 v4_le_entry;
 } opal;
 
 static u32 opal_con_id;
@@ -75,6 +76,10 @@ static void opal_init(void)
 	if (getprop(opal_node, "opal-entry-address", &opal.entry, sizeof(u64)) < 0)
 		return;
 	opal.entry = be64_to_cpu(opal.entry);
+
+	if (getprop(opal_node, "opal-v4-le-entry-address", &opal.v4_le_entry, sizeof(u64)) < 0)
+		return;
+	opal.v4_le_entry = be64_to_cpu(opal.v4_le_entry);
 }
 
 int opal_console_init(void *devp, struct serial_console_data *scdp)
diff --git a/arch/powerpc/platforms/powernv/opal-call.c b/arch/powerpc/platforms/powernv/opal-call.c
index 506b1798081a..32857254d268 100644
--- a/arch/powerpc/platforms/powernv/opal-call.c
+++ b/arch/powerpc/platforms/powernv/opal-call.c
@@ -92,6 +92,18 @@ static s64 __opal_call_trace(s64 a0, s64 a1, s64 a2, s64 a3,
 #define DO_TRACE false
 #endif /* CONFIG_TRACEPOINTS */
 
+struct opal {
+	u64 base;
+	u64 entry;
+	u64 size;
+	u64 v4_le_entry;
+};
+extern struct opal opal;
+
+typedef int64_t (*opal_v4_le_entry_fn)(uint64_t r3, uint64_t r4, uint64_t r5,
+                               uint64_t r6, uint64_t r7, uint64_t r8,
+                               uint64_t r9, uint64_t r10);
+
 static int64_t opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3,
 	     int64_t a4, int64_t a5, int64_t a6, int64_t a7, int64_t opcode)
 {
@@ -99,6 +111,30 @@ static int64_t opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3,
 	unsigned long msr = mfmsr();
 	bool mmu = (msr & (MSR_IR|MSR_DR));
 	int64_t ret;
+	opal_v4_le_entry_fn fn;
+
+	if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN))
+		fn = (opal_v4_le_entry_fn)(opal.v4_le_entry);
+
+	if (fn) {
+		if (!mmu) {
+			BUG_ON(msr & MSR_EE);
+			ret = fn(opcode, a0, a1, a2, a3, a4, a5, a6);
+			return ret;
+		}
+
+		local_irq_save(flags);
+		hard_irq_disable(); /* XXX r13 */
+		msr &= ~MSR_EE;
+		mtmsr(msr & ~(MSR_IR|MSR_DR));
+
+		ret = fn(opcode, a0, a1, a2, a3, a4, a5, a6);
+
+		mtmsr(msr);
+		local_irq_restore(flags);
+
+		return ret;
+	}
 
 	msr &= ~MSR_EE;
 
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index a0e9808237b2..d00772d40680 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -46,13 +46,14 @@ static DEFINE_SPINLOCK(msg_list_lock);
 static LIST_HEAD(msg_list);
 
 /* /sys/firmware/opal */
-struct kobject *opal_kobj;
+struct kobject *opal_kobj __read_mostly;
 
 struct opal {
 	u64 base;
 	u64 entry;
 	u64 size;
-} opal;
+	u64 v4_le_entry;
+} opal __read_mostly;
 
 struct mcheck_recoverable_range {
 	u64 start_addr;
@@ -150,14 +151,15 @@ unsigned long arch_symbol_lookup_name(const char *name)
 int __init early_init_dt_scan_opal(unsigned long node,
 				   const char *uname, int depth, void *data)
 {
-	const void *basep, *entryp, *sizep;
-	int basesz, entrysz, runtimesz;
+	const void *basep, *entryp, *v4_le_entryp, *sizep;
+	int basesz, entrysz, v4_le_entrysz, runtimesz;
 
 	if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
 		return 0;
 
 	basep  = of_get_flat_dt_prop(node, "opal-base-address", &basesz);
 	entryp = of_get_flat_dt_prop(node, "opal-entry-address", &entrysz);
+	v4_le_entryp = of_get_flat_dt_prop(node, "opal-v4-le-entry-address", &v4_le_entrysz);
 	sizep = of_get_flat_dt_prop(node, "opal-runtime-size", &runtimesz);
 
 	if (!basep || !entryp || !sizep)
@@ -166,19 +168,25 @@ int __init early_init_dt_scan_opal(unsigned long node,
 	opal.base = of_read_number(basep, basesz/4);
 	opal.entry = of_read_number(entryp, entrysz/4);
 	opal.size = of_read_number(sizep, runtimesz/4);
+	opal.v4_le_entry = of_read_number(v4_le_entryp, v4_le_entrysz/4);
+
+	if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) {
+		powerpc_firmware_features |= FW_FEATURE_OPAL;
+		pr_debug("OPAL detected !\n");
+	} else {
+		panic("OPAL v3 compatible firmware not detected, can not continue.\n");
+	}
 
 	pr_debug("OPAL Base  = 0x%llx (basep=%p basesz=%d)\n",
 		 opal.base, basep, basesz);
-	pr_debug("OPAL Entry = 0x%llx (entryp=%p basesz=%d)\n",
+	pr_debug("OPAL Entry = 0x%llx (entryp=%p entrysz=%d)\n",
 		 opal.entry, entryp, entrysz);
-	pr_debug("OPAL Entry = 0x%llx (sizep=%p runtimesz=%d)\n",
+	pr_debug("OPAL Size = 0x%llx (sizep=%p runtimesz=%d)\n",
 		 opal.size, sizep, runtimesz);
+	if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN) && v4_le_entryp) {
 
-	if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) {
-		powerpc_firmware_features |= FW_FEATURE_OPAL;
-		pr_debug("OPAL detected !\n");
-	} else {
-		panic("OPAL != V3 detected, no longer supported.\n");
+		pr_debug("OPAL v4 Entry = 0x%llx (v4_le_entryp=%p v4_le_entrysz=%d)\n",
+			 opal.v4_le_entry, v4_le_entryp, v4_le_entrysz);
 	}
 
 	return 1;
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 07/10] powerpc/powernv: Add OPAL_FIND_VM_AREA API
  2020-05-02 11:19 [RFC PATCH 00/10] OPAL V4 Nicholas Piggin
                   ` (5 preceding siblings ...)
  2020-05-02 11:19 ` [RFC PATCH 06/10] powerpc/powernv: opal use new opal call entry point if it exists Nicholas Piggin
@ 2020-05-02 11:19 ` Nicholas Piggin
  2020-05-02 11:19 ` [RFC PATCH 08/10] powerpc/powernv: Set up an mm context to call OPAL in Nicholas Piggin
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Nicholas Piggin @ 2020-05-02 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

This will be used in the next patch.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/include/asm/opal-api.h        | 15 ++++++++++++++-
 arch/powerpc/include/asm/opal.h            |  2 ++
 arch/powerpc/platforms/powernv/opal-call.c |  1 +
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index 018d4734c323..0be5ff4e51b5 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -217,7 +217,8 @@
 #define OPAL_ADDR_TO_SYM			181
 #define OPAL_SYM_TO_ADDR			182
 #define OPAL_REPORT_TRAP			183
-#define OPAL_LAST				183
+#define OPAL_FIND_VM_AREA			184
+#define OPAL_LAST				184
 
 #define QUIESCE_HOLD			1 /* Spin all calls at entry */
 #define QUIESCE_REJECT			2 /* Fail all calls with OPAL_BUSY */
@@ -1189,6 +1190,18 @@ struct opal_mpipl_fadump {
 #define OPAL_TRAP_WARN	2
 #define OPAL_TRAP_PANIC	3
 
+#define OS_VM_FLAG_READ		0x1
+#define OS_VM_FLAG_WRITE	0x2
+#define OS_VM_FLAG_EXECUTE	0x4
+#define OS_VM_FLAG_CI		0x8
+
+struct opal_vm_area {
+	__be64  address;
+	__be64  length;
+	__be64  pa;
+	__be64  vm_flags;
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index dc77c2d5e036..199b5582b700 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -405,6 +405,8 @@ void opal_powercap_init(void);
 void opal_psr_init(void);
 void opal_sensor_groups_init(void);
 
+int64_t opal_find_vm_area(uint64_t addr, struct opal_vm_area *opal_vm_area);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_OPAL_H */
diff --git a/arch/powerpc/platforms/powernv/opal-call.c b/arch/powerpc/platforms/powernv/opal-call.c
index 32857254d268..e62a74dfb3d0 100644
--- a/arch/powerpc/platforms/powernv/opal-call.c
+++ b/arch/powerpc/platforms/powernv/opal-call.c
@@ -332,3 +332,4 @@ OPAL_CALL(opal_secvar_enqueue_update,		OPAL_SECVAR_ENQUEUE_UPDATE);
 OPAL_CALL(opal_addr_to_sym,			OPAL_ADDR_TO_SYM);
 OPAL_CALL(opal_sym_to_addr,			OPAL_SYM_TO_ADDR);
 OPAL_CALL(opal_report_trap,			OPAL_REPORT_TRAP);
+OPAL_CALL(opal_find_vm_area,			OPAL_FIND_VM_AREA);
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 08/10] powerpc/powernv: Set up an mm context to call OPAL in
  2020-05-02 11:19 [RFC PATCH 00/10] OPAL V4 Nicholas Piggin
                   ` (6 preceding siblings ...)
  2020-05-02 11:19 ` [RFC PATCH 07/10] powerpc/powernv: Add OPAL_FIND_VM_AREA API Nicholas Piggin
@ 2020-05-02 11:19 ` Nicholas Piggin
  2020-05-02 11:19 ` [RFC PATCH 09/10] powerpc/powernv: OPAL V4 OS services Nicholas Piggin
  2020-05-02 11:19 ` [RFC PATCH 10/10] powerpc/powernv: OPAL V4 Implement vm_map/unmap service Nicholas Piggin
  9 siblings, 0 replies; 14+ messages in thread
From: Nicholas Piggin @ 2020-05-02 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

This creates an mm context to be used for OPAL V4 calls, which
is populated with ptes according to querying OPAL_FIND_VM_AREA.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/platforms/powernv/opal-call.c |  21 +++-
 arch/powerpc/platforms/powernv/opal.c      | 119 ++++++++++++++++++++-
 2 files changed, 137 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-call.c b/arch/powerpc/platforms/powernv/opal-call.c
index e62a74dfb3d0..4bdad3d2fa18 100644
--- a/arch/powerpc/platforms/powernv/opal-call.c
+++ b/arch/powerpc/platforms/powernv/opal-call.c
@@ -104,6 +104,9 @@ typedef int64_t (*opal_v4_le_entry_fn)(uint64_t r3, uint64_t r4, uint64_t r5,
                                uint64_t r6, uint64_t r7, uint64_t r8,
                                uint64_t r9, uint64_t r10);
 
+extern struct mm_struct *opal_mm;
+extern bool opal_mm_enabled;
+
 static int64_t opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3,
 	     int64_t a4, int64_t a5, int64_t a6, int64_t a7, int64_t opcode)
 {
@@ -117,6 +120,8 @@ static int64_t opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3,
 		fn = (opal_v4_le_entry_fn)(opal.v4_le_entry);
 
 	if (fn) {
+		struct mm_struct *old_mm = current->active_mm;
+
 		if (!mmu) {
 			BUG_ON(msr & MSR_EE);
 			ret = fn(opcode, a0, a1, a2, a3, a4, a5, a6);
@@ -126,11 +131,23 @@ static int64_t opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3,
 		local_irq_save(flags);
 		hard_irq_disable(); /* XXX r13 */
 		msr &= ~MSR_EE;
-		mtmsr(msr & ~(MSR_IR|MSR_DR));
+		if (!opal_mm_enabled)
+			mtmsr(msr & ~(MSR_IR|MSR_DR));
+
+		if (opal_mm_enabled && old_mm != opal_mm) {
+			current->active_mm = opal_mm;
+			switch_mm_irqs_off(NULL, opal_mm, current);
+		}
 
 		ret = fn(opcode, a0, a1, a2, a3, a4, a5, a6);
 
-		mtmsr(msr);
+		if (opal_mm_enabled && old_mm != opal_mm) {
+			current->active_mm = old_mm;
+			switch_mm_irqs_off(NULL, old_mm, current);
+		}
+
+		if (!opal_mm_enabled)
+			mtmsr(msr);
 		local_irq_restore(flags);
 
 		return ret;
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index d00772d40680..98d6d7fc5411 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -45,6 +45,10 @@ struct opal_msg_node {
 static DEFINE_SPINLOCK(msg_list_lock);
 static LIST_HEAD(msg_list);
 
+struct mm_struct *opal_mm __read_mostly;
+bool opal_v4_present __read_mostly;
+bool opal_mm_enabled __read_mostly;
+
 /* /sys/firmware/opal */
 struct kobject *opal_kobj __read_mostly;
 
@@ -172,7 +176,12 @@ int __init early_init_dt_scan_opal(unsigned long node,
 
 	if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) {
 		powerpc_firmware_features |= FW_FEATURE_OPAL;
-		pr_debug("OPAL detected !\n");
+		if (of_flat_dt_is_compatible(node, "ibm,opal-v4")) {
+			opal_v4_present = true;
+			pr_debug("OPAL v4 runtime firmware\n");
+		} else {
+			pr_debug("OPAL detected !\n");
+		}
 	} else {
 		panic("OPAL v3 compatible firmware not detected, can not continue.\n");
 	}
@@ -187,6 +196,9 @@ int __init early_init_dt_scan_opal(unsigned long node,
 
 		pr_debug("OPAL v4 Entry = 0x%llx (v4_le_entryp=%p v4_le_entrysz=%d)\n",
 			 opal.v4_le_entry, v4_le_entryp, v4_le_entrysz);
+	} else {
+		/* Can't use v4 entry */
+		opal_v4_present = false;
 	}
 
 	return 1;
@@ -1033,6 +1045,111 @@ static void opal_init_heartbeat(void)
 		kopald_tsk = kthread_run(kopald, NULL, "kopald");
 }
 
+static pgprot_t opal_vm_flags_to_prot(uint64_t flags)
+{
+	pgprot_t prot;
+
+	BUG_ON(!flags);
+	if (flags & OS_VM_FLAG_EXECUTE) {
+		if (flags & OS_VM_FLAG_CI)
+			BUG();
+		if (flags & OS_VM_FLAG_WRITE)
+			prot = PAGE_KERNEL_X;
+		else
+			prot = PAGE_KERNEL_X /* XXX!? PAGE_KERNEL_ROX */;
+	} else {
+		if (flags & OS_VM_FLAG_WRITE)
+			prot = PAGE_KERNEL;
+		else if (flags & OS_VM_FLAG_READ)
+			prot = PAGE_KERNEL_RO;
+		else
+			BUG();
+		if (flags & OS_VM_FLAG_CI)
+			prot = pgprot_noncached(prot);
+	}
+	return prot;
+}
+
+static int __init opal_init_mm(void)
+{
+	struct mm_struct *mm;
+	unsigned long addr;
+	struct opal_vm_area vm_area;
+
+	mm = copy_init_mm();
+	if (!mm)
+		return -ENOMEM;
+
+	/* Set up initial mappings for OPAL. */
+	addr = 0;
+	while (opal_find_vm_area(addr, &vm_area) == OPAL_SUCCESS) {
+		unsigned long length;
+		unsigned long pa;
+		unsigned long flags;
+		unsigned long end;
+		pgprot_t prot;
+
+		addr = be64_to_cpu(vm_area.address);
+		length = be64_to_cpu(vm_area.length);
+		pa = be64_to_cpu(vm_area.pa);
+		flags = be64_to_cpu(vm_area.vm_flags);
+
+		if (flags == 0) {
+			/* flags == 0 is a special case */
+			BUG_ON(pa != 0);
+		} else {
+			/* Don't support non-linear (yet?) */
+			BUG_ON(addr != pa);
+			prot = opal_vm_flags_to_prot(flags);
+		}
+
+		/* Align to PAGE_SIZE */
+		end = (addr + length + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+		addr &= ~(PAGE_SIZE - 1);
+
+		while (addr < end) {
+			spinlock_t *ptl;
+			pte_t pte, *ptep;
+
+			ptep = get_locked_pte(mm, addr, &ptl);
+			if (flags) {
+				pte = pfn_pte(addr >> PAGE_SHIFT, prot);
+				set_pte_at(mm, addr, ptep, pte);
+			} else {
+				pte_clear(mm, addr, ptep);
+			}
+			pte_unmap_unlock(ptep, ptl);
+
+			addr += PAGE_SIZE;
+		}
+	}
+
+	printk("OPAL Virtual Memory Runtime Enabled, using PID=0x%04x\n", (unsigned int)mm->context.id);
+
+	opal_mm = mm;
+	opal_mm_enabled = true;
+
+	return 0;
+}
+
+static int __init opal_init_early(void)
+{
+	int rc;
+
+	if (opal_v4_present) {
+		if (radix_enabled()) {
+			/* Hash can't resolve SLB faults to the switched mm */
+			rc = opal_init_mm();
+			if (rc) {
+				pr_warn("OPAL virtual memory init failed, firmware will run in real-mode.\n");
+			}
+		}
+	}
+
+	return 0;
+}
+machine_early_initcall(powernv, opal_init_early);
+
 static int __init opal_init(void)
 {
 	struct device_node *np, *consoles, *leds;
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 09/10] powerpc/powernv: OPAL V4 OS services
  2020-05-02 11:19 [RFC PATCH 00/10] OPAL V4 Nicholas Piggin
                   ` (7 preceding siblings ...)
  2020-05-02 11:19 ` [RFC PATCH 08/10] powerpc/powernv: Set up an mm context to call OPAL in Nicholas Piggin
@ 2020-05-02 11:19 ` Nicholas Piggin
  2020-05-02 11:19 ` [RFC PATCH 10/10] powerpc/powernv: OPAL V4 Implement vm_map/unmap service Nicholas Piggin
  9 siblings, 0 replies; 14+ messages in thread
From: Nicholas Piggin @ 2020-05-02 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

This implements OPAL_REGISTER_OS_OPS and implements the printf
service.

When this API is called, OPAL switches to V4 mode which requires
the OS to subsequently handle its program interrupts and printf
calls.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/include/asm/opal-api.h        |  7 ++++-
 arch/powerpc/include/asm/opal.h            |  1 +
 arch/powerpc/platforms/powernv/opal-call.c |  1 +
 arch/powerpc/platforms/powernv/opal.c      | 36 ++++++++++++++++++++++
 4 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index 0be5ff4e51b5..1b2f176677fc 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -218,7 +218,8 @@
 #define OPAL_SYM_TO_ADDR			182
 #define OPAL_REPORT_TRAP			183
 #define OPAL_FIND_VM_AREA			184
-#define OPAL_LAST				184
+#define OPAL_REGISTER_OS_OPS			185
+#define OPAL_LAST				185
 
 #define QUIESCE_HOLD			1 /* Spin all calls at entry */
 #define QUIESCE_REJECT			2 /* Fail all calls with OPAL_BUSY */
@@ -1202,6 +1203,10 @@ struct opal_vm_area {
 	__be64  vm_flags;
 };
 
+struct opal_os_ops {
+	__be64  os_printf; /* void printf(int32_t level, const char *str) */
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 199b5582b700..09985b7718b3 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -406,6 +406,7 @@ void opal_psr_init(void);
 void opal_sensor_groups_init(void);
 
 int64_t opal_find_vm_area(uint64_t addr, struct opal_vm_area *opal_vm_area);
+int64_t opal_register_os_ops(struct opal_os_ops *ops, uint64_t size);
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/powerpc/platforms/powernv/opal-call.c b/arch/powerpc/platforms/powernv/opal-call.c
index 4bdad3d2fa18..11f419e76059 100644
--- a/arch/powerpc/platforms/powernv/opal-call.c
+++ b/arch/powerpc/platforms/powernv/opal-call.c
@@ -350,3 +350,4 @@ OPAL_CALL(opal_addr_to_sym,			OPAL_ADDR_TO_SYM);
 OPAL_CALL(opal_sym_to_addr,			OPAL_SYM_TO_ADDR);
 OPAL_CALL(opal_report_trap,			OPAL_REPORT_TRAP);
 OPAL_CALL(opal_find_vm_area,			OPAL_FIND_VM_AREA);
+OPAL_CALL(opal_register_os_ops,			OPAL_REGISTER_OS_OPS);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 98d6d7fc5411..0fbfcd088c58 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -47,6 +47,7 @@ static LIST_HEAD(msg_list);
 
 struct mm_struct *opal_mm __read_mostly;
 bool opal_v4_present __read_mostly;
+bool opal_v4_enabled __read_mostly;
 bool opal_mm_enabled __read_mostly;
 
 /* /sys/firmware/opal */
@@ -152,6 +153,8 @@ unsigned long arch_symbol_lookup_name(const char *name)
 	return be64_to_cpu(addr);
 }
 
+static void os_printf(int32_t level, const char *str);
+
 int __init early_init_dt_scan_opal(unsigned long node,
 				   const char *uname, int depth, void *data)
 {
@@ -1045,6 +1048,28 @@ static void opal_init_heartbeat(void)
 		kopald_tsk = kthread_run(kopald, NULL, "kopald");
 }
 
+static void os_printf(int32_t level, const char *str)
+{
+	const char *l;
+
+	/* Assuming printk does not work in real mode */
+	if (WARN_ON_ONCE(!(mfmsr() & (MSR_IR|MSR_DR))))
+		return;
+
+	switch (level) {
+	case 0: l = KERN_EMERG; break;
+	case 1: l = KERN_ALERT; break;
+	case 2: l = KERN_CRIT; break;
+	case 3: l = KERN_ERR; break;
+	case 4: l = KERN_WARNING; break;
+	case 5: l = KERN_NOTICE; break;
+	case 6: l = KERN_INFO; break;
+	case 7: l = KERN_DEBUG; break;
+	default: l = KERN_ERR;
+	}
+	printk("%s[OPAL] %s", l, str);
+}
+
 static pgprot_t opal_vm_flags_to_prot(uint64_t flags)
 {
 	pgprot_t prot;
@@ -1137,6 +1162,8 @@ static int __init opal_init_early(void)
 	int rc;
 
 	if (opal_v4_present) {
+		struct opal_os_ops opal_os_ops;
+
 		if (radix_enabled()) {
 			/* Hash can't resolve SLB faults to the switched mm */
 			rc = opal_init_mm();
@@ -1144,6 +1171,15 @@ static int __init opal_init_early(void)
 				pr_warn("OPAL virtual memory init failed, firmware will run in real-mode.\n");
 			}
 		}
+
+		memset(&opal_os_ops, 0, sizeof(opal_os_ops));
+		opal_os_ops.os_printf = cpu_to_be64(&os_printf);
+		if (opal_register_os_ops(&opal_os_ops, sizeof(opal_os_ops))) {
+			pr_warn("OPAL register OS ops failed, firmware will run in v3 mode.\n");
+		} else {
+			opal_v4_enabled = true;
+			pr_warn("OPAL running in v4 mode!\n");
+		}
 	}
 
 	return 0;
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 10/10] powerpc/powernv: OPAL V4 Implement vm_map/unmap service
  2020-05-02 11:19 [RFC PATCH 00/10] OPAL V4 Nicholas Piggin
                   ` (8 preceding siblings ...)
  2020-05-02 11:19 ` [RFC PATCH 09/10] powerpc/powernv: OPAL V4 OS services Nicholas Piggin
@ 2020-05-02 11:19 ` Nicholas Piggin
  9 siblings, 0 replies; 14+ messages in thread
From: Nicholas Piggin @ 2020-05-02 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

This implements os_vm_map, os_vm_unmap. OPAL uses EA regions that
is specifies in OPAL_FIND_VM_AREA for these mappings, so provided
the page tables are allocated at init-time and not freed, these
services can be provided without memory allocation / blocking.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/include/asm/opal-api.h   |  2 +
 arch/powerpc/platforms/powernv/opal.c | 57 +++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index 1b2f176677fc..97c5e5423827 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -1205,6 +1205,8 @@ struct opal_vm_area {
 
 struct opal_os_ops {
 	__be64  os_printf; /* void printf(int32_t level, const char *str) */
+	__be64  os_vm_map; /* int64_t os_vm_map(uint64_t ea, uint64_t pa, uint64_t flags) */
+	__be64  os_vm_unmap; /* void os_vm_unmap(uint64_t ea) */
 };
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 0fbfcd088c58..93b9afaf33b3 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -1095,6 +1095,61 @@ static pgprot_t opal_vm_flags_to_prot(uint64_t flags)
 	return prot;
 }
 
+static int64_t os_vm_map(uint64_t ea, uint64_t pa, uint64_t flags)
+{
+	struct mm_struct *mm = opal_mm;
+	spinlock_t *ptl;
+	pte_t pte, *ptep;
+	pgprot_t prot;
+
+	if (WARN_ON_ONCE(!opal_mm_enabled))
+		return -EINVAL;
+
+	if (WARN_ON_ONCE(!(mfmsr() & (MSR_IR|MSR_DR))))
+		return -EINVAL;
+
+	/* mm should be active_mm if MMU is on here */
+
+//	printk("os_vm_map 0x%llx->0x%llx flags=0x%llx\n", ea, pa, flags);
+
+	prot = opal_vm_flags_to_prot(flags);
+
+	pte = pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL_X);
+
+	ptep = get_locked_pte(mm, ea, &ptl);
+	set_pte_at(mm, ea, ptep, pte);
+	pte_unmap_unlock(ptep, ptl);
+
+	return 0;
+}
+
+static void os_vm_unmap(uint64_t ea)
+{
+	struct mm_struct *mm = opal_mm;
+	spinlock_t *ptl;
+	pte_t *ptep;
+
+	if (WARN_ON_ONCE(!opal_mm_enabled))
+		return;
+
+	if (WARN_ON_ONCE(!(mfmsr() & (MSR_IR|MSR_DR))))
+		return;
+
+//	printk("os_vm_unmap 0x%llx\n", ea);
+
+	/* mm should be active_mm if MMU is on here */
+
+	ptep = get_locked_pte(mm, ea, &ptl);
+	pte_clear(mm, ea, ptep);
+	pte_unmap_unlock(ptep, ptl);
+
+	/*
+	 * This leaves potential TLBs in other CPUs for this EA, but it is
+	 * only used by this CPU. Can't do a broadcast flush here, no IPIs.
+	 */
+	local_flush_tlb_mm(mm);
+}
+
 static int __init opal_init_mm(void)
 {
 	struct mm_struct *mm;
@@ -1174,6 +1229,8 @@ static int __init opal_init_early(void)
 
 		memset(&opal_os_ops, 0, sizeof(opal_os_ops));
 		opal_os_ops.os_printf = cpu_to_be64(&os_printf);
+		opal_os_ops.os_vm_map = cpu_to_be64(&os_vm_map);
+		opal_os_ops.os_vm_unmap = cpu_to_be64(&os_vm_unmap);
 		if (opal_register_os_ops(&opal_os_ops, sizeof(opal_os_ops))) {
 			pr_warn("OPAL register OS ops failed, firmware will run in v3 mode.\n");
 		} else {
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH 03/10] powerpc/powernv: Use OPAL_REPORT_TRAP to cope with trap interrupts from OPAL
  2020-05-02 11:19 ` [RFC PATCH 03/10] powerpc/powernv: Use OPAL_REPORT_TRAP to cope with trap interrupts from OPAL Nicholas Piggin
@ 2020-05-02 14:30   ` kbuild test robot
  0 siblings, 0 replies; 14+ messages in thread
From: kbuild test robot @ 2020-05-02 14:30 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 7083 bytes --]

Hi Nicholas,

[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on powerpc/next]
[also build test ERROR on linus/master scottwood/next v5.7-rc3]
[cannot apply to next-20200501]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Nicholas-Piggin/OPAL-V4/20200502-195816
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-mpc866_ads_defconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day GCC_VERSION=9.3.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/powerpc/kernel/traps.c: In function 'program_check_exception':
>> arch/powerpc/kernel/traps.c:1509:11: error: implicit declaration of function 'opal_report_trap' [-Werror=implicit-function-declaration]
    1509 |     ret = opal_report_trap(regs->nip);
         |           ^~~~~~~~~~~~~~~~
>> arch/powerpc/kernel/traps.c:1510:16: error: 'OPAL_TRAP_WARN' undeclared (first use in this function)
    1510 |     if (ret == OPAL_TRAP_WARN) {
         |                ^~~~~~~~~~~~~~
   arch/powerpc/kernel/traps.c:1510:16: note: each undeclared identifier is reported only once for each function it appears in
   cc1: all warnings being treated as errors

vim +/opal_report_trap +1509 arch/powerpc/kernel/traps.c

  1460	
  1461	void program_check_exception(struct pt_regs *regs)
  1462	{
  1463		enum ctx_state prev_state = exception_enter();
  1464		unsigned int reason = get_reason(regs);
  1465	
  1466		/* We can now get here via a FP Unavailable exception if the core
  1467		 * has no FPU, in that case the reason flags will be 0 */
  1468	
  1469		if (reason & REASON_FP) {
  1470			/* IEEE FP exception */
  1471			parse_fpe(regs);
  1472			goto bail;
  1473		}
  1474		if (reason & REASON_TRAP) {
  1475			/* Debugger is first in line to stop recursive faults in
  1476			 * rcu_lock, notify_die, or atomic_notifier_call_chain */
  1477			if (debugger_bpt(regs))
  1478				goto bail;
  1479	
  1480			if (kprobe_handler(regs))
  1481				goto bail;
  1482	
  1483			/* trap exception */
  1484			if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP)
  1485					== NOTIFY_STOP)
  1486				goto bail;
  1487	
  1488			if (!(regs->msr & MSR_PR)) { /* not user-mode */
  1489				unsigned long bugaddr;
  1490				enum bug_trap_type t;
  1491	
  1492				/*
  1493				 * Fixup bugaddr for BUG_ON() in real mode
  1494				 */
  1495				bugaddr = regs->nip;
  1496				if (!is_kernel_addr(bugaddr) && !(regs->msr & MSR_IR))
  1497					bugaddr += PAGE_OFFSET;
  1498				t = report_bug(bugaddr, regs);
  1499				if (t == BUG_TRAP_TYPE_WARN) {
  1500					regs->nip += 4;
  1501					goto bail;
  1502				}
  1503				if (t == BUG_TRAP_TYPE_BUG)
  1504					goto bug;
  1505	
  1506				if (firmware_has_feature(FW_FEATURE_OPAL)) {
  1507					int64_t ret;
  1508	
> 1509					ret = opal_report_trap(regs->nip);
> 1510					if (ret == OPAL_TRAP_WARN) {
  1511						regs->nip += 4;
  1512						goto bail;
  1513					}
  1514				}
  1515			}
  1516	bug:
  1517			_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
  1518			goto bail;
  1519		}
  1520	#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
  1521		if (reason & REASON_TM) {
  1522			/* This is a TM "Bad Thing Exception" program check.
  1523			 * This occurs when:
  1524			 * -  An rfid/hrfid/mtmsrd attempts to cause an illegal
  1525			 *    transition in TM states.
  1526			 * -  A trechkpt is attempted when transactional.
  1527			 * -  A treclaim is attempted when non transactional.
  1528			 * -  A tend is illegally attempted.
  1529			 * -  writing a TM SPR when transactional.
  1530			 *
  1531			 * If usermode caused this, it's done something illegal and
  1532			 * gets a SIGILL slap on the wrist.  We call it an illegal
  1533			 * operand to distinguish from the instruction just being bad
  1534			 * (e.g. executing a 'tend' on a CPU without TM!); it's an
  1535			 * illegal /placement/ of a valid instruction.
  1536			 */
  1537			if (user_mode(regs)) {
  1538				_exception(SIGILL, regs, ILL_ILLOPN, regs->nip);
  1539				goto bail;
  1540			} else {
  1541				printk(KERN_EMERG "Unexpected TM Bad Thing exception "
  1542				       "at %lx (msr 0x%lx) tm_scratch=%llx\n",
  1543				       regs->nip, regs->msr, get_paca()->tm_scratch);
  1544				die("Unrecoverable exception", regs, SIGABRT);
  1545			}
  1546		}
  1547	#endif
  1548	
  1549		/*
  1550		 * If we took the program check in the kernel skip down to sending a
  1551		 * SIGILL. The subsequent cases all relate to emulating instructions
  1552		 * which we should only do for userspace. We also do not want to enable
  1553		 * interrupts for kernel faults because that might lead to further
  1554		 * faults, and loose the context of the original exception.
  1555		 */
  1556		if (!user_mode(regs))
  1557			goto sigill;
  1558	
  1559		/* We restore the interrupt state now */
  1560		if (!arch_irq_disabled_regs(regs))
  1561			local_irq_enable();
  1562	
  1563		/* (reason & REASON_ILLEGAL) would be the obvious thing here,
  1564		 * but there seems to be a hardware bug on the 405GP (RevD)
  1565		 * that means ESR is sometimes set incorrectly - either to
  1566		 * ESR_DST (!?) or 0.  In the process of chasing this with the
  1567		 * hardware people - not sure if it can happen on any illegal
  1568		 * instruction or only on FP instructions, whether there is a
  1569		 * pattern to occurrences etc. -dgibson 31/Mar/2003
  1570		 */
  1571		if (!emulate_math(regs))
  1572			goto bail;
  1573	
  1574		/* Try to emulate it if we should. */
  1575		if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
  1576			switch (emulate_instruction(regs)) {
  1577			case 0:
  1578				regs->nip += 4;
  1579				emulate_single_step(regs);
  1580				goto bail;
  1581			case -EFAULT:
  1582				_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
  1583				goto bail;
  1584			}
  1585		}
  1586	
  1587	sigill:
  1588		if (reason & REASON_PRIVILEGED)
  1589			_exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
  1590		else
  1591			_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
  1592	
  1593	bail:
  1594		exception_exit(prev_state);
  1595	}
  1596	NOKPROBE_SYMBOL(program_check_exception);
  1597	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 12140 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH 06/10] powerpc/powernv: opal use new opal call entry point if it exists
  2020-05-02 11:19 ` [RFC PATCH 06/10] powerpc/powernv: opal use new opal call entry point if it exists Nicholas Piggin
@ 2020-05-02 16:25   ` kbuild test robot
  2020-05-06  7:02   ` Gautham R Shenoy
  1 sibling, 0 replies; 14+ messages in thread
From: kbuild test robot @ 2020-05-02 16:25 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3330 bytes --]

Hi Nicholas,

[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on powerpc/next]
[also build test WARNING on linus/master scottwood/next v5.7-rc3]
[cannot apply to next-20200501]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Nicholas-Piggin/OPAL-V4/20200502-195816
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-allyesconfig (attached as .config)
compiler: powerpc64-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day GCC_VERSION=9.3.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   arch/powerpc/platforms/powernv/opal-call.c: In function 'opal_call':
>> arch/powerpc/platforms/powernv/opal-call.c:119:5: warning: 'fn' is used uninitialized in this function [-Wuninitialized]
     119 |  if (fn) {
         |     ^

vim +/fn +119 arch/powerpc/platforms/powernv/opal-call.c

   102	
   103	typedef int64_t (*opal_v4_le_entry_fn)(uint64_t r3, uint64_t r4, uint64_t r5,
   104	                               uint64_t r6, uint64_t r7, uint64_t r8,
   105	                               uint64_t r9, uint64_t r10);
   106	
   107	static int64_t opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3,
   108		     int64_t a4, int64_t a5, int64_t a6, int64_t a7, int64_t opcode)
   109	{
   110		unsigned long flags;
   111		unsigned long msr = mfmsr();
   112		bool mmu = (msr & (MSR_IR|MSR_DR));
   113		int64_t ret;
   114		opal_v4_le_entry_fn fn;
   115	
   116		if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN))
   117			fn = (opal_v4_le_entry_fn)(opal.v4_le_entry);
   118	
 > 119		if (fn) {
   120			if (!mmu) {
   121				BUG_ON(msr & MSR_EE);
   122				ret = fn(opcode, a0, a1, a2, a3, a4, a5, a6);
   123				return ret;
   124			}
   125	
   126			local_irq_save(flags);
   127			hard_irq_disable(); /* XXX r13 */
   128			msr &= ~MSR_EE;
   129			mtmsr(msr & ~(MSR_IR|MSR_DR));
   130	
   131			ret = fn(opcode, a0, a1, a2, a3, a4, a5, a6);
   132	
   133			mtmsr(msr);
   134			local_irq_restore(flags);
   135	
   136			return ret;
   137		}
   138	
   139		msr &= ~MSR_EE;
   140	
   141		if (unlikely(!mmu))
   142			return __opal_call(a0, a1, a2, a3, a4, a5, a6, a7, opcode, msr);
   143	
   144		local_save_flags(flags);
   145		hard_irq_disable();
   146	
   147		if (DO_TRACE) {
   148			ret = __opal_call_trace(a0, a1, a2, a3, a4, a5, a6, a7, opcode, msr);
   149		} else {
   150			ret = __opal_call(a0, a1, a2, a3, a4, a5, a6, a7, opcode, msr);
   151		}
   152	
   153		local_irq_restore(flags);
   154	
   155		return ret;
   156	}
   157	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 66093 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH 06/10] powerpc/powernv: opal use new opal call entry point if it exists
  2020-05-02 11:19 ` [RFC PATCH 06/10] powerpc/powernv: opal use new opal call entry point if it exists Nicholas Piggin
  2020-05-02 16:25   ` kbuild test robot
@ 2020-05-06  7:02   ` Gautham R Shenoy
  1 sibling, 0 replies; 14+ messages in thread
From: Gautham R Shenoy @ 2020-05-06  7:02 UTC (permalink / raw)
  To: Nicholas Piggin; +Cc: linuxppc-dev

Hello Nicholas,

On Sat, May 02, 2020 at 09:19:10PM +1000, Nicholas Piggin wrote:
> OPAL may advertise new endian-specific entry point which has different
> calling conventions including using the caller's stack, but otherwise
> provides the standard OPAL call API without any changes required to
> the OS.
> 
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---

[..snip..]

> index 506b1798081a..32857254d268 100644
> --- a/arch/powerpc/platforms/powernv/opal-call.c
> +++ b/arch/powerpc/platforms/powernv/opal-call.c
> @@ -92,6 +92,18 @@ static s64 __opal_call_trace(s64 a0, s64 a1, s64 a2, s64 a3,
>  #define DO_TRACE false
>  #endif /* CONFIG_TRACEPOINTS */
> 
> +struct opal {
> +	u64 base;
> +	u64 entry;
> +	u64 size;
> +	u64 v4_le_entry;
> +};
> +extern struct opal opal;
> +
> +typedef int64_t (*opal_v4_le_entry_fn)(uint64_t r3, uint64_t r4, uint64_t r5,
> +                               uint64_t r6, uint64_t r7, uint64_t r8,
> +                               uint64_t r9, uint64_t r10);
> +
>  static int64_t opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3,
>  	     int64_t a4, int64_t a5, int64_t a6, int64_t a7, int64_t opcode)
>  {
> @@ -99,6 +111,30 @@ static int64_t opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3,
>  	unsigned long msr = mfmsr();
>  	bool mmu = (msr & (MSR_IR|MSR_DR));
>  	int64_t ret;
> +	opal_v4_le_entry_fn fn;

fn should be initialized to NULL here to ensure correctness when
kernel is built with CONFIG_CPU_BIG_ENDIAN.

> +
> +	if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN))
> +		fn = (opal_v4_le_entry_fn)(opal.v4_le_entry);
> +
> +	if (fn) {
> +		if (!mmu) {
> +			BUG_ON(msr & MSR_EE);
> +			ret = fn(opcode, a0, a1, a2, a3, a4, a5, a6);
> +			return ret;
> +		}
> +
> +		local_irq_save(flags);
> +		hard_irq_disable(); /* XXX r13 */
> +		msr &= ~MSR_EE;
> +		mtmsr(msr & ~(MSR_IR|MSR_DR));
> +
> +		ret = fn(opcode, a0, a1, a2, a3, a4, a5, a6);
> +
> +		mtmsr(msr);
> +		local_irq_restore(flags);
> +
> +		return ret;
> +	}
> 
>  	msr &= ~MSR_EE;
> 

--
Thanks and Regards
gautham.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-05-06  7:03 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-02 11:19 [RFC PATCH 00/10] OPAL V4 Nicholas Piggin
2020-05-02 11:19 ` [RFC PATCH 01/10] kallsyms: architecture specific symbol lookups Nicholas Piggin
2020-05-02 11:19 ` [RFC PATCH 02/10] powerpc/powernv: Wire up OPAL address lookups Nicholas Piggin
2020-05-02 11:19 ` [RFC PATCH 03/10] powerpc/powernv: Use OPAL_REPORT_TRAP to cope with trap interrupts from OPAL Nicholas Piggin
2020-05-02 14:30   ` kbuild test robot
2020-05-02 11:19 ` [RFC PATCH 04/10] powerpc/powernv: avoid polling in opal_get_chars Nicholas Piggin
2020-05-02 11:19 ` [RFC PATCH 05/10] powerpc/powernv: Don't translate kernel addresses to real addresses for OPAL Nicholas Piggin
2020-05-02 11:19 ` [RFC PATCH 06/10] powerpc/powernv: opal use new opal call entry point if it exists Nicholas Piggin
2020-05-02 16:25   ` kbuild test robot
2020-05-06  7:02   ` Gautham R Shenoy
2020-05-02 11:19 ` [RFC PATCH 07/10] powerpc/powernv: Add OPAL_FIND_VM_AREA API Nicholas Piggin
2020-05-02 11:19 ` [RFC PATCH 08/10] powerpc/powernv: Set up an mm context to call OPAL in Nicholas Piggin
2020-05-02 11:19 ` [RFC PATCH 09/10] powerpc/powernv: OPAL V4 OS services Nicholas Piggin
2020-05-02 11:19 ` [RFC PATCH 10/10] powerpc/powernv: OPAL V4 Implement vm_map/unmap service Nicholas Piggin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.