Skip to content

Commit 7ef3d06

Browse files
zx2c4mpe
authored andcommitted
powerpc/powernv/kvm: Use darn for H_RANDOM on Power9
The existing logic in KVM to support guests calling H_RANDOM only works on Power8, because it looks for an RNG in the device tree, but on Power9 we just use darn. In addition the existing code needs to work in real mode, so we have the special cased powernv_get_random_real_mode() to deal with that. Instead just have KVM call ppc_md.get_random_seed(), and do the real mode check inside of there, that way we use whatever RNG is available, including darn on Power9. Fixes: e928e9c ("KVM: PPC: Book3S HV: Add fast real-mode H_RANDOM implementation.") Cc: stable@vger.kernel.org # v4.1+ Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Tested-by: Sachin Sant <sachinp@linux.ibm.com> [mpe: Rebase on previous commit, update change log appropriately] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20220727143219.2684192-2-mpe@ellerman.id.au
1 parent 90b5d4f commit 7ef3d06

3 files changed

Lines changed: 12 additions & 36 deletions

File tree

arch/powerpc/include/asm/archrandom.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,7 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
3838
#endif /* CONFIG_ARCH_RANDOM */
3939

4040
#ifdef CONFIG_PPC_POWERNV
41-
int powernv_hwrng_present(void);
4241
int powernv_get_random_long(unsigned long *v);
43-
int powernv_get_random_real_mode(unsigned long *v);
44-
#else
45-
static inline int powernv_hwrng_present(void) { return 0; }
46-
static inline int powernv_get_random_real_mode(unsigned long *v) { return 0; }
4742
#endif
4843

4944
#endif /* _ASM_POWERPC_ARCHRANDOM_H */

arch/powerpc/kvm/book3s_hv_builtin.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include <asm/interrupt.h>
2020
#include <asm/kvm_ppc.h>
2121
#include <asm/kvm_book3s.h>
22-
#include <asm/archrandom.h>
22+
#include <asm/machdep.h>
2323
#include <asm/xics.h>
2424
#include <asm/xive.h>
2525
#include <asm/dbell.h>
@@ -176,13 +176,14 @@ EXPORT_SYMBOL_GPL(kvmppc_hcall_impl_hv_realmode);
176176

177177
int kvmppc_hwrng_present(void)
178178
{
179-
return powernv_hwrng_present();
179+
return ppc_md.get_random_seed != NULL;
180180
}
181181
EXPORT_SYMBOL_GPL(kvmppc_hwrng_present);
182182

183183
long kvmppc_rm_h_random(struct kvm_vcpu *vcpu)
184184
{
185-
if (powernv_get_random_real_mode(&vcpu->arch.regs.gpr[4]))
185+
if (ppc_md.get_random_seed &&
186+
ppc_md.get_random_seed(&vcpu->arch.regs.gpr[4]))
186187
return H_SUCCESS;
187188

188189
return H_HARDWARE;

arch/powerpc/platforms/powernv/rng.c

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,6 @@ struct powernv_rng {
2929

3030
static DEFINE_PER_CPU(struct powernv_rng *, powernv_rng);
3131

32-
int powernv_hwrng_present(void)
33-
{
34-
struct powernv_rng *rng;
35-
36-
rng = get_cpu_var(powernv_rng);
37-
put_cpu_var(rng);
38-
return rng != NULL;
39-
}
40-
4132
static unsigned long rng_whiten(struct powernv_rng *rng, unsigned long val)
4233
{
4334
unsigned long parity;
@@ -58,19 +49,6 @@ static unsigned long rng_whiten(struct powernv_rng *rng, unsigned long val)
5849
return val;
5950
}
6051

61-
int powernv_get_random_real_mode(unsigned long *v)
62-
{
63-
struct powernv_rng *rng;
64-
65-
rng = raw_cpu_read(powernv_rng);
66-
if (!rng)
67-
return 0;
68-
69-
*v = rng_whiten(rng, __raw_rm_readq(rng->regs_real));
70-
71-
return 1;
72-
}
73-
7452
static int powernv_get_random_darn(unsigned long *v)
7553
{
7654
unsigned long val;
@@ -107,12 +85,14 @@ int powernv_get_random_long(unsigned long *v)
10785
{
10886
struct powernv_rng *rng;
10987

110-
rng = get_cpu_var(powernv_rng);
111-
112-
*v = rng_whiten(rng, in_be64(rng->regs));
113-
114-
put_cpu_var(rng);
115-
88+
if (mfmsr() & MSR_DR) {
89+
rng = get_cpu_var(powernv_rng);
90+
*v = rng_whiten(rng, in_be64(rng->regs));
91+
put_cpu_var(rng);
92+
} else {
93+
rng = raw_cpu_read(powernv_rng);
94+
*v = rng_whiten(rng, __raw_rm_readq(rng->regs_real));
95+
}
11696
return 1;
11797
}
11898
EXPORT_SYMBOL_GPL(powernv_get_random_long);

0 commit comments

Comments
 (0)