Skip to content

Commit aa24865

Browse files
committed
Merge tag 'kvm-riscv-6.10-1' of https://github.com/kvm-riscv/linux into HEAD
KVM/riscv changes for 6.10 - Support guest breakpoints using ebreak - Introduce per-VCPU mp_state_lock and reset_cntx_lock - Virtualize SBI PMU snapshot and counter overflow interrupts - New selftests for SBI PMU and Guest ebreak
2 parents a96cb3b + 5ef2f3d commit aa24865

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+2186
-403
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
VERSION = 6
33
PATCHLEVEL = 9
44
SUBLEVEL = 0
5-
EXTRAVERSION = -rc2
5+
EXTRAVERSION = -rc3
66
NAME = Hurr durr I'ma ninja sloth
77

88
# *DOCUMENTATION*

arch/powerpc/include/asm/vdso/gettimeofday.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
#ifndef __ASSEMBLY__
66

7-
#include <asm/page.h>
87
#include <asm/vdso/timebase.h>
98
#include <asm/barrier.h>
109
#include <asm/unistd.h>
@@ -95,7 +94,7 @@ const struct vdso_data *__arch_get_vdso_data(void);
9594
static __always_inline
9695
const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
9796
{
98-
return (void *)vd + PAGE_SIZE;
97+
return (void *)vd + (1U << CONFIG_PAGE_SHIFT);
9998
}
10099
#endif
101100

arch/riscv/include/asm/csr.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@
168168
#define VSIP_TO_HVIP_SHIFT (IRQ_VS_SOFT - IRQ_S_SOFT)
169169
#define VSIP_VALID_MASK ((_AC(1, UL) << IRQ_S_SOFT) | \
170170
(_AC(1, UL) << IRQ_S_TIMER) | \
171-
(_AC(1, UL) << IRQ_S_EXT))
171+
(_AC(1, UL) << IRQ_S_EXT) | \
172+
(_AC(1, UL) << IRQ_PMU_OVF))
172173

173174
/* AIA CSR bits */
174175
#define TOPI_IID_SHIFT 16
@@ -281,7 +282,7 @@
281282
#define CSR_HPMCOUNTER30H 0xc9e
282283
#define CSR_HPMCOUNTER31H 0xc9f
283284

284-
#define CSR_SSCOUNTOVF 0xda0
285+
#define CSR_SCOUNTOVF 0xda0
285286

286287
#define CSR_SSTATUS 0x100
287288
#define CSR_SIE 0x104

