Skip to content

Commit b539627

Browse files
committed
Merge tag 'kvm-riscv-6.5-1' of https://github.com/kvm-riscv/linux into HEAD
KVM/riscv changes for 6.5 - Redirect AMO load/store misaligned traps to KVM guest - Trap-n-emulate AIA in-kernel irqchip for KVM guest - Svnapot support for KVM Guest
2 parents a443e26 + 07f225b commit b539627

20 files changed

Lines changed: 3100 additions & 61 deletions

File tree

arch/riscv/include/asm/csr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@
8282
#define EXC_INST_ACCESS 1
8383
#define EXC_INST_ILLEGAL 2
8484
#define EXC_BREAKPOINT 3
85+
#define EXC_LOAD_MISALIGNED 4
8586
#define EXC_LOAD_ACCESS 5
87+
#define EXC_STORE_MISALIGNED 6
8688
#define EXC_STORE_ACCESS 7
8789
#define EXC_SYSCALL 8
8890
#define EXC_HYPERVISOR_SYSCALL 9

arch/riscv/include/asm/kvm_aia.h

Lines changed: 77 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,33 @@ struct kvm_aia {
2020

2121
/* In-kernel irqchip initialized */
2222
bool initialized;
23+
24+
/* Virtualization mode (Emulation, HW Accelerated, or Auto) */
25+
u32 mode;
26+
27+
/* Number of MSIs */
28+
u32 nr_ids;
29+
30+
/* Number of wired IRQs */
31+
u32 nr_sources;
32+
33+
/* Number of group bits in IMSIC address */
34+
u32 nr_group_bits;
35+
36+
/* Position of group bits in IMSIC address */
37+
u32 nr_group_shift;
38+
39+
/* Number of hart bits in IMSIC address */
40+
u32 nr_hart_bits;
41+
42+
/* Number of guest bits in IMSIC address */
43+
u32 nr_guest_bits;
44+
45+
/* Guest physical address of APLIC */
46+
gpa_t aplic_addr;
47+
48+
/* Internal state of APLIC */
49+
void *aplic_state;
2350
};
2451

