Commit 2e2e9115 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvm-riscv-5.20-1' of https://github.com/kvm-riscv/linux into HEAD

KVM/riscv changes for 5.20

* Track ISA extensions used by Guest using bitmap

* Added system instruction emulation framework

* Added CSR emulation framework

* Added gfp_custom flag in struct kvm_mmu_memory_cache

* Added G-stage ioremap() and iounmap() functions

* Added support for Svpbmt inside Guest
parents e0dccc3b 6bb2e00e
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -156,6 +156,18 @@
				 (_AC(1, UL) << IRQ_S_TIMER) | \
				 (_AC(1, UL) << IRQ_S_EXT))

/* xENVCFG flags */
#define ENVCFG_STCE			(_AC(1, ULL) << 63)
#define ENVCFG_PBMTE			(_AC(1, ULL) << 62)
#define ENVCFG_CBZE			(_AC(1, UL) << 7)
#define ENVCFG_CBCFE			(_AC(1, UL) << 6)
#define ENVCFG_CBIE_SHIFT		4
#define ENVCFG_CBIE			(_AC(0x3, UL) << ENVCFG_CBIE_SHIFT)
#define ENVCFG_CBIE_ILL			_AC(0x0, UL)
#define ENVCFG_CBIE_FLUSH		_AC(0x1, UL)
#define ENVCFG_CBIE_INV			_AC(0x3, UL)
#define ENVCFG_FIOM			_AC(0x1, UL)

/* symbolic CSR names: */
#define CSR_CYCLE		0xc00
#define CSR_TIME		0xc01
@@ -252,7 +264,9 @@
#define CSR_HTIMEDELTA		0x605
#define CSR_HCOUNTEREN		0x606
#define CSR_HGEIE		0x607
#define CSR_HENVCFG		0x60a
#define CSR_HTIMEDELTAH		0x615
#define CSR_HENVCFGH		0x61a
#define CSR_HTVAL		0x643
#define CSR_HIP			0x644
#define CSR_HVIP		0x645
@@ -264,6 +278,8 @@
#define CSR_MISA		0x301
#define CSR_MIE			0x304
#define CSR_MTVEC		0x305
#define CSR_MENVCFG		0x30a
#define CSR_MENVCFGH		0x31a
#define CSR_MSCRATCH		0x340
#define CSR_MEPC		0x341
#define CSR_MCAUSE		0x342
+13 −11
Original line number Diff line number Diff line
@@ -14,7 +14,9 @@
#include <linux/kvm_types.h>
#include <linux/spinlock.h>
#include <asm/csr.h>
#include <asm/hwcap.h>
#include <asm/kvm_vcpu_fp.h>
#include <asm/kvm_vcpu_insn.h>
#include <asm/kvm_vcpu_timer.h>

#define KVM_MAX_VCPUS			1024
@@ -63,6 +65,8 @@ struct kvm_vcpu_stat {
	u64 wfi_exit_stat;
	u64 mmio_exit_user;
	u64 mmio_exit_kernel;
	u64 csr_exit_user;
	u64 csr_exit_kernel;
	u64 exits;
};

@@ -90,14 +94,6 @@ struct kvm_arch {
	struct kvm_guest_timer timer;
};

struct kvm_mmio_decode {
	unsigned long insn;
	int insn_len;
	int len;
	int shift;
	int return_handled;
};