arch/riscv/include/asm/kvm_host.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@
4343
KVM_ARCH_REQ_FLAGS(5, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
4444
#define KVM_REQ_STEAL_UPDATE KVM_ARCH_REQ(6)
4545

46+
#define KVM_HEDELEG_DEFAULT (BIT(EXC_INST_MISALIGNED) | \
47+
BIT(EXC_BREAKPOINT) | \
48+
BIT(EXC_SYSCALL) | \
49+
BIT(EXC_INST_PAGE_FAULT) | \
50+
BIT(EXC_LOAD_PAGE_FAULT) | \
51+
BIT(EXC_STORE_PAGE_FAULT))
52+
53+
#define KVM_HIDELEG_DEFAULT (BIT(IRQ_VS_SOFT) | \
54+
BIT(IRQ_VS_TIMER) | \
55+
BIT(IRQ_VS_EXT))
56+
4657
enum kvm_riscv_hfence_type {
4758
KVM_RISCV_HFENCE_UNKNOWN = 0,
4859
KVM_RISCV_HFENCE_GVMA_VMID_GPA,
@@ -169,6 +180,7 @@ struct kvm_vcpu_csr {
169180
struct kvm_vcpu_config {
170181
u64 henvcfg;
171182
u64 hstateen0;
183+
unsigned long hedeleg;
172184
};
173185

174186
struct kvm_vcpu_smstateen_csr {
@@ -211,6 +223,7 @@ struct kvm_vcpu_arch {
211223

212224
/* CPU context upon Guest VCPU reset */
213225
struct kvm_cpu_context guest_reset_context;
226+
spinlock_t reset_cntx_lock;
214227

215228
/* CPU CSR context upon Guest VCPU reset */
216229
struct kvm_vcpu_csr guest_reset_csr;
@@ -252,8 +265,9 @@ struct kvm_vcpu_arch {
252265
/* Cache pages needed to program page tables with spinlock held */
253266
struct kvm_mmu_memory_cache mmu_page_cache;
254267

255-
/* VCPU power-off state */
256-
bool power_off;
268+
/* VCPU power state */
269+
struct kvm_mp_state mp_state;
270+
spinlock_t mp_state_lock;
257271

258272
/* Don't run the VCPU (blocked) */
259273
bool pause;
@@ -374,8 +388,11 @@ int kvm_riscv_vcpu_unset_interrupt(struct kvm_vcpu *vcpu, unsigned int irq);
374388
void kvm_riscv_vcpu_flush_interrupts(struct kvm_vcpu *vcpu);
375389
void kvm_riscv_vcpu_sync_interrupts(struct kvm_vcpu *vcpu);
376390
bool kvm_riscv_vcpu_has_interrupts(struct kvm_vcpu *vcpu, u64 mask);
391+
void __kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu);
377392
void kvm_riscv_vcpu_power_off(struct kvm_vcpu *vcpu);
393+
void __kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu);
378394
void kvm_riscv_vcpu_power_on(struct kvm_vcpu *vcpu);
395+
bool kvm_riscv_vcpu_stopped(struct kvm_vcpu *vcpu);
379396

380397
void kvm_riscv_vcpu_sbi_sta_reset(struct kvm_vcpu *vcpu);
381398
void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu);

arch/riscv/include/asm/kvm_vcpu_pmu.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ static_assert(RISCV_KVM_MAX_COUNTERS <= 64);
2020

2121
struct kvm_fw_event {
2222
/* Current value of the event */
23-
unsigned long value;
23+
u64 value;
2424

2525
/* Event monitoring status */
2626
bool started;
@@ -36,6 +36,7 @@ struct kvm_pmc {
3636
bool started;
3737
/* Monitoring event ID */
3838
unsigned long event_idx;
39+
struct kvm_vcpu *vcpu;
3940
};
4041

4142
/* PMU data structure per vcpu */
@@ -50,6 +51,12 @@ struct kvm_pmu {
5051
bool init_done;
5152
/* Bit map of all the virtual counter used */
5253
DECLARE_BITMAP(pmc_in_use, RISCV_KVM_MAX_COUNTERS);
54+
/* Bit map of all the virtual counter overflown */
55+
DECLARE_BITMAP(pmc_overflown, RISCV_KVM_MAX_COUNTERS);
56+
/* The address of the counter snapshot area (guest physical address) */
57+
gpa_t snapshot_addr;
58+
/* The actual data of the snapshot */
59+
struct riscv_pmu_snapshot_data *sdata;
5360
};
5461

5562
#define vcpu_to_pmu(vcpu) (&(vcpu)->arch.pmu_context)
@@ -82,9 +89,14 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *vcpu, unsigned long ctr_ba
8289
unsigned long ctr_mask, unsigned long flags,
8390
unsigned long eidx, u64 evtdata,
8491
struct kvm_vcpu_sbi_return *retdata);
85-
int kvm_riscv_vcpu_pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
92+
int kvm_riscv_vcpu_pmu_fw_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
8693
struct kvm_vcpu_sbi_return *retdata);
94+
int kvm_riscv_vcpu_pmu_fw_ctr_read_hi(struct kvm_vcpu *vcpu, unsigned long cidx,
95+
struct kvm_vcpu_sbi_return *retdata);
8796
void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu);
97+
int kvm_riscv_vcpu_pmu_snapshot_set_shmem(struct kvm_vcpu *vcpu, unsigned long saddr_low,
98+
unsigned long saddr_high, unsigned long flags,
99+
struct kvm_vcpu_sbi_return *retdata);
88100
void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu);
89101
void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu);
90102

arch/riscv/include/asm/sbi.h

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ enum sbi_ext_pmu_fid {
131131
SBI_EXT_PMU_COUNTER_START,
132132
SBI_EXT_PMU_COUNTER_STOP,
133133
SBI_EXT_PMU_COUNTER_FW_READ,
134+
SBI_EXT_PMU_COUNTER_FW_READ_HI,
135+
SBI_EXT_PMU_SNAPSHOT_SET_SHMEM,
134136
};
135137

136138
union sbi_pmu_ctr_info {
@@ -147,6 +149,13 @@ union sbi_pmu_ctr_info {
147149
};
148150
};
149151

