Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

RISC-V: KVM: Implement VCPU create, init and destroy functions

This patch implements VCPU create, init and destroy functions
required by generic KVM module. We don't have much dynamic
resources in struct kvm_vcpu_arch so these functions are quite
simple for KVM RISC-V.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Alexander Graf <graf@amazon.com>
Acked-by: Palmer Dabbelt <palmerdabbelt@google.com>

authored by

Anup Patel and committed by
Anup Patel
a33c72fa 99cdc6c1

+115 -9
+69
arch/riscv/include/asm/kvm_host.h
··· 57 57 unsigned long htinst; 58 58 }; 59 59 60 + struct kvm_cpu_context { 61 + unsigned long zero; 62 + unsigned long ra; 63 + unsigned long sp; 64 + unsigned long gp; 65 + unsigned long tp; 66 + unsigned long t0; 67 + unsigned long t1; 68 + unsigned long t2; 69 + unsigned long s0; 70 + unsigned long s1; 71 + unsigned long a0; 72 + unsigned long a1; 73 + unsigned long a2; 74 + unsigned long a3; 75 + unsigned long a4; 76 + unsigned long a5; 77 + unsigned long a6; 78 + unsigned long a7; 79 + unsigned long s2; 80 + unsigned long s3; 81 + unsigned long s4; 82 + unsigned long s5; 83 + unsigned long s6; 84 + unsigned long s7; 85 + unsigned long s8; 86 + unsigned long s9; 87 + unsigned long s10; 88 + unsigned long s11; 89 + unsigned long t3; 90 + unsigned long t4; 91 + unsigned long t5; 92 + unsigned long t6; 93 + unsigned long sepc; 94 + unsigned long sstatus; 95 + unsigned long hstatus; 96 + }; 97 + 98 + struct kvm_vcpu_csr { 99 + unsigned long vsstatus; 100 + unsigned long vsie; 101 + unsigned long vstvec; 102 + unsigned long vsscratch; 103 + unsigned long vsepc; 104 + unsigned long vscause; 105 + unsigned long vstval; 106 + unsigned long hvip; 107 + unsigned long vsatp; 108 + unsigned long scounteren; 109 + }; 110 + 60 111 struct kvm_vcpu_arch { 112 + /* VCPU ran at least once */ 113 + bool ran_atleast_once; 114 + 115 + /* ISA feature bits (similar to MISA) */ 116 + unsigned long isa; 117 + 118 + /* CPU context of Guest VCPU */ 119 + struct kvm_cpu_context guest_context; 120 + 121 + /* CPU CSR context of Guest VCPU */ 122 + struct kvm_vcpu_csr guest_csr; 123 + 124 + /* CPU context upon Guest VCPU reset */ 125 + struct kvm_cpu_context guest_reset_context; 126 + 127 + /* CPU CSR context upon Guest VCPU reset */ 128 + struct kvm_vcpu_csr guest_reset_csr; 129 + 61 130 /* Don't run the VCPU (blocked) */ 62 131 bool pause; 63 132
+46 -9
arch/riscv/kvm/vcpu.c
··· 38 38 sizeof(kvm_vcpu_stats_desc), 39 39 }; 40 40 41 + #define KVM_RISCV_ISA_ALLOWED (riscv_isa_extension_mask(a) | \ 42 + riscv_isa_extension_mask(c) | \ 43 + riscv_isa_extension_mask(d) | \ 44 + riscv_isa_extension_mask(f) | \ 45 + riscv_isa_extension_mask(i) | \ 46 + riscv_isa_extension_mask(m) | \ 47 + riscv_isa_extension_mask(s) | \ 48 + riscv_isa_extension_mask(u)) 49 + 50 + static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu) 51 + { 52 + struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; 53 + struct kvm_vcpu_csr *reset_csr = &vcpu->arch.guest_reset_csr; 54 + struct kvm_cpu_context *cntx = &vcpu->arch.guest_context; 55 + struct kvm_cpu_context *reset_cntx = &vcpu->arch.guest_reset_context; 56 + 57 + memcpy(csr, reset_csr, sizeof(*csr)); 58 + 59 + memcpy(cntx, reset_cntx, sizeof(*cntx)); 60 + } 61 + 41 62 int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id) 42 63 { 43 64 return 0; ··· 66 45 67 46 int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) 68 47 { 69 - /* TODO: */ 48 + struct kvm_cpu_context *cntx; 49 + 50 + /* Mark this VCPU never ran */ 51 + vcpu->arch.ran_atleast_once = false; 52 + 53 + /* Setup ISA features available to VCPU */ 54 + vcpu->arch.isa = riscv_isa_extension_base(NULL) & KVM_RISCV_ISA_ALLOWED; 55 + 56 + /* Setup reset state of shadow SSTATUS and HSTATUS CSRs */ 57 + cntx = &vcpu->arch.guest_reset_context; 58 + cntx->sstatus = SR_SPP | SR_SPIE; 59 + cntx->hstatus = 0; 60 + cntx->hstatus |= HSTATUS_VTW; 61 + cntx->hstatus |= HSTATUS_SPVP; 62 + cntx->hstatus |= HSTATUS_SPV; 63 + 64 + /* Reset VCPU */ 65 + kvm_riscv_reset_vcpu(vcpu); 66 + 70 67 return 0; 71 68 } 72 69 ··· 92 53 { 93 54 } 94 55 95 - int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) 96 - { 97 - /* TODO: */ 98 - return 0; 99 - } 100 - 101 56 void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) 102 57 { 103 - /* TODO: */ 58 + /* Flush the pages pre-allocated for Stage2 page table mappings */ 59 + kvm_riscv_stage2_flush_cache(vcpu); 104 60 } 105 61 106 62 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) ··· 231 197 struct kvm_cpu_trap trap; 232 198 struct kvm_run *run = vcpu->run; 233 199 200 + /* Mark this VCPU ran at least once */ 201 + vcpu->arch.ran_atleast_once = true; 202 + 234 203 vcpu->arch.srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); 235 204 236 205 /* Process MMIO value returned from user-space */ ··· 307 270 * get an interrupt between __kvm_riscv_switch_to() and 308 271 * local_irq_enable() which can potentially change CSRs. 309 272 */ 310 - trap.sepc = 0; 273 + trap.sepc = vcpu->arch.guest_context.sepc; 311 274 trap.scause = csr_read(CSR_SCAUSE); 312 275 trap.stval = csr_read(CSR_STVAL); 313 276 trap.htval = csr_read(CSR_HTVAL);