Skip to content

Commit 0a86512

Browse files
avpatelbonzini
authored andcommitted
RISC-V: KVM: Factor-out FP virtualization into separate sources
The timer and SBI virtualization is already in separate sources. In future, we will have vector and AIA virtualization also added as separate sources. To align with above described modularity, we factor-out FP virtualization into separate sources. Signed-off-by: Anup Patel <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 4e33868 commit 0a86512

File tree

5 files changed

+228
-176
lines changed

5 files changed

+228
-176
lines changed

arch/riscv/include/asm/kvm_host.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/types.h>
1313
#include <linux/kvm.h>
1414
#include <linux/kvm_types.h>
15+
#include <asm/kvm_vcpu_fp.h>
1516
#include <asm/kvm_vcpu_timer.h>
1617

1718
#ifdef CONFIG_64BIT
@@ -247,10 +248,6 @@ int kvm_riscv_vcpu_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
247248
struct kvm_cpu_trap *trap);
248249

249250
void __kvm_riscv_switch_to(struct kvm_vcpu_arch *vcpu_arch);
250-
void __kvm_riscv_fp_f_save(struct kvm_cpu_context *context);
251-
void __kvm_riscv_fp_f_restore(struct kvm_cpu_context *context);
252-
void __kvm_riscv_fp_d_save(struct kvm_cpu_context *context);
253-
void __kvm_riscv_fp_d_restore(struct kvm_cpu_context *context);
254251

255252
int kvm_riscv_vcpu_set_interrupt(struct kvm_vcpu *vcpu, unsigned int irq);
256253
int kvm_riscv_vcpu_unset_interrupt(struct kvm_vcpu *vcpu, unsigned int irq);

arch/riscv/include/asm/kvm_vcpu_fp.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (C) 2021 Western Digital Corporation or its affiliates.
4+
*
5+
* Authors:
6+
* Atish Patra <[email protected]>
7+
* Anup Patel <[email protected]>
8+
*/
9+
10+
#ifndef __KVM_VCPU_RISCV_FP_H
11+
#define __KVM_VCPU_RISCV_FP_H
12+
13+
#include <linux/types.h>
14+
15+
struct kvm_cpu_context;
16+
17+
#ifdef CONFIG_FPU
18+
void __kvm_riscv_fp_f_save(struct kvm_cpu_context *context);
19+
void __kvm_riscv_fp_f_restore(struct kvm_cpu_context *context);
20+
void __kvm_riscv_fp_d_save(struct kvm_cpu_context *context);
21+
void __kvm_riscv_fp_d_restore(struct kvm_cpu_context *context);
22+
23+
void kvm_riscv_vcpu_fp_reset(struct kvm_vcpu *vcpu);
24+
void kvm_riscv_vcpu_guest_fp_save(struct kvm_cpu_context *cntx,
25+
unsigned long isa);
26+
void kvm_riscv_vcpu_guest_fp_restore(struct kvm_cpu_context *cntx,
27+
unsigned long isa);
28+
void kvm_riscv_vcpu_host_fp_save(struct kvm_cpu_context *cntx);
29+
void kvm_riscv_vcpu_host_fp_restore(struct kvm_cpu_context *cntx);
30+
#else
31+
static inline void kvm_riscv_vcpu_fp_reset(struct kvm_vcpu *vcpu)
32+
{
33+
}
34+
static inline void kvm_riscv_vcpu_guest_fp_save(struct kvm_cpu_context *cntx,
35+
unsigned long isa)
36+
{
37+
}
38+
static inline void kvm_riscv_vcpu_guest_fp_restore(
39+
struct kvm_cpu_context *cntx,
40+
unsigned long isa)
41+
{
42+
}
43+
static inline void kvm_riscv_vcpu_host_fp_save(struct kvm_cpu_context *cntx)
44+
{
45+
}
46+
static inline void kvm_riscv_vcpu_host_fp_restore(
47+
struct kvm_cpu_context *cntx)
48+
{
49+
}
50+
#endif
51+
52+
int kvm_riscv_vcpu_get_reg_fp(struct kvm_vcpu *vcpu,
53+
const struct kvm_one_reg *reg,
54+
unsigned long rtype);
55+
int kvm_riscv_vcpu_set_reg_fp(struct kvm_vcpu *vcpu,
56+
const struct kvm_one_reg *reg,
57+
unsigned long rtype);
58+
59+
#endif

arch/riscv/kvm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ kvm-y += tlb.o
2020
kvm-y += mmu.o
2121
kvm-y += vcpu.o
2222
kvm-y += vcpu_exit.o
23+
kvm-y += vcpu_fp.o
2324
kvm-y += vcpu_switch.o
2425
kvm-y += vcpu_sbi.o
2526
kvm-y += vcpu_timer.o

