Skip to content

Commit 493804a

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull more kvm updates from Paolo Bonzini: "This includes the 6.4 changes for RISC-V, and a few bugfix patches for other architectures. For x86, this closes a longstanding performance issue in the newer and (usually) more scalable page table management code. RISC-V: - ONE_REG interface to enable/disable SBI extensions - Zbb extension for Guest/VM - AIA CSR virtualization x86: - Fix a long-standing TDP MMU flaw, where unloading roots on a vCPU can result in the root being freed even though the root is completely valid and can be reused as-is (with a TLB flush). s390: - A couple of bugfixes" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: s390: fix race in gmap_make_secure() KVM: s390: pv: fix asynchronous teardown for small VMs KVM: x86: Preserve TDP MMU roots until they are explicitly invalidated RISC-V: KVM: Virtualize per-HART AIA CSRs RISC-V: KVM: Use bitmap for irqs_pending and irqs_pending_mask RISC-V: KVM: Add ONE_REG interface for AIA CSRs RISC-V: KVM: Implement subtype for CSR ONE_REG interface RISC-V: KVM: Initial skeletal support for AIA RISC-V: KVM: Drop the _MASK suffix from hgatp.VMID mask defines RISC-V: Detect AIA CSRs from ISA string RISC-V: Add AIA related CSR defines RISC-V: KVM: Allow Zbb extension for Guest/VM RISC-V: KVM: Add ONE_REG interface to enable/disable SBI extensions RISC-V: KVM: Alphabetize selects KVM: RISC-V: Retry fault if vma_lookup() results become invalid
2 parents 7163a21 + 7a8016d commit 493804a

23 files changed

Lines changed: 1208 additions & 177 deletions

File tree

arch/riscv/include/asm/csr.h

Lines changed: 100 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#define _ASM_RISCV_CSR_H
88

99
#include <asm/asm.h>
10-
#include <linux/const.h>
10+
#include <linux/bits.h>
1111

1212
/* Status register flags */
1313
#define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
@@ -72,7 +72,10 @@
7272
#define IRQ_S_EXT 9
7373
#define IRQ_VS_EXT 10
7474
#define IRQ_M_EXT 11
75+
#define IRQ_S_GEXT 12
7576
#define IRQ_PMU_OVF 13
77+
#define IRQ_LOCAL_MAX (IRQ_PMU_OVF + 1)
78+
#define IRQ_LOCAL_MASK GENMASK((IRQ_LOCAL_MAX - 1), 0)
7679

7780
/* Exception causes */
7881
#define EXC_INST_MISALIGNED 0
@@ -127,25 +130,25 @@
127130

128131
#define HGATP32_MODE_SHIFT 31
129132
#define HGATP32_VMID_SHIFT 22
130-
#define HGATP32_VMID_MASK _AC(0x1FC00000, UL)
131-
#define HGATP32_PPN _AC(0x003FFFFF, UL)
133+
#define HGATP32_VMID GENMASK(28, 22)
134+
#define HGATP32_PPN GENMASK(21, 0)
132135

133136
#define HGATP64_MODE_SHIFT 60
134137
#define HGATP64_VMID_SHIFT 44
135-
#define HGATP64_VMID_MASK _AC(0x03FFF00000000000, UL)
136-
#define HGATP64_PPN _AC(0x00000FFFFFFFFFFF, UL)
138+
#define HGATP64_VMID GENMASK(57, 44)
139+
#define HGATP64_PPN GENMASK(43, 0)
137140

138141
#define HGATP_PAGE_SHIFT 12
139142

140143
#ifdef CONFIG_64BIT
141144
#define HGATP_PPN HGATP64_PPN
142145
#define HGATP_VMID_SHIFT HGATP64_VMID_SHIFT
143-
#define HGATP_VMID_MASK HGATP64_VMID_MASK
146+
#define HGATP_VMID HGATP64_VMID
144147
#define HGATP_MODE_SHIFT HGATP64_MODE_SHIFT
145148
#else
146149
#define HGATP_PPN HGATP32_PPN
147150
#define HGATP_VMID_SHIFT HGATP32_VMID_SHIFT
148-
#define HGATP_VMID_MASK HGATP32_VMID_MASK
151+
#define HGATP_VMID HGATP32_VMID
149152
#define HGATP_MODE_SHIFT HGATP32_MODE_SHIFT
150153
#endif
151154

@@ -155,6 +158,27 @@
155158
(_AC(1, UL) << IRQ_S_TIMER) | \
156159
(_AC(1, UL) << IRQ_S_EXT))
157160

