[04/13] KVM: PPC: Ultravisor: Use UV_WRITE_PATE ucall to register a PATE
diff mbox series

Message ID 1548172784-27414-5-git-send-email-linuxram@us.ibm.com
State Changes Requested
Headers show
Series
  • KVM: PPC: Paravirtualize KVM to support Ultravisor
Related show

Commit Message

Ram Pai Jan. 22, 2019, 3:59 p.m. UTC
From: Michael Anderson <andmike@linux.ibm.com>

The Nest_MMU needs to know the address of the Partition table (PT).
However the PT is in secure memory, and nestMMU cannot access secure
memory.  Hence hypevisor will continue to use a Partition table of
its own. It will have PATE entries for HV and for Normal virtual
machines. The same entries are also in the UV's PT.  The HV's PT
is programmed with the nest MMU.

Suggested-by: Ryan Grimm <grimm@linux.vnet.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
[device node name to ibm,ultravisor]
Signed-off-by: Michael Anderson <andmike@linux.ibm.com>
Signed-off-by: Ram Pai <linuxram@us.ibm.com>
---
 arch/powerpc/include/asm/ucall-api.h        | 30 +++++++++++++++++++++++++++++
 arch/powerpc/include/uapi/asm/uapi_uvcall.h |  2 ++
 arch/powerpc/mm/hash_utils_64.c             |  4 +++-
 arch/powerpc/mm/pgtable-book3s64.c          | 29 ++++++++++++++++++++++++++--
 arch/powerpc/mm/pgtable-radix.c             | 10 +++++++---
 5 files changed, 69 insertions(+), 6 deletions(-)

Comments

Paul Mackerras Jan. 22, 2019, 11:48 p.m. UTC | #1
On Tue, Jan 22, 2019 at 07:59:35AM -0800, Ram Pai wrote:
> From: Michael Anderson <andmike@linux.ibm.com>
> 
> The Nest_MMU needs to know the address of the Partition table (PT).
> However the PT is in secure memory, and nestMMU cannot access secure
> memory.  Hence hypevisor will continue to use a Partition table of
> its own. It will have PATE entries for HV and for Normal virtual
> machines. The same entries are also in the UV's PT.  The HV's PT
> is programmed with the nest MMU.

This isn't a good patch description.  It's confusing because it
doesn't start with the primary motivation of the patch - which is that
when running under an ultravisor, the ultravisor controls the real
partition table and has it in secure memory where the hypervisor can't
access it, and therefore we (the HV) have to do a ucall whenever we
want to update an entry.  Once you have explained that, then you can
explain the secondary aspect of the patch, which is that the HV still
keeps a copy of its view of the partition table in normal memory so
that the nest MMU can access it.

> Suggested-by: Ryan Grimm <grimm@linux.vnet.ibm.com>
> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
> [device node name to ibm,ultravisor]
> Signed-off-by: Michael Anderson <andmike@linux.ibm.com>
> Signed-off-by: Ram Pai <linuxram@us.ibm.com>

If Michael Anderson wrote the patch and sent it to you, and you sent
it to the list, why is Maddy's signoff relevant?  Was the original
version of the patch actually written by Maddy?

> diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable-book3s64.c

Given how much this series is modifying in arch/powerpc outside of
arch/powerpc/kvm, next time you need to cc the whole series to
linuxppc-dev@ozlabs.org.