arch/riscv/kvm/vcpu.c

Lines changed: 0 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -38,86 +38,6 @@ const struct kvm_stats_header kvm_vcpu_stats_header = {
3838
sizeof(kvm_vcpu_stats_desc),
3939
};
4040

41-
#ifdef CONFIG_FPU
42-
static void kvm_riscv_vcpu_fp_reset(struct kvm_vcpu *vcpu)
43-
{
44-
unsigned long isa = vcpu->arch.isa;
45-
struct kvm_cpu_context *cntx = &vcpu->arch.guest_context;
46-
47-
cntx->sstatus &= ~SR_FS;
48-
if (riscv_isa_extension_available(&isa, f) ||
49-
riscv_isa_extension_available(&isa, d))
50-
cntx->sstatus |= SR_FS_INITIAL;
51-
else
52-
cntx->sstatus |= SR_FS_OFF;
53-
}
54-
55-
static void kvm_riscv_vcpu_fp_clean(struct kvm_cpu_context *cntx)
56-
{
57-
cntx->sstatus &= ~SR_FS;
58-
cntx->sstatus |= SR_FS_CLEAN;
59-
}
60-
61-
static void kvm_riscv_vcpu_guest_fp_save(struct kvm_cpu_context *cntx,
62-
unsigned long isa)
63-
{
64-
if ((cntx->sstatus & SR_FS) == SR_FS_DIRTY) {
65-
if (riscv_isa_extension_available(&isa, d))
66-
__kvm_riscv_fp_d_save(cntx);
67-
else if (riscv_isa_extension_available(&isa, f))
68-
__kvm_riscv_fp_f_save(cntx);
69-
kvm_riscv_vcpu_fp_clean(cntx);
70-
}
71-
}
72-
73-
static void kvm_riscv_vcpu_guest_fp_restore(struct kvm_cpu_context *cntx,
74-
unsigned long isa)
75-
{
76-
if ((cntx->sstatus & SR_FS) != SR_FS_OFF) {
77-
if (riscv_isa_extension_available(&isa, d))
78-
__kvm_riscv_fp_d_restore(cntx);
79-
else if (riscv_isa_extension_available(&isa, f))
80-
__kvm_riscv_fp_f_restore(cntx);
81-
kvm_riscv_vcpu_fp_clean(cntx);
82-
}
83-
}
84-
85-
static void kvm_riscv_vcpu_host_fp_save(struct kvm_cpu_context *cntx)
86-
{
87-
/* No need to check host sstatus as it can be modified outside */
88-
if (riscv_isa_extension_available(NULL, d))
89-
__kvm_riscv_fp_d_save(cntx);
90-
else if (riscv_isa_extension_available(NULL, f))
91-
__kvm_riscv_fp_f_save(cntx);
92-
}
93-
94-
static void kvm_riscv_vcpu_host_fp_restore(struct kvm_cpu_context *cntx)
95-
{
96-
if (riscv_isa_extension_available(NULL, d))
97-
__kvm_riscv_fp_d_restore(cntx);
98-
else if (riscv_isa_extension_available(NULL, f))
99-
__kvm_riscv_fp_f_restore(cntx);
100-
}
101-
#else
102-
static void kvm_riscv_vcpu_fp_reset(struct kvm_vcpu *vcpu)
103-
{
104-
}
105-
static void kvm_riscv_vcpu_guest_fp_save(struct kvm_cpu_context *cntx,
106-
unsigned long isa)
107-
{
108-
}
109-
static void kvm_riscv_vcpu_guest_fp_restore(struct kvm_cpu_context *cntx,
110-
unsigned long isa)
111-
{
112-
}
113-
static void kvm_riscv_vcpu_host_fp_save(struct kvm_cpu_context *cntx)
114-
{
115-
}
116-
static void kvm_riscv_vcpu_host_fp_restore(struct kvm_cpu_context *cntx)
117-
{
118-
}
119-
#endif
120-
12141
#define KVM_RISCV_ISA_ALLOWED (riscv_isa_extension_mask(a) | \
12242
riscv_isa_extension_mask(c) | \
12343
riscv_isa_extension_mask(d) | \
@@ -414,98 +334,6 @@ static int kvm_riscv_vcpu_set_reg_csr(struct kvm_vcpu *vcpu,
414334
return 0;
415335
}
416336