161+
/* AIA CSR bits */
162+
#define TOPI_IID_SHIFT 16
163+
#define TOPI_IID_MASK GENMASK(11, 0)
164+
#define TOPI_IPRIO_MASK GENMASK(7, 0)
165+
#define TOPI_IPRIO_BITS 8
166+
167+
#define TOPEI_ID_SHIFT 16
168+
#define TOPEI_ID_MASK GENMASK(10, 0)
169+
#define TOPEI_PRIO_MASK GENMASK(10, 0)
170+
171+
#define ISELECT_IPRIO0 0x30
172+
#define ISELECT_IPRIO15 0x3f
173+
#define ISELECT_MASK GENMASK(8, 0)
174+
175+
#define HVICTL_VTI BIT(30)
176+
#define HVICTL_IID GENMASK(27, 16)
177+
#define HVICTL_IID_SHIFT 16
178+
#define HVICTL_DPR BIT(9)
179+
#define HVICTL_IPRIOM BIT(8)
180+
#define HVICTL_IPRIO GENMASK(7, 0)
181+
158182
/* xENVCFG flags */
159183
#define ENVCFG_STCE (_AC(1, ULL) << 63)
160184
#define ENVCFG_PBMTE (_AC(1, ULL) << 62)
@@ -249,6 +273,18 @@
249273
#define CSR_STIMECMP 0x14D
250274
#define CSR_STIMECMPH 0x15D
251275

276+
/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
277+
#define CSR_SISELECT 0x150
278+
#define CSR_SIREG 0x151
279+
280+
/* Supervisor-Level Interrupts (AIA) */
281+
#define CSR_STOPEI 0x15c
282+
#define CSR_STOPI 0xdb0
283+
284+
/* Supervisor-Level High-Half CSRs (AIA) */
285+
#define CSR_SIEH 0x114
286+
#define CSR_SIPH 0x154
287+
252288
#define CSR_VSSTATUS 0x200
253289
#define CSR_VSIE 0x204
254290
#define CSR_VSTVEC 0x205
@@ -278,8 +314,32 @@
278314
#define CSR_HGATP 0x680
279315
#define CSR_HGEIP 0xe12
280316

317+
/* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
318+
#define CSR_HVIEN 0x608
319+
#define CSR_HVICTL 0x609
320+
#define CSR_HVIPRIO1 0x646
321+
#define CSR_HVIPRIO2 0x647
322+
323+
/* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA) */
324+
#define CSR_VSISELECT 0x250
325+
#define CSR_VSIREG 0x251
326+
327+
/* VS-Level Interrupts (H-extension with AIA) */
328+
#define CSR_VSTOPEI 0x25c
329+
#define CSR_VSTOPI 0xeb0
330+
331+
/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
332+
#define CSR_HIDELEGH 0x613
333+
#define CSR_HVIENH 0x618
334+
#define CSR_HVIPH 0x655
335+
#define CSR_HVIPRIO1H 0x656
336+
#define CSR_HVIPRIO2H 0x657
337+
#define CSR_VSIEH 0x214
338+
#define CSR_VSIPH 0x254
339+
281340
#define CSR_MSTATUS 0x300
282341
#define CSR_MISA 0x301
342+
#define CSR_MIDELEG 0x303
283343
#define CSR_MIE 0x304
284344
#define CSR_MTVEC 0x305
285345
#define CSR_MENVCFG 0x30a
@@ -296,6 +356,25 @@
296356
#define CSR_MIMPID 0xf13
297357
#define CSR_MHARTID 0xf14
298358

359+
/* Machine-Level Window to Indirectly Accessed Registers (AIA) */
360+
#define CSR_MISELECT 0x350
361+
#define CSR_MIREG 0x351
362+
363+
/* Machine-Level Interrupts (AIA) */
364+
#define CSR_MTOPEI 0x35c
365+
#define CSR_MTOPI 0xfb0
366+
367+
/* Virtual Interrupts for Supervisor Level (AIA) */
368+
#define CSR_MVIEN 0x308
369+
#define CSR_MVIP 0x309
370+
371+
/* Machine-Level High-Half CSRs (AIA) */
372+
#define CSR_MIDELEGH 0x313
373+
#define CSR_MIEH 0x314
374+
#define CSR_MVIENH 0x318
375+
#define CSR_MVIPH 0x319
376+
#define CSR_MIPH 0x354
377+
299378
#ifdef CONFIG_RISCV_M_MODE
300379
# define CSR_STATUS CSR_MSTATUS
301380
# define CSR_IE CSR_MIE
@@ -306,6 +385,13 @@
306385
# define CSR_TVAL CSR_MTVAL
307386
# define CSR_IP CSR_MIP
308387