struct kvm_sbi_context {
	int return_handled;
};
@@ -170,7 +166,7 @@ struct kvm_vcpu_arch {
	int last_exit_cpu;

	/* ISA feature bits (similar to MISA) */
	unsigned long isa;
	DECLARE_BITMAP(isa, RISCV_ISA_EXT_MAX);

	/* SSCRATCH, STVEC, and SCOUNTEREN of Host */
	unsigned long host_sscratch;
@@ -216,6 +212,9 @@ struct kvm_vcpu_arch {
	/* MMIO instruction details */
	struct kvm_mmio_decode mmio_decode;

	/* CSR instruction details */
	struct kvm_csr_decode csr_decode;

	/* SBI context */
	struct kvm_sbi_context sbi_context;

@@ -285,6 +284,11 @@ void kvm_riscv_hfence_vvma_gva(struct kvm *kvm,
void kvm_riscv_hfence_vvma_all(struct kvm *kvm,
			       unsigned long hbase, unsigned long hmask);

int kvm_riscv_gstage_ioremap(struct kvm *kvm, gpa_t gpa,
			     phys_addr_t hpa, unsigned long size,
			     bool writable, bool in_atomic);
void kvm_riscv_gstage_iounmap(struct kvm *kvm, gpa_t gpa,
			      unsigned long size);
int kvm_riscv_gstage_map(struct kvm_vcpu *vcpu,
			 struct kvm_memory_slot *memslot,
			 gpa_t gpa, unsigned long hva, bool is_write);
@@ -303,14 +307,12 @@ void kvm_riscv_gstage_vmid_update(struct kvm_vcpu *vcpu);

void __kvm_riscv_unpriv_trap(void);

void kvm_riscv_vcpu_wfi(struct kvm_vcpu *vcpu);
unsigned long kvm_riscv_vcpu_unpriv_read(struct kvm_vcpu *vcpu,
					 bool read_insn,
					 unsigned long guest_addr,
					 struct kvm_cpu_trap *trap);
void kvm_riscv_vcpu_trap_redirect(struct kvm_vcpu *vcpu,
				  struct kvm_cpu_trap *trap);
int kvm_riscv_vcpu_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
int kvm_riscv_vcpu_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
			struct kvm_cpu_trap *trap);

+4 −4
Original line number Diff line number Diff line
@@ -22,9 +22,9 @@ void __kvm_riscv_fp_d_restore(struct kvm_cpu_context *context);

void kvm_riscv_vcpu_fp_reset(struct kvm_vcpu *vcpu);
void kvm_riscv_vcpu_guest_fp_save(struct kvm_cpu_context *cntx,
				  unsigned long isa);
				  const unsigned long *isa);
void kvm_riscv_vcpu_guest_fp_restore(struct kvm_cpu_context *cntx,
				     unsigned long isa);
				     const unsigned long *isa);
void kvm_riscv_vcpu_host_fp_save(struct kvm_cpu_context *cntx);
void kvm_riscv_vcpu_host_fp_restore(struct kvm_cpu_context *cntx);
#else
@@ -32,12 +32,12 @@ static inline void kvm_riscv_vcpu_fp_reset(struct kvm_vcpu *vcpu)
{
}
static inline void kvm_riscv_vcpu_guest_fp_save(struct kvm_cpu_context *cntx,
						unsigned long isa)
						const unsigned long *isa)
{
}
static inline void kvm_riscv_vcpu_guest_fp_restore(
					struct kvm_cpu_context *cntx,
					unsigned long isa)
					const unsigned long *isa)
{
}
static inline void kvm_riscv_vcpu_host_fp_save(struct kvm_cpu_context *cntx)
+48 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2022 Ventana Micro Systems Inc.
 */

#ifndef __KVM_VCPU_RISCV_INSN_H
#define __KVM_VCPU_RISCV_INSN_H

struct kvm_vcpu;
struct kvm_run;
struct kvm_cpu_trap;

struct kvm_mmio_decode {
	unsigned long insn;
	int insn_len;
	int len;
	int shift;
	int return_handled;
};

struct kvm_csr_decode {
	unsigned long insn;
	int return_handled;
};

/* Return values used by function emulating a particular instruction */
enum kvm_insn_return {
	KVM_INSN_EXIT_TO_USER_SPACE = 0,
	KVM_INSN_CONTINUE_NEXT_SEPC,
	KVM_INSN_CONTINUE_SAME_SEPC,
	KVM_INSN_ILLEGAL_TRAP,
	KVM_INSN_VIRTUAL_TRAP
};

void kvm_riscv_vcpu_wfi(struct kvm_vcpu *vcpu);
int kvm_riscv_vcpu_csr_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run,
				struct kvm_cpu_trap *trap);

int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run,
			     unsigned long fault_addr,
			     unsigned long htinst);
int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run,
			      unsigned long fault_addr,
			      unsigned long htinst);
int kvm_riscv_vcpu_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run);

#endif
+1 −1
Original line number Diff line number Diff line
@@ -39,6 +39,6 @@ int kvm_riscv_vcpu_timer_init(struct kvm_vcpu *vcpu);
int kvm_riscv_vcpu_timer_deinit(struct kvm_vcpu *vcpu);
int kvm_riscv_vcpu_timer_reset(struct kvm_vcpu *vcpu);
void kvm_riscv_vcpu_timer_restore(struct kvm_vcpu *vcpu);
int kvm_riscv_guest_timer_init(struct kvm *kvm);
void kvm_riscv_guest_timer_init(struct kvm *kvm);

#endif
Loading