417-
static int kvm_riscv_vcpu_get_reg_fp(struct kvm_vcpu *vcpu,
418-
const struct kvm_one_reg *reg,
419-
unsigned long rtype)
420-
{
421-
struct kvm_cpu_context *cntx = &vcpu->arch.guest_context;
422-
unsigned long isa = vcpu->arch.isa;
423-
unsigned long __user *uaddr =
424-
(unsigned long __user *)(unsigned long)reg->addr;
425-
unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
426-
KVM_REG_SIZE_MASK |
427-
rtype);
428-
void *reg_val;
429-
430-
if ((rtype == KVM_REG_RISCV_FP_F) &&
431-
riscv_isa_extension_available(&isa, f)) {
432-
if (KVM_REG_SIZE(reg->id) != sizeof(u32))
433-
return -EINVAL;
434-
if (reg_num == KVM_REG_RISCV_FP_F_REG(fcsr))
435-
reg_val = &cntx->fp.f.fcsr;
436-
else if ((KVM_REG_RISCV_FP_F_REG(f[0]) <= reg_num) &&
437-
reg_num <= KVM_REG_RISCV_FP_F_REG(f[31]))
438-
reg_val = &cntx->fp.f.f[reg_num];
439-
else
440-
return -EINVAL;
441-
} else if ((rtype == KVM_REG_RISCV_FP_D) &&
442-
riscv_isa_extension_available(&isa, d)) {
443-
if (reg_num == KVM_REG_RISCV_FP_D_REG(fcsr)) {
444-
if (KVM_REG_SIZE(reg->id) != sizeof(u32))
445-
return -EINVAL;
446-
reg_val = &cntx->fp.d.fcsr;
447-
} else if ((KVM_REG_RISCV_FP_D_REG(f[0]) <= reg_num) &&
448-
reg_num <= KVM_REG_RISCV_FP_D_REG(f[31])) {
449-
if (KVM_REG_SIZE(reg->id) != sizeof(u64))
450-
return -EINVAL;
451-
reg_val = &cntx->fp.d.f[reg_num];
452-
} else
453-
return -EINVAL;
454-
} else
455-
return -EINVAL;
456-
457-
if (copy_to_user(uaddr, reg_val, KVM_REG_SIZE(reg->id)))
458-
return -EFAULT;
459-
460-
return 0;
461-
}
462-
463-
static int kvm_riscv_vcpu_set_reg_fp(struct kvm_vcpu *vcpu,
464-
const struct kvm_one_reg *reg,
465-
unsigned long rtype)
466-
{
467-
struct kvm_cpu_context *cntx = &vcpu->arch.guest_context;
468-
unsigned long isa = vcpu->arch.isa;
469-
unsigned long __user *uaddr =
470-
(unsigned long __user *)(unsigned long)reg->addr;
471-
unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
472-
KVM_REG_SIZE_MASK |
473-
rtype);
474-
void *reg_val;
475-
476-
if ((rtype == KVM_REG_RISCV_FP_F) &&
477-
riscv_isa_extension_available(&isa, f)) {
478-
if (KVM_REG_SIZE(reg->id) != sizeof(u32))
479-
return -EINVAL;
480-
if (reg_num == KVM_REG_RISCV_FP_F_REG(fcsr))
481-
reg_val = &cntx->fp.f.fcsr;
482-
else if ((KVM_REG_RISCV_FP_F_REG(f[0]) <= reg_num) &&
483-
reg_num <= KVM_REG_RISCV_FP_F_REG(f[31]))
484-
reg_val = &cntx->fp.f.f[reg_num];
485-
else
486-
return -EINVAL;
487-
} else if ((rtype == KVM_REG_RISCV_FP_D) &&
488-
riscv_isa_extension_available(&isa, d)) {
489-
if (reg_num == KVM_REG_RISCV_FP_D_REG(fcsr)) {
490-
if (KVM_REG_SIZE(reg->id) != sizeof(u32))
491-
return -EINVAL;
492-
reg_val = &cntx->fp.d.fcsr;
493-
} else if ((KVM_REG_RISCV_FP_D_REG(f[0]) <= reg_num) &&
494-
reg_num <= KVM_REG_RISCV_FP_D_REG(f[31])) {
495-
if (KVM_REG_SIZE(reg->id) != sizeof(u64))
496-
return -EINVAL;
497-
reg_val = &cntx->fp.d.f[reg_num];
498-
} else
499-
return -EINVAL;
500-
} else
501-
return -EINVAL;
502-
503-
if (copy_from_user(reg_val, uaddr, KVM_REG_SIZE(reg->id)))
504-
return -EFAULT;
505-
506-
return 0;
507-
}
508-
509337
static int kvm_riscv_vcpu_set_reg(struct kvm_vcpu *vcpu,
510338
const struct kvm_one_reg *reg)
511339
{

0 commit comments

Comments
 (0)