388+
# define CSR_IEH CSR_MIEH
389+
# define CSR_ISELECT CSR_MISELECT
390+
# define CSR_IREG CSR_MIREG
391+
# define CSR_IPH CSR_MIPH
392+
# define CSR_TOPEI CSR_MTOPEI
393+
# define CSR_TOPI CSR_MTOPI
394+
309395
# define SR_IE SR_MIE
310396
# define SR_PIE SR_MPIE
311397
# define SR_PP SR_MPP
@@ -323,6 +409,13 @@
323409
# define CSR_TVAL CSR_STVAL
324410
# define CSR_IP CSR_SIP
325411

412+
# define CSR_IEH CSR_SIEH
413+
# define CSR_ISELECT CSR_SISELECT
414+
# define CSR_IREG CSR_SIREG
415+
# define CSR_IPH CSR_SIPH
416+
# define CSR_TOPEI CSR_STOPEI
417+
# define CSR_TOPI CSR_STOPI
418+
326419
# define SR_IE SR_SIE
327420
# define SR_PIE SR_SPIE
328421
# define SR_PP SR_SPP

arch/riscv/include/asm/hwcap.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,18 @@
4444
#define RISCV_ISA_EXT_ZIHINTPAUSE 32
4545
#define RISCV_ISA_EXT_SVNAPOT 33
4646
#define RISCV_ISA_EXT_ZICBOZ 34
47+
#define RISCV_ISA_EXT_SMAIA 35
48+
#define RISCV_ISA_EXT_SSAIA 36
4749

4850
#define RISCV_ISA_EXT_MAX 64
4951
#define RISCV_ISA_EXT_NAME_LEN_MAX 32
5052

53+
#ifdef CONFIG_RISCV_M_MODE
54+
#define RISCV_ISA_EXT_SxAIA RISCV_ISA_EXT_SMAIA
55+
#else
56+
#define RISCV_ISA_EXT_SxAIA RISCV_ISA_EXT_SSAIA
57+
#endif
58+
5159
#ifndef __ASSEMBLY__
5260

5361
#include <linux/jump_label.h>

arch/riscv/include/asm/kvm_aia.h

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
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+
* Authors:
7+
* Anup Patel <apatel@ventanamicro.com>
8+
*/
9+
10+
#ifndef __KVM_RISCV_AIA_H
11+
#define __KVM_RISCV_AIA_H
12+
13+
#include <linux/jump_label.h>
14+
#include <linux/kvm_types.h>
15+
#include <asm/csr.h>
16+
17+
struct kvm_aia {
18+
/* In-kernel irqchip created */
19+
bool in_kernel;
20+
21+
/* In-kernel irqchip initialized */
22+
bool initialized;
23+
};
24+
25+
struct kvm_vcpu_aia_csr {
26+
unsigned long vsiselect;
27+
unsigned long hviprio1;
28+
unsigned long hviprio2;
29+
unsigned long vsieh;
30+
unsigned long hviph;
31+
unsigned long hviprio1h;
32+
unsigned long hviprio2h;
33+
};
34+
35+
struct kvm_vcpu_aia {
36+
/* CPU AIA CSR context of Guest VCPU */
37+
struct kvm_vcpu_aia_csr guest_csr;
38+
39+
/* CPU AIA CSR context upon Guest VCPU reset */
40+
struct kvm_vcpu_aia_csr guest_reset_csr;
41+
};
42+
43+
#define kvm_riscv_aia_initialized(k) ((k)->arch.aia.initialized)
44+
45+
#define irqchip_in_kernel(k) ((k)->arch.aia.in_kernel)
46+
47+
DECLARE_STATIC_KEY_FALSE(kvm_riscv_aia_available);
48+
#define kvm_riscv_aia_available() \
49+
static_branch_unlikely(&kvm_riscv_aia_available)
50+
51+
#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+
}
60+
61+
#ifdef CONFIG_32BIT
62+
void kvm_riscv_vcpu_aia_flush_interrupts(struct kvm_vcpu *vcpu);
63+
void kvm_riscv_vcpu_aia_sync_interrupts(struct kvm_vcpu *vcpu);
64+
#else
65+
static inline void kvm_riscv_vcpu_aia_flush_interrupts(struct kvm_vcpu *vcpu)
66+
{
67+
}
68+
static inline void kvm_riscv_vcpu_aia_sync_interrupts(struct kvm_vcpu *vcpu)
69+
{
70+
}
71+
#endif
72+
bool kvm_riscv_vcpu_aia_has_interrupts(struct kvm_vcpu *vcpu, u64 mask);
73+
74+
void kvm_riscv_vcpu_aia_update_hvip(struct kvm_vcpu *vcpu);
75+
void kvm_riscv_vcpu_aia_load(struct kvm_vcpu *vcpu, int cpu);
76+
void kvm_riscv_vcpu_aia_put(struct kvm_vcpu *vcpu);
77+
int kvm_riscv_vcpu_aia_get_csr(struct kvm_vcpu *vcpu,
78+
unsigned long reg_num,
79+
unsigned long *out_val);
80+
int kvm_riscv_vcpu_aia_set_csr(struct kvm_vcpu *vcpu,
81+
unsigned long reg_num,
82+
unsigned long val);
83+
84+
int kvm_riscv_vcpu_aia_rmw_topei(struct kvm_vcpu *vcpu,
85+
unsigned int csr_num,
86+
unsigned long *val,
87+
unsigned long new_val,
88+
unsigned long wr_mask);
89+
int kvm_riscv_vcpu_aia_rmw_ireg(struct kvm_vcpu *vcpu, unsigned int csr_num,
90+
unsigned long *val, unsigned long new_val,
91+
unsigned long wr_mask);
92+
#define KVM_RISCV_VCPU_AIA_CSR_FUNCS \
93+
{ .base = CSR_SIREG, .count = 1, .func = kvm_riscv_vcpu_aia_rmw_ireg }, \
94+
{ .base = CSR_STOPEI, .count = 1, .func = kvm_riscv_vcpu_aia_rmw_topei },
95+
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+
}
109+
110+
static inline void kvm_riscv_vcpu_aia_deinit(struct kvm_vcpu *vcpu)
111+
{
112+
}
113+
114+
static inline void kvm_riscv_aia_init_vm(struct kvm *kvm)
115+
{
116+
}
117+
118+
static inline void kvm_riscv_aia_destroy_vm(struct kvm *kvm)
119+
{
120+
}
121+
122+
void kvm_riscv_aia_enable(void);
123+
void kvm_riscv_aia_disable(void);
124+
int kvm_riscv_aia_init(void);
125+
void kvm_riscv_aia_exit(void);
126+
127+
#endif