> +void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
> +				  unsigned long dw1)
> +{
> +	pr_info("%s: SMF Regitered PATE for Hypervisor dw0 = 0x%lx dw1 = 0x%lx ", __func__, dw0, dw1);

Here you're printing an SMF message on all powernv systems, the vast
majority of which won't have any SMF or ultravisor capability.  That
seems unnecessary and confusing.

Also you have a spelling error in "Regitered".

Paul.
Ram Pai Jan. 23, 2019, 6 p.m. UTC | #2
On Wed, Jan 23, 2019 at 10:48:20AM +1100, Paul Mackerras wrote:
> On Tue, Jan 22, 2019 at 07:59:35AM -0800, Ram Pai wrote:
> > From: Michael Anderson <andmike@linux.ibm.com>
> > 
> > The Nest_MMU needs to know the address of the Partition table (PT).
> > However the PT is in secure memory, and nestMMU cannot access secure
> > memory.  Hence hypevisor will continue to use a Partition table of
> > its own. It will have PATE entries for HV and for Normal virtual
> > machines. The same entries are also in the UV's PT.  The HV's PT
> > is programmed with the nest MMU.
> 
> This isn't a good patch description.  It's confusing because it
> doesn't start with the primary motivation of the patch - which is that
> when running under an ultravisor, the ultravisor controls the real
> partition table and has it in secure memory where the hypervisor can't
> access it, and therefore we (the HV) have to do a ucall whenever we
> want to update an entry.  Once you have explained that, then you can
> explain the secondary aspect of the patch, which is that the HV still
> keeps a copy of its view of the partition table in normal memory so
> that the nest MMU can access it.
> 
> > Suggested-by: Ryan Grimm <grimm@linux.vnet.ibm.com>
> > Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
> > [device node name to ibm,ultravisor]
> > Signed-off-by: Michael Anderson <andmike@linux.ibm.com>
> > Signed-off-by: Ram Pai <linuxram@us.ibm.com>
> 
> If Michael Anderson wrote the patch and sent it to you, and you sent
> it to the list, why is Maddy's signoff relevant?  Was the original
> version of the patch actually written by Maddy?

Yes. this patch description needs a good amount work.  A couple of
related patches; some by Michael and some by me and some bug fixes by Maddy,
were merged  leading to this signoff cocktail and incoherent
description.

This was my first attempt to bring a logical order to
our internal set of patches, which I agree has some more way to go. :(

Thanks,
RP

Patch
diff mbox series

diff --git a/arch/powerpc/include/asm/ucall-api.h b/arch/powerpc/include/asm/ucall-api.h
index 3833b55..f411dcb 100644
--- a/arch/powerpc/include/asm/ucall-api.h
+++ b/arch/powerpc/include/asm/ucall-api.h
@@ -1,5 +1,35 @@ 
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef _ASM_POWERPC_UCALL_API_H
 #define _ASM_POWERPC_UCALL_API_H
+
 #include <uapi/asm/uapi_uvcall.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
+
+extern unsigned int smf_state;
+static inline bool smf_enabled(void)
+{
+	unsigned long smf;
+
+	if (!smf_state) {
+		smf = of_get_flat_dt_subnode_by_name(0, "ibm,ultravisor");
+		smf_state = (smf == -FDT_ERR_NOTFOUND) ? 1 : 2;
+	}
+	return (smf_state == 2);
+}
+
+#define PLPAR_UCALL_BUFSIZE 4
+long plpar_ucall(unsigned long opcode, unsigned long *retbuf, ...);
+
+static inline int uv_register_pate(u64 lpid, u64 dw0, u64 dw1)
+{
+	unsigned long retbuf[PLPAR_UCALL_BUFSIZE];
+
+	return plpar_ucall(UV_WRITE_PATE, retbuf, lpid, dw0, dw1);
+}
+
+#endif /* __ASSEMBLY__ */
 #endif	/* _ASM_POWERPC_UCALL_API_H */
diff --git a/arch/powerpc/include/uapi/asm/uapi_uvcall.h b/arch/powerpc/include/uapi/asm/uapi_uvcall.h
index 7e213a1..7f018cf 100644
--- a/arch/powerpc/include/uapi/asm/uapi_uvcall.h
+++ b/arch/powerpc/include/uapi/asm/uapi_uvcall.h
@@ -7,4 +7,6 @@ 
  */
 #ifndef UAPI_UC_H
 #define UAPI_UC_H
+
+#define UV_WRITE_PATE 	0xf104
 #endif /* #ifndef UAPI_UC_H */
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 0cc7fbc..6d0eef6 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -64,6 +64,7 @@ 
 #include <asm/ps3.h>
 #include <asm/pte-walk.h>
 #include <asm/asm-prototypes.h>
+#include <asm/ucall-api.h>
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -1051,9 +1052,10 @@  void hash__early_init_mmu_secondary(void)
 
 		if (!cpu_has_feature(CPU_FTR_ARCH_300))
 			mtspr(SPRN_SDR1, _SDR1);
-		else
+		else if (!smf_enabled())
 			mtspr(SPRN_PTCR,
 			      __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
+
 	}
 	/* Initialize SLB */
 	slb_initialize();
diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable-book3s64.c
index f3c31f5..ba6b34d 100644
--- a/arch/powerpc/mm/pgtable-book3s64.c
+++ b/arch/powerpc/mm/pgtable-book3s64.c
@@ -16,6 +16,7 @@ 
 #include <asm/tlb.h>
 #include <asm/trace.h>
 #include <asm/powernv.h>
+#include <asm/ucall-api.h>
 
 #include "mmu_decl.h"
 #include <trace/events/thp.h>
@@ -206,11 +207,23 @@  void __init mmu_partition_table_init(void)
 	 * 64 K size.
 	 */
 	ptcr = __pa(partition_tb) | (PATB_SIZE_SHIFT - 12);
-	mtspr(SPRN_PTCR, ptcr);
+	/*
+	 * Ultravisor creates and manages partition table if SMF
+	 * is enabled.
+	 */
+	if (!smf_enabled())
+		mtspr(SPRN_PTCR, ptcr);
+
+	/*
+	 * Since nestMMU cannot access secure memory. Create
+	 * and manage our own partition table. This table
+	 * contains entries for nonsecure and hypervisor
+	 * partition.
+	 */
 	powernv_set_nmmu_ptcr(ptcr);
 }
 
-void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
+static void __mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
 				   unsigned long dw1)
 {
 	unsigned long old = be64_to_cpu(partition_tb[lpid].patb0);
@@ -238,6 +251,18 @@  void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
 	/* do we need fixup here ?*/
 	asm volatile("eieio; tlbsync; ptesync" : : : "memory");
 }
