|
Michal Suchanek |
42e06b |
From 7ef3d06f1bc4a5e62273726f3dc2bd258ae1c71f Mon Sep 17 00:00:00 2001
|
|
Michal Suchanek |
42e06b |
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
|
Michal Suchanek |
42e06b |
Date: Thu, 28 Jul 2022 00:32:18 +1000
|
|
Michal Suchanek |
42e06b |
Subject: [PATCH] powerpc/powernv/kvm: Use darn for H_RANDOM on Power9
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
References: bsc#1065729
|
|
Michal Suchanek |
42e06b |
Patch-mainline: v6.0-rc1
|
|
Michal Suchanek |
42e06b |
Git-commit: 7ef3d06f1bc4a5e62273726f3dc2bd258ae1c71f
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
The existing logic in KVM to support guests calling H_RANDOM only works
|
|
Michal Suchanek |
42e06b |
on Power8, because it looks for an RNG in the device tree, but on Power9
|
|
Michal Suchanek |
42e06b |
we just use darn.
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
In addition the existing code needs to work in real mode, so we have the
|
|
Michal Suchanek |
42e06b |
special cased powernv_get_random_real_mode() to deal with that.
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
Instead just have KVM call ppc_md.get_random_seed(), and do the real
|
|
Michal Suchanek |
42e06b |
mode check inside of there, that way we use whatever RNG is available,
|
|
Michal Suchanek |
42e06b |
including darn on Power9.
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
Fixes: e928e9cb3601 ("KVM: PPC: Book3S HV: Add fast real-mode H_RANDOM implementation.")
|
|
Michal Suchanek |
42e06b |
Cc: stable@vger.kernel.org # v4.1+
|
|
Michal Suchanek |
42e06b |
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
|
Michal Suchanek |
42e06b |
Tested-by: Sachin Sant <sachinp@linux.ibm.com>
|
|
Michal Suchanek |
42e06b |
[mpe: Rebase on previous commit, update change log appropriately]
|
|
Michal Suchanek |
42e06b |
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
|
|
Michal Suchanek |
42e06b |
Link: https://lore.kernel.org/r/20220727143219.2684192-2-mpe@ellerman.id.au
|
|
Michal Suchanek |
42e06b |
Acked-by: Michal Suchanek <msuchanek@suse.de>
|
|
Michal Suchanek |
42e06b |
---
|
|
Michal Suchanek |
42e06b |
arch/powerpc/include/asm/archrandom.h | 5 ----
|
|
Michal Suchanek |
42e06b |
arch/powerpc/kvm/book3s_hv_builtin.c | 7 +++---
|
|
Michal Suchanek |
42e06b |
arch/powerpc/platforms/powernv/rng.c | 36 ++++++---------------------
|
|
Michal Suchanek |
42e06b |
3 files changed, 12 insertions(+), 36 deletions(-)
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
diff --git a/arch/powerpc/include/asm/archrandom.h b/arch/powerpc/include/asm/archrandom.h
|
|
Michal Suchanek |
42e06b |
index 9a53e29680f4..258174304904 100644
|
|
Michal Suchanek |
42e06b |
--- a/arch/powerpc/include/asm/archrandom.h
|
|
Michal Suchanek |
42e06b |
+++ b/arch/powerpc/include/asm/archrandom.h
|
|
Michal Suchanek |
42e06b |
@@ -38,12 +38,7 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
|
|
Michal Suchanek |
42e06b |
#endif /* CONFIG_ARCH_RANDOM */
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
#ifdef CONFIG_PPC_POWERNV
|
|
Michal Suchanek |
42e06b |
-int powernv_hwrng_present(void);
|
|
Michal Suchanek |
42e06b |
int powernv_get_random_long(unsigned long *v);
|
|
Michal Suchanek |
42e06b |
-int powernv_get_random_real_mode(unsigned long *v);
|
|
Michal Suchanek |
42e06b |
-#else
|
|
Michal Suchanek |
42e06b |
-static inline int powernv_hwrng_present(void) { return 0; }
|
|
Michal Suchanek |
42e06b |
-static inline int powernv_get_random_real_mode(unsigned long *v) { return 0; }
|
|
Michal Suchanek |
42e06b |
#endif
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
#endif /* _ASM_POWERPC_ARCHRANDOM_H */
|
|
Michal Suchanek |
42e06b |
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
|
|
Michal Suchanek |
42e06b |
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
|
|
Michal Suchanek |
42e06b |
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
|
|
Michal Suchanek |
42e06b |
@@ -19,7 +19,7 @@
|
|
Michal Suchanek |
42e06b |
#include <asm/cputable.h>
|
|
Michal Suchanek |
42e06b |
#include <asm/kvm_ppc.h>
|
|
Michal Suchanek |
42e06b |
#include <asm/kvm_book3s.h>
|
|
Michal Suchanek |
42e06b |
-#include <asm/archrandom.h>
|
|
Michal Suchanek |
42e06b |
+#include <asm/machdep.h>
|
|
Michal Suchanek |
42e06b |
#include <asm/xics.h>
|
|
Michal Suchanek |
42e06b |
#include <asm/xive.h>
|
|
Michal Suchanek |
42e06b |
#include <asm/dbell.h>
|
|
Michal Suchanek |
42e06b |
@@ -176,20 +176,14 @@ EXPORT_SYMBOL_GPL(kvmppc_hcall_impl_hv_realmode);
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
int kvmppc_hwrng_present(void)
|
|
Michal Suchanek |
42e06b |
{
|
|
Michal Suchanek |
42e06b |
- return powernv_hwrng_present();
|
|
Michal Suchanek |
42e06b |
+ return ppc_md.get_random_seed != NULL;
|
|
Michal Suchanek |
42e06b |
}
|
|
Michal Suchanek |
42e06b |
EXPORT_SYMBOL_GPL(kvmppc_hwrng_present);
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
long kvmppc_h_random(struct kvm_vcpu *vcpu)
|
|
Michal Suchanek |
42e06b |
{
|
|
Michal Suchanek |
42e06b |
- int r;
|
|
Michal Suchanek |
42e06b |
-
|
|
Michal Suchanek |
42e06b |
- /* Only need to do the expensive mfmsr() on radix */
|
|
Michal Suchanek |
42e06b |
- if (kvm_is_radix(vcpu->kvm) && (mfmsr() & MSR_IR))
|
|
Michal Suchanek |
42e06b |
- r = powernv_get_random_long(&vcpu->arch.regs.gpr[4]);
|
|
Michal Suchanek |
42e06b |
- else
|
|
Michal Suchanek |
42e06b |
- r = powernv_get_random_real_mode(&vcpu->arch.regs.gpr[4]);
|
|
Michal Suchanek |
42e06b |
- if (r)
|
|
Michal Suchanek |
42e06b |
+ if (ppc_md.get_random_seed &&
|
|
Michal Suchanek |
42e06b |
+ ppc_md.get_random_seed(&vcpu->arch.regs.gpr[4]))
|
|
Michal Suchanek |
42e06b |
return H_SUCCESS;
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
return H_HARDWARE;
|
|
Michal Suchanek |
42e06b |
diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c
|
|
Michal Suchanek |
42e06b |
index 2287c9cd0cd5..d19305292e1e 100644
|
|
Michal Suchanek |
42e06b |
--- a/arch/powerpc/platforms/powernv/rng.c
|
|
Michal Suchanek |
42e06b |
+++ b/arch/powerpc/platforms/powernv/rng.c
|
|
Michal Suchanek |
42e06b |
@@ -29,15 +29,6 @@ struct powernv_rng {
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
static DEFINE_PER_CPU(struct powernv_rng *, powernv_rng);
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
-int powernv_hwrng_present(void)
|
|
Michal Suchanek |
42e06b |
-{
|
|
Michal Suchanek |
42e06b |
- struct powernv_rng *rng;
|
|
Michal Suchanek |
42e06b |
-
|
|
Michal Suchanek |
42e06b |
- rng = get_cpu_var(powernv_rng);
|
|
Michal Suchanek |
42e06b |
- put_cpu_var(rng);
|
|
Michal Suchanek |
42e06b |
- return rng != NULL;
|
|
Michal Suchanek |
42e06b |
-}
|
|
Michal Suchanek |
42e06b |
-
|
|
Michal Suchanek |
42e06b |
static unsigned long rng_whiten(struct powernv_rng *rng, unsigned long val)
|
|
Michal Suchanek |
42e06b |
{
|
|
Michal Suchanek |
42e06b |
unsigned long parity;
|
|
Michal Suchanek |
42e06b |
@@ -58,19 +49,6 @@ static unsigned long rng_whiten(struct powernv_rng *rng, unsigned long val)
|
|
Michal Suchanek |
42e06b |
return val;
|
|
Michal Suchanek |
42e06b |
}
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
-int powernv_get_random_real_mode(unsigned long *v)
|
|
Michal Suchanek |
42e06b |
-{
|
|
Michal Suchanek |
42e06b |
- struct powernv_rng *rng;
|
|
Michal Suchanek |
42e06b |
-
|
|
Michal Suchanek |
42e06b |
- rng = raw_cpu_read(powernv_rng);
|
|
Michal Suchanek |
42e06b |
- if (!rng)
|
|
Michal Suchanek |
42e06b |
- return 0;
|
|
Michal Suchanek |
42e06b |
-
|
|
Michal Suchanek |
42e06b |
- *v = rng_whiten(rng, __raw_rm_readq(rng->regs_real));
|
|
Michal Suchanek |
42e06b |
-
|
|
Michal Suchanek |
42e06b |
- return 1;
|
|
Michal Suchanek |
42e06b |
-}
|
|
Michal Suchanek |
42e06b |
-
|
|
Michal Suchanek |
42e06b |
static int powernv_get_random_darn(unsigned long *v)
|
|
Michal Suchanek |
42e06b |
{
|
|
Michal Suchanek |
42e06b |
unsigned long val;
|
|
Michal Suchanek |
42e06b |
@@ -107,12 +85,14 @@ int powernv_get_random_long(unsigned long *v)
|
|
Michal Suchanek |
42e06b |
{
|
|
Michal Suchanek |
42e06b |
struct powernv_rng *rng;
|
|
Michal Suchanek |
42e06b |
|
|
Michal Suchanek |
42e06b |
- rng = get_cpu_var(powernv_rng);
|
|
Michal Suchanek |
42e06b |
-
|
|
Michal Suchanek |
42e06b |
- *v = rng_whiten(rng, in_be64(rng->regs));
|
|
Michal Suchanek |
42e06b |
-
|
|
Michal Suchanek |
42e06b |
- put_cpu_var(rng);
|
|
Michal Suchanek |
42e06b |
-
|
|
Michal Suchanek |
42e06b |
+ if (mfmsr() & MSR_DR) {
|
|
Michal Suchanek |
42e06b |
+ rng = get_cpu_var(powernv_rng);
|
|
Michal Suchanek |
42e06b |
+ *v = rng_whiten(rng, in_be64(rng->regs));
|
|
Michal Suchanek |
42e06b |
+ put_cpu_var(rng);
|
|
Michal Suchanek |
42e06b |
+ } else {
|
|
Michal Suchanek |
42e06b |
+ rng = raw_cpu_read(powernv_rng);
|
|
Michal Suchanek |
42e06b |
+ *v = rng_whiten(rng, __raw_rm_readq(rng->regs_real));
|
|
Michal Suchanek |
42e06b |
+ }
|
|
Michal Suchanek |
42e06b |
return 1;
|
|
Michal Suchanek |
42e06b |
}
|
|
Michal Suchanek |
42e06b |
EXPORT_SYMBOL_GPL(powernv_get_random_long);
|
|
Michal Suchanek |
42e06b |
--
|
|
Michal Suchanek |
42e06b |
2.35.3
|
|
Michal Suchanek |
42e06b |
|