arch/riscv/include/asm/kvm_host.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/kvm_types.h>
1515
#include <linux/spinlock.h>
1616
#include <asm/hwcap.h>
17+
#include <asm/kvm_aia.h>
1718
#include <asm/kvm_vcpu_fp.h>
1819
#include <asm/kvm_vcpu_insn.h>
1920
#include <asm/kvm_vcpu_sbi.h>
@@ -94,6 +95,9 @@ struct kvm_arch {
9495

9596
/* Guest Timer */
9697
struct kvm_guest_timer timer;
98+
99+
/* AIA Guest/VM context */
100+
struct kvm_aia aia;
97101
};
98102

99103
struct kvm_cpu_trap {
@@ -200,8 +204,9 @@ struct kvm_vcpu_arch {
200204
* in irqs_pending. Our approach is modeled around multiple producer
201205
* and single consumer problem where the consumer is the VCPU itself.
202206
*/
203-
unsigned long irqs_pending;
204-
unsigned long irqs_pending_mask;
207+
#define KVM_RISCV_VCPU_NR_IRQS 64
208+
DECLARE_BITMAP(irqs_pending, KVM_RISCV_VCPU_NR_IRQS);
209+
DECLARE_BITMAP(irqs_pending_mask, KVM_RISCV_VCPU_NR_IRQS);
205210

206211
/* VCPU Timer */
207212
struct kvm_vcpu_timer timer;
@@ -221,6 +226,9 @@ struct kvm_vcpu_arch {
221226
/* SBI context */
222227
struct kvm_vcpu_sbi_context sbi_context;
223228

229+
/* AIA VCPU context */
230+
struct kvm_vcpu_aia aia_context;
231+
224232
/* Cache pages needed to program page tables with spinlock held */
225233
struct kvm_mmu_memory_cache mmu_page_cache;
226234

@@ -327,7 +335,7 @@ int kvm_riscv_vcpu_set_interrupt(struct kvm_vcpu *vcpu, unsigned int irq);
327335
int kvm_riscv_vcpu_unset_interrupt(struct kvm_vcpu *vcpu, unsigned int irq);
328336
void kvm_riscv_vcpu_flush_interrupts(struct kvm_vcpu *vcpu);
329337
void kvm_riscv_vcpu_sync_interrupts(struct kvm_vcpu *vcpu);
330-
bool kvm_riscv_vcpu_has_interrupts(struct kvm_vcpu *vcpu, unsigned long mask);
338+
bool kvm_riscv_vcpu_has_interrupts(struct kvm_vcpu *vcpu, u64 mask);
331339
void kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu);
332340
void kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu);
333341

0 commit comments

Comments
 (0)