+
+void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
+				  unsigned long dw1)
+{
+	pr_info("%s: SMF Regitered PATE for Hypervisor dw0 = 0x%lx dw1 = 0x%lx ", __func__, dw0, dw1);
+	if (smf_enabled())
+		uv_register_pate(lpid, dw0, dw1);
+
+	__mmu_partition_table_set_entry(lpid, dw0, dw1);
+	return;
+}
+
 EXPORT_SYMBOL_GPL(mmu_partition_table_set_entry);
 
 static pmd_t *get_pmd_from_cache(struct mm_struct *mm)
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index 9311560..bcc8398 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -29,11 +29,13 @@ 
 #include <asm/powernv.h>
 #include <asm/sections.h>
 #include <asm/trace.h>
+#include <asm/ucall-api.h>
 
 #include <trace/events/thp.h>
 
 unsigned int mmu_pid_bits;
 unsigned int mmu_base_pid;
+unsigned int smf_state;
 
 static int native_register_process_table(unsigned long base, unsigned long pg_sz,
 					 unsigned long table_size)
@@ -623,8 +625,9 @@  void radix__early_init_mmu_secondary(void)
 		lpcr = mfspr(SPRN_LPCR);
 		mtspr(SPRN_LPCR, lpcr | LPCR_UPRT | LPCR_HR);
 
-		mtspr(SPRN_PTCR,
-		      __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
+		if (!smf_enabled())
+			mtspr(SPRN_PTCR, __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
+
 		radix_init_amor();
 	}
 	radix_init_iamr();
@@ -641,7 +644,8 @@  void radix__mmu_cleanup_all(void)
 	if (!firmware_has_feature(FW_FEATURE_LPAR)) {
 		lpcr = mfspr(SPRN_LPCR);
 		mtspr(SPRN_LPCR, lpcr & ~LPCR_UPRT);
-		mtspr(SPRN_PTCR, 0);
+		if (!smf_enabled())
+			mtspr(SPRN_PTCR, 0);
 		powernv_set_nmmu_ptcr(0);
 		radix__flush_tlb_all();
 	}