152+
/* Data structure to contain the pmu snapshot data */
153+
struct riscv_pmu_snapshot_data {
154+
u64 ctr_overflow_mask;
155+
u64 ctr_values[64];
156+
u64 reserved[447];
157+
};
158+
150159
#define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
151160
#define RISCV_PMU_RAW_EVENT_IDX 0x20000
152161

@@ -232,20 +241,22 @@ enum sbi_pmu_ctr_type {
232241
#define SBI_PMU_EVENT_IDX_INVALID 0xFFFFFFFF
233242

234243
/* Flags defined for config matching function */
235-
#define SBI_PMU_CFG_FLAG_SKIP_MATCH (1 << 0)
236-
#define SBI_PMU_CFG_FLAG_CLEAR_VALUE (1 << 1)
237-
#define SBI_PMU_CFG_FLAG_AUTO_START (1 << 2)
238-
#define SBI_PMU_CFG_FLAG_SET_VUINH (1 << 3)
239-
#define SBI_PMU_CFG_FLAG_SET_VSINH (1 << 4)
240-
#define SBI_PMU_CFG_FLAG_SET_UINH (1 << 5)
241-
#define SBI_PMU_CFG_FLAG_SET_SINH (1 << 6)
242-
#define SBI_PMU_CFG_FLAG_SET_MINH (1 << 7)
244+
#define SBI_PMU_CFG_FLAG_SKIP_MATCH BIT(0)
245+
#define SBI_PMU_CFG_FLAG_CLEAR_VALUE BIT(1)
246+
#define SBI_PMU_CFG_FLAG_AUTO_START BIT(2)
247+
#define SBI_PMU_CFG_FLAG_SET_VUINH BIT(3)
248+
#define SBI_PMU_CFG_FLAG_SET_VSINH BIT(4)
249+
#define SBI_PMU_CFG_FLAG_SET_UINH BIT(5)
250+
#define SBI_PMU_CFG_FLAG_SET_SINH BIT(6)
251+
#define SBI_PMU_CFG_FLAG_SET_MINH BIT(7)
243252

244253
/* Flags defined for counter start function */
245-
#define SBI_PMU_START_FLAG_SET_INIT_VALUE (1 << 0)
254+
#define SBI_PMU_START_FLAG_SET_INIT_VALUE BIT(0)
255+
#define SBI_PMU_START_FLAG_INIT_SNAPSHOT BIT(1)
246256

247257
/* Flags defined for counter stop function */
248-
#define SBI_PMU_STOP_FLAG_RESET (1 << 0)
258+
#define SBI_PMU_STOP_FLAG_RESET BIT(0)
259+
#define SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT BIT(1)
249260

250261
enum sbi_ext_dbcn_fid {
251262
SBI_EXT_DBCN_CONSOLE_WRITE = 0,
@@ -266,7 +277,7 @@ struct sbi_sta_struct {
266277
u8 pad[47];
267278
} __packed;
268279

269-
#define SBI_STA_SHMEM_DISABLE -1
280+
#define SBI_SHMEM_DISABLE -1
270281

271282
/* SBI spec version fields */
272283
#define SBI_SPEC_VERSION_DEFAULT 0x1
@@ -284,6 +295,7 @@ struct sbi_sta_struct {
284295
#define SBI_ERR_ALREADY_AVAILABLE -6
285296
#define SBI_ERR_ALREADY_STARTED -7
286297
#define SBI_ERR_ALREADY_STOPPED -8
298+
#define SBI_ERR_NO_SHMEM -9
287299

288300
extern unsigned long sbi_spec_version;
289301
struct sbiret {
@@ -355,8 +367,8 @@ static inline unsigned long sbi_minor_version(void)
355367
static inline unsigned long sbi_mk_version(unsigned long major,
356368
unsigned long minor)
357369
{
358-
return ((major & SBI_SPEC_VERSION_MAJOR_MASK) <<
359-
SBI_SPEC_VERSION_MAJOR_SHIFT) | minor;
370+
return ((major & SBI_SPEC_VERSION_MAJOR_MASK) << SBI_SPEC_VERSION_MAJOR_SHIFT)
371+
| (minor & SBI_SPEC_VERSION_MINOR_MASK);
360372
}
361373

362374
int sbi_err_map_linux_errno(int err);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ enum KVM_RISCV_ISA_EXT_ID {
167167
KVM_RISCV_ISA_EXT_ZFA,
168168
KVM_RISCV_ISA_EXT_ZTSO,
169169
KVM_RISCV_ISA_EXT_ZACAS,
170+
KVM_RISCV_ISA_EXT_SSCOFPMF,
170171
KVM_RISCV_ISA_EXT_MAX,
171172
};
172173

arch/riscv/kernel/paravirt.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static int sbi_sta_steal_time_set_shmem(unsigned long lo, unsigned long hi,
6262
ret = sbi_ecall(SBI_EXT_STA, SBI_EXT_STA_STEAL_TIME_SET_SHMEM,
6363
lo, hi, flags, 0, 0, 0);
6464
if (ret.error) {
65-
if (lo == SBI_STA_SHMEM_DISABLE && hi == SBI_STA_SHMEM_DISABLE)
65+
if (lo == SBI_SHMEM_DISABLE && hi == SBI_SHMEM_DISABLE)
6666
pr_warn("Failed to disable steal-time shmem");
6767
else
6868
pr_warn("Failed to set steal-time shmem");
@@ -84,8 +84,8 @@ static int pv_time_cpu_online(unsigned int cpu)
8484

8585
static int pv_time_cpu_down_prepare(unsigned int cpu)
8686
{
87-
return sbi_sta_steal_time_set_shmem(SBI_STA_SHMEM_DISABLE,
88-
SBI_STA_SHMEM_DISABLE, 0);
87+
return sbi_sta_steal_time_set_shmem(SBI_SHMEM_DISABLE,
88+
SBI_SHMEM_DISABLE, 0);
8989
}
9090

9191
static u64 pv_time_steal_clock(int cpu)

arch/riscv/kvm/aia.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,9 @@ void kvm_riscv_aia_enable(void)
545545
enable_percpu_irq(hgei_parent_irq,
546546
irq_get_trigger_type(hgei_parent_irq));
547547
csr_set(CSR_HIE, BIT(IRQ_S_GEXT));
548+
/* Enable IRQ filtering for overflow interrupt only if sscofpmf is present */
549+
if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSCOFPMF))
550+
csr_write(CSR_HVIEN, BIT(IRQ_PMU_OVF));
548551
}
549552

550553
void kvm_riscv_aia_disable(void)
@@ -558,6 +561,8 @@ void kvm_riscv_aia_disable(void)
558561
return;
559562
hgctrl = get_cpu_ptr(&aia_hgei);
560563

564+
if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_SSCOFPMF))
565+
csr_clear(CSR_HVIEN, BIT(IRQ_PMU_OVF));
561566
/* Disable per-CPU SGEI interrupt */
562567
csr_clear(CSR_HIE, BIT(IRQ_S_GEXT));
563568
disable_percpu_irq(hgei_parent_irq);

arch/riscv/kvm/main.c

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,8 @@ long kvm_arch_dev_ioctl(struct file *filp,
2222

2323
int kvm_arch_hardware_enable(void)
2424
{
25-
unsigned long hideleg, hedeleg;
26-
27-
hedeleg = 0;
28-
hedeleg |= (1UL << EXC_INST_MISALIGNED);
29-
hedeleg |= (1UL << EXC_BREAKPOINT);
30-
hedeleg |= (1UL << EXC_SYSCALL);
31-
hedeleg |= (1UL << EXC_INST_PAGE_FAULT);
32-
hedeleg |= (1UL << EXC_LOAD_PAGE_FAULT);
33-
hedeleg |= (1UL << EXC_STORE_PAGE_FAULT);
34-
csr_write(CSR_HEDELEG, hedeleg);
35-
36-
hideleg = 0;
37-
hideleg |= (1UL << IRQ_VS_SOFT);
38-
hideleg |= (1UL << IRQ_VS_TIMER);
39-
hideleg |= (1UL << IRQ_VS_EXT);
40-
csr_write(CSR_HIDELEG, hideleg);
25+
csr_write(CSR_HEDELEG, KVM_HEDELEG_DEFAULT);
26+
csr_write(CSR_HIDELEG, KVM_HIDELEG_DEFAULT);
4127

4228
/* VS should access only the time counter directly. Everything else should trap */
4329
csr_write(CSR_HCOUNTEREN, 0x02);

0 commit comments

Comments
 (0)