2552
struct kvm_vcpu_aia_csr {
@@ -38,25 +65,53 @@ struct kvm_vcpu_aia {
3865

3966
/* CPU AIA CSR context upon Guest VCPU reset */
4067
struct kvm_vcpu_aia_csr guest_reset_csr;
68+
69+
/* Guest physical address of IMSIC for this VCPU */
70+
gpa_t imsic_addr;
71+
72+
/* HART index of IMSIC extacted from guest physical address */
73+
u32 hart_index;
74+
75+
/* Internal state of IMSIC for this VCPU */
76+
void *imsic_state;
4177
};
4278

79+
#define KVM_RISCV_AIA_UNDEF_ADDR (-1)
80+
4381
#define kvm_riscv_aia_initialized(k) ((k)->arch.aia.initialized)
4482

4583
#define irqchip_in_kernel(k) ((k)->arch.aia.in_kernel)
4684

85+
extern unsigned int kvm_riscv_aia_nr_hgei;
86+
extern unsigned int kvm_riscv_aia_max_ids;
4787
DECLARE_STATIC_KEY_FALSE(kvm_riscv_aia_available);
4888
#define kvm_riscv_aia_available() \
4989
static_branch_unlikely(&kvm_riscv_aia_available)
5090

91+
extern struct kvm_device_ops kvm_riscv_aia_device_ops;
92+
93+
void kvm_riscv_vcpu_aia_imsic_release(struct kvm_vcpu *vcpu);
94+
int kvm_riscv_vcpu_aia_imsic_update(struct kvm_vcpu *vcpu);
95+
5196
#define KVM_RISCV_AIA_IMSIC_TOPEI (ISELECT_MASK + 1)
52-
static inline int kvm_riscv_vcpu_aia_imsic_rmw(struct kvm_vcpu *vcpu,
53-
unsigned long isel,
54-
unsigned long *val,
55-
unsigned long new_val,
56-
unsigned long wr_mask)
57-
{
58-
return 0;
59-
}
97+
int kvm_riscv_vcpu_aia_imsic_rmw(struct kvm_vcpu *vcpu, unsigned long isel,
98+
unsigned long *val, unsigned long new_val,
99+
unsigned long wr_mask);
100+
int kvm_riscv_aia_imsic_rw_attr(struct kvm *kvm, unsigned long type,
101+
bool write, unsigned long *val);
102+
int kvm_riscv_aia_imsic_has_attr(struct kvm *kvm, unsigned long type);
103+
void kvm_riscv_vcpu_aia_imsic_reset(struct kvm_vcpu *vcpu);
104+
int kvm_riscv_vcpu_aia_imsic_inject(struct kvm_vcpu *vcpu,
105+
u32 guest_index, u32 offset, u32 iid);
106+
int kvm_riscv_vcpu_aia_imsic_init(struct kvm_vcpu *vcpu);
107+
void kvm_riscv_vcpu_aia_imsic_cleanup(struct kvm_vcpu *vcpu);
108+
109+
int kvm_riscv_aia_aplic_set_attr(struct kvm *kvm, unsigned long type, u32 v);
110+
int kvm_riscv_aia_aplic_get_attr(struct kvm *kvm, unsigned long type, u32 *v);
111+
int kvm_riscv_aia_aplic_has_attr(struct kvm *kvm, unsigned long type);
112+
int kvm_riscv_aia_aplic_inject(struct kvm *kvm, u32 source, bool level);
113+
int kvm_riscv_aia_aplic_init(struct kvm *kvm);
114+
void kvm_riscv_aia_aplic_cleanup(struct kvm *kvm);
60115

61116
#ifdef CONFIG_32BIT
62117
void kvm_riscv_vcpu_aia_flush_interrupts(struct kvm_vcpu *vcpu);
@@ -93,31 +148,23 @@ int kvm_riscv_vcpu_aia_rmw_ireg(struct kvm_vcpu *vcpu, unsigned int csr_num,
93148
{ .base = CSR_SIREG, .count = 1, .func = kvm_riscv_vcpu_aia_rmw_ireg }, \
94149
{ .base = CSR_STOPEI, .count = 1, .func = kvm_riscv_vcpu_aia_rmw_topei },
95150

96-
static inline int kvm_riscv_vcpu_aia_update(struct kvm_vcpu *vcpu)
97-
{
98-
return 1;
99-
}
100-
101-
static inline void kvm_riscv_vcpu_aia_reset(struct kvm_vcpu *vcpu)
102-
{
103-
}
104-
105-
static inline int kvm_riscv_vcpu_aia_init(struct kvm_vcpu *vcpu)
106-
{
107-
return 0;
108-
}
151+
int kvm_riscv_vcpu_aia_update(struct kvm_vcpu *vcpu);
152+
void kvm_riscv_vcpu_aia_reset(struct kvm_vcpu *vcpu);
153+
int kvm_riscv_vcpu_aia_init(struct kvm_vcpu *vcpu);
154+
void kvm_riscv_vcpu_aia_deinit(struct kvm_vcpu *vcpu);
109155

110-
static inline void kvm_riscv_vcpu_aia_deinit(struct kvm_vcpu *vcpu)
111-
{
112-
}
156+
int kvm_riscv_aia_inject_msi_by_id(struct kvm *kvm, u32 hart_index,
157+
u32 guest_index, u32 iid);
158+
int kvm_riscv_aia_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
159+
int kvm_riscv_aia_inject_irq(struct kvm *kvm, unsigned int irq, bool level);
113160

114-
static inline void kvm_riscv_aia_init_vm(struct kvm *kvm)
115-
{
116-
}
161+
void kvm_riscv_aia_init_vm(struct kvm *kvm);
162+
void kvm_riscv_aia_destroy_vm(struct kvm *kvm);
117163

118-
static inline void kvm_riscv_aia_destroy_vm(struct kvm *kvm)
119-
{
120-
}
164+
int kvm_riscv_aia_alloc_hgei(int cpu, struct kvm_vcpu *owner,
165+
void __iomem **hgei_va, phys_addr_t *hgei_pa);
166+
void kvm_riscv_aia_free_hgei(int cpu, int hgei);
167+
void kvm_riscv_aia_wakeon_hgei(struct kvm_vcpu *owner, bool enable);
121168

122169
void kvm_riscv_aia_enable(void);
123170
void kvm_riscv_aia_disable(void);
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (C) 2021 Western Digital Corporation or its affiliates.
4+
* Copyright (C) 2022 Ventana Micro Systems Inc.
5+
*/
6+
#ifndef __KVM_RISCV_AIA_IMSIC_H
7+
#define __KVM_RISCV_AIA_IMSIC_H
8+
9+
#include <linux/bitops.h>
10+
11+
#define APLIC_MAX_IDC BIT(14)
12+
#define APLIC_MAX_SOURCE 1024
13+
14+
#define APLIC_DOMAINCFG 0x0000
15+
#define APLIC_DOMAINCFG_RDONLY 0x80000000
16+
#define APLIC_DOMAINCFG_IE BIT(8)
17+
#define APLIC_DOMAINCFG_DM BIT(2)
18+
#define APLIC_DOMAINCFG_BE BIT(0)
19+
20+
#define APLIC_SOURCECFG_BASE 0x0004
21+
#define APLIC_SOURCECFG_D BIT(10)
22+
#define APLIC_SOURCECFG_CHILDIDX_MASK 0x000003ff
23+
#define APLIC_SOURCECFG_SM_MASK 0x00000007
24+
#define APLIC_SOURCECFG_SM_INACTIVE 0x0
25+
#define APLIC_SOURCECFG_SM_DETACH 0x1
26+
#define APLIC_SOURCECFG_SM_EDGE_RISE 0x4
27+
#define APLIC_SOURCECFG_SM_EDGE_FALL 0x5
28+
#define APLIC_SOURCECFG_SM_LEVEL_HIGH 0x6
29+
#define APLIC_SOURCECFG_SM_LEVEL_LOW 0x7
30+
31+
#define APLIC_IRQBITS_PER_REG 32
32+
33+
#define APLIC_SETIP_BASE 0x1c00
34+
#define APLIC_SETIPNUM 0x1cdc
35+
36+
#define APLIC_CLRIP_BASE 0x1d00
37+
#define APLIC_CLRIPNUM 0x1ddc
38+
39+
#define APLIC_SETIE_BASE 0x1e00
40+
#define APLIC_SETIENUM 0x1edc
41+
42+
#define APLIC_CLRIE_BASE 0x1f00
43+
#define APLIC_CLRIENUM 0x1fdc
44+
45+
#define APLIC_SETIPNUM_LE 0x2000
46+
#define APLIC_SETIPNUM_BE 0x2004
47+
48+
#define APLIC_GENMSI 0x3000
49+
50+
#define APLIC_TARGET_BASE 0x3004
51+
#define APLIC_TARGET_HART_IDX_SHIFT 18
52+
#define APLIC_TARGET_HART_IDX_MASK 0x3fff
53+
#define APLIC_TARGET_GUEST_IDX_SHIFT 12
54+
#define APLIC_TARGET_GUEST_IDX_MASK 0x3f
55+
#define APLIC_TARGET_IPRIO_MASK 0xff
56+
#define APLIC_TARGET_EIID_MASK 0x7ff
57+
58+
#endif
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (C) 2021 Western Digital Corporation or its affiliates.
4+
* Copyright (C) 2022 Ventana Micro Systems Inc.
5+
*/
6+
#ifndef __KVM_RISCV_AIA_IMSIC_H
7+
#define __KVM_RISCV_AIA_IMSIC_H
8+
9+
#include <linux/types.h>
10+
#include <asm/csr.h>
11+
12+
#define IMSIC_MMIO_PAGE_SHIFT 12
13+
#define IMSIC_MMIO_PAGE_SZ (1UL << IMSIC_MMIO_PAGE_SHIFT)
14+
#define IMSIC_MMIO_PAGE_LE 0x00
15+
#define IMSIC_MMIO_PAGE_BE 0x04
16+
17+
#define IMSIC_MIN_ID 63
18+
#define IMSIC_MAX_ID 2048
19+
20+
#define IMSIC_EIDELIVERY 0x70
21+
22+
#define IMSIC_EITHRESHOLD 0x72
23+
24+
#define IMSIC_EIP0 0x80
25+
#define IMSIC_EIP63 0xbf
26+
#define IMSIC_EIPx_BITS 32
27+
28+
#define IMSIC_EIE0 0xc0
29+
#define IMSIC_EIE63 0xff
30+
#define IMSIC_EIEx_BITS 32
31+
32+
#define IMSIC_FIRST IMSIC_EIDELIVERY
33+
#define IMSIC_LAST IMSIC_EIE63
34+
35+
#define IMSIC_MMIO_SETIPNUM_LE 0x00
36+
#define IMSIC_MMIO_SETIPNUM_BE 0x04
37+
38+
#endif

arch/riscv/include/asm/kvm_host.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
#define KVM_VCPU_MAX_FEATURES 0
2929

30+
#define KVM_IRQCHIP_NUM_PINS 1024
31+
3032
#define KVM_REQ_SLEEP \
3133
KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
3234
#define KVM_REQ_VCPU_RESET KVM_ARCH_REQ(1)
@@ -318,6 +320,8 @@ int kvm_riscv_gstage_vmid_init(struct kvm *kvm);
318320
bool kvm_riscv_gstage_vmid_ver_changed(struct kvm_vmid *vmid);
319321
void kvm_riscv_gstage_vmid_update(struct kvm_vcpu *vcpu);
320322

323+
int kvm_riscv_setup_default_irq_routing(struct kvm *kvm, u32 lines);
324+
321325
void __kvm_riscv_unpriv_trap(void);
322326

323327
unsigned long kvm_riscv_vcpu_unpriv_read(struct kvm_vcpu *vcpu,

arch/riscv/include/asm/kvm_vcpu_sbi.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,15 @@
1414
#define KVM_SBI_VERSION_MAJOR 1
1515
#define KVM_SBI_VERSION_MINOR 0
1616

17+
enum kvm_riscv_sbi_ext_status {
18+
KVM_RISCV_SBI_EXT_UNINITIALIZED,
19+
KVM_RISCV_SBI_EXT_AVAILABLE,
20+
KVM_RISCV_SBI_EXT_UNAVAILABLE,
21+
};
22+
1723
struct kvm_vcpu_sbi_context {
1824
int return_handled;
19-
bool extension_disabled[KVM_RISCV_SBI_EXT_MAX];
25+
enum kvm_riscv_sbi_ext_status ext_status[KVM_RISCV_SBI_EXT_MAX];
2026
};
2127

2228
struct kvm_vcpu_sbi_return {
@@ -66,4 +72,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_hsm;
6672
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental;
6773
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor;
6874

75+
#ifdef CONFIG_RISCV_PMU_SBI
76+
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_pmu;
77+
#endif
6978
#endif /* __RISCV_KVM_VCPU_SBI_H__ */

arch/riscv/include/uapi/asm/kvm.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <asm/bitsperlong.h>
1616
#include <asm/ptrace.h>
1717

18+
#define __KVM_HAVE_IRQ_LINE
1819
#define __KVM_HAVE_READONLY_MEM
1920

2021
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
@@ -121,6 +122,7 @@ enum KVM_RISCV_ISA_EXT_ID {
121122
KVM_RISCV_ISA_EXT_ZICBOZ,
122123
KVM_RISCV_ISA_EXT_ZBB,
123124
KVM_RISCV_ISA_EXT_SSAIA,
125+
KVM_RISCV_ISA_EXT_SVNAPOT,
124126
KVM_RISCV_ISA_EXT_MAX,
125127
};
126128

@@ -203,6 +205,77 @@ enum KVM_RISCV_SBI_EXT_ID {
203205
#define KVM_REG_RISCV_SBI_MULTI_REG_LAST \
204206
KVM_REG_RISCV_SBI_MULTI_REG(KVM_RISCV_SBI_EXT_MAX - 1)
205207

208+
/* Device Control API: RISC-V AIA */
209+
#define KVM_DEV_RISCV_APLIC_ALIGN 0x1000
210+
#define KVM_DEV_RISCV_APLIC_SIZE 0x4000
211+
#define KVM_DEV_RISCV_APLIC_MAX_HARTS 0x4000
212+
#define KVM_DEV_RISCV_IMSIC_ALIGN 0x1000
213+
#define KVM_DEV_RISCV_IMSIC_SIZE 0x1000
214+
215+
#define KVM_DEV_RISCV_AIA_GRP_CONFIG 0
216+
#define KVM_DEV_RISCV_AIA_CONFIG_MODE 0
217+
#define KVM_DEV_RISCV_AIA_CONFIG_IDS 1
218+
#define KVM_DEV_RISCV_AIA_CONFIG_SRCS 2
219+
#define KVM_DEV_RISCV_AIA_CONFIG_GROUP_BITS 3
220+
#define KVM_DEV_RISCV_AIA_CONFIG_GROUP_SHIFT 4
221+
#define KVM_DEV_RISCV_AIA_CONFIG_HART_BITS 5
222+
#define KVM_DEV_RISCV_AIA_CONFIG_GUEST_BITS 6
223+
224+
/*
225+
* Modes of RISC-V AIA device:
226+
* 1) EMUL (aka Emulation): Trap-n-emulate IMSIC
227+
* 2) HWACCEL (aka HW Acceleration): Virtualize IMSIC using IMSIC guest files
228+
* 3) AUTO (aka Automatic): Virtualize IMSIC using IMSIC guest files whenever
229+
* available otherwise fallback to trap-n-emulation
230+
*/
231+
#define KVM_DEV_RISCV_AIA_MODE_EMUL 0
232+
#define KVM_DEV_RISCV_AIA_MODE_HWACCEL 1
233+
#define KVM_DEV_RISCV_AIA_MODE_AUTO 2
234+
235+
#define KVM_DEV_RISCV_AIA_IDS_MIN 63
236+
#define KVM_DEV_RISCV_AIA_IDS_MAX 2048
237+
#define KVM_DEV_RISCV_AIA_SRCS_MAX 1024
238+
#define KVM_DEV_RISCV_AIA_GROUP_BITS_MAX 8
239+
#define KVM_DEV_RISCV_AIA_GROUP_SHIFT_MIN 24
240+
#define KVM_DEV_RISCV_AIA_GROUP_SHIFT_MAX 56
241+
#define KVM_DEV_RISCV_AIA_HART_BITS_MAX 16
242+
#define KVM_DEV_RISCV_AIA_GUEST_BITS_MAX 8
243+
244+
#define KVM_DEV_RISCV_AIA_GRP_ADDR 1
245+
#define KVM_DEV_RISCV_AIA_ADDR_APLIC 0
246+
#define KVM_DEV_RISCV_AIA_ADDR_IMSIC(__vcpu) (1 + (__vcpu))
247+
#define KVM_DEV_RISCV_AIA_ADDR_MAX \
248+
(1 + KVM_DEV_RISCV_APLIC_MAX_HARTS)
249+
250+
#define KVM_DEV_RISCV_AIA_GRP_CTRL 2
251+
#define KVM_DEV_RISCV_AIA_CTRL_INIT 0
252+
253+
/*
254+
* The device attribute type contains the memory mapped offset of the
255+
* APLIC register (range 0x0000-0x3FFF) and it must be 4-byte aligned.
256+
*/
257+
#define KVM_DEV_RISCV_AIA_GRP_APLIC 3
258+
259+
/*
260+
* The lower 12-bits of the device attribute type contains the iselect
261+
* value of the IMSIC register (range 0x70-0xFF) whereas the higher order
262+
* bits contains the VCPU id.
263+
*/
264+
#define KVM_DEV_RISCV_AIA_GRP_IMSIC 4
265+
#define KVM_DEV_RISCV_AIA_IMSIC_ISEL_BITS 12
266+
#define KVM_DEV_RISCV_AIA_IMSIC_ISEL_MASK \
267+
((1U << KVM_DEV_RISCV_AIA_IMSIC_ISEL_BITS) - 1)
268+
#define KVM_DEV_RISCV_AIA_IMSIC_MKATTR(__vcpu, __isel) \
269+
(((__vcpu) << KVM_DEV_RISCV_AIA_IMSIC_ISEL_BITS) | \
270+
((__isel) & KVM_DEV_RISCV_AIA_IMSIC_ISEL_MASK))
271+
#define KVM_DEV_RISCV_AIA_IMSIC_GET_ISEL(__attr) \
272+
((__attr) & KVM_DEV_RISCV_AIA_IMSIC_ISEL_MASK)
273+
#define KVM_DEV_RISCV_AIA_IMSIC_GET_VCPU(__attr) \
274+
((__attr) >> KVM_DEV_RISCV_AIA_IMSIC_ISEL_BITS)
275+
276+
/* One single KVM irqchip, ie. the AIA */
277+
#define KVM_NR_IRQCHIPS 1
278+
206279
#endif
207280

208281
#endif /* __LINUX_KVM_RISCV_H */

arch/riscv/kvm/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ config KVM
2121
tristate "Kernel-based Virtual Machine (KVM) support (EXPERIMENTAL)"
2222
depends on RISCV_SBI && MMU
2323
select HAVE_KVM_EVENTFD
24+
select HAVE_KVM_IRQCHIP
25+
select HAVE_KVM_IRQFD
26+
select HAVE_KVM_IRQ_ROUTING
27+
select HAVE_KVM_MSI
2428
select HAVE_KVM_VCPU_ASYNC_IOCTL
2529
select KVM_GENERIC_DIRTYLOG_READ_PROTECT
2630
select KVM_GENERIC_HARDWARE_ENABLING

0 commit comments

Comments
 (0)