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

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

KVM/riscv changes for 5.18

- Prevent KVM_COMPAT from being selected
- Refine __kvm_riscv_switch_to() implementation
- RISC-V SBI v0.3 support

+161 -59
+1
arch/riscv/include/asm/kvm_host.h
··· 228 228 229 229 void __kvm_riscv_unpriv_trap(void); 230 230 231 + void kvm_riscv_vcpu_wfi(struct kvm_vcpu *vcpu); 231 232 unsigned long kvm_riscv_vcpu_unpriv_read(struct kvm_vcpu *vcpu, 232 233 bool read_insn, 233 234 unsigned long guest_addr,
+4 -1
arch/riscv/include/asm/kvm_vcpu_sbi.h
··· 12 12 #define KVM_SBI_IMPID 3 13 13 14 14 #define KVM_SBI_VERSION_MAJOR 0 15 - #define KVM_SBI_VERSION_MINOR 2 15 + #define KVM_SBI_VERSION_MINOR 3 16 16 17 17 struct kvm_vcpu_sbi_extension { 18 18 unsigned long extid_start; ··· 28 28 }; 29 29 30 30 void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run); 31 + void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu, 32 + struct kvm_run *run, 33 + u32 type, u64 flags); 31 34 const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned long extid); 32 35 33 36 #endif /* __RISCV_KVM_VCPU_SBI_H__ */
+22 -5
arch/riscv/include/asm/sbi.h
··· 71 71 SBI_EXT_HSM_HART_START = 0, 72 72 SBI_EXT_HSM_HART_STOP, 73 73 SBI_EXT_HSM_HART_STATUS, 74 + SBI_EXT_HSM_HART_SUSPEND, 74 75 }; 75 76 76 - enum sbi_hsm_hart_status { 77 - SBI_HSM_HART_STATUS_STARTED = 0, 78 - SBI_HSM_HART_STATUS_STOPPED, 79 - SBI_HSM_HART_STATUS_START_PENDING, 80 - SBI_HSM_HART_STATUS_STOP_PENDING, 77 + enum sbi_hsm_hart_state { 78 + SBI_HSM_STATE_STARTED = 0, 79 + SBI_HSM_STATE_STOPPED, 80 + SBI_HSM_STATE_START_PENDING, 81 + SBI_HSM_STATE_STOP_PENDING, 82 + SBI_HSM_STATE_SUSPENDED, 83 + SBI_HSM_STATE_SUSPEND_PENDING, 84 + SBI_HSM_STATE_RESUME_PENDING, 81 85 }; 86 + 87 + #define SBI_HSM_SUSP_BASE_MASK 0x7fffffff 88 + #define SBI_HSM_SUSP_NON_RET_BIT 0x80000000 89 + #define SBI_HSM_SUSP_PLAT_BASE 0x10000000 90 + 91 + #define SBI_HSM_SUSPEND_RET_DEFAULT 0x00000000 92 + #define SBI_HSM_SUSPEND_RET_PLATFORM SBI_HSM_SUSP_PLAT_BASE 93 + #define SBI_HSM_SUSPEND_RET_LAST SBI_HSM_SUSP_BASE_MASK 94 + #define SBI_HSM_SUSPEND_NON_RET_DEFAULT SBI_HSM_SUSP_NON_RET_BIT 95 + #define SBI_HSM_SUSPEND_NON_RET_PLATFORM (SBI_HSM_SUSP_NON_RET_BIT | \ 96 + SBI_HSM_SUSP_PLAT_BASE) 97 + #define SBI_HSM_SUSPEND_NON_RET_LAST (SBI_HSM_SUSP_NON_RET_BIT | \ 98 + SBI_HSM_SUSP_BASE_MASK) 82 99 83 100 enum sbi_ext_srst_fid { 84 101 SBI_EXT_SRST_RESET = 0,
+1 -1
arch/riscv/kernel/cpu_ops_sbi.c
··· 111 111 112 112 rc = sbi_hsm_hart_get_status(hartid); 113 113 114 - if (rc == SBI_HSM_HART_STATUS_STOPPED) 114 + if (rc == SBI_HSM_STATE_STOPPED) 115 115 return 0; 116 116 return rc; 117 117 }
+16 -6
arch/riscv/kvm/vcpu_exit.c
··· 144 144 { 145 145 if ((insn & INSN_MASK_WFI) == INSN_MATCH_WFI) { 146 146 vcpu->stat.wfi_exit_stat++; 147 - if (!kvm_arch_vcpu_runnable(vcpu)) { 148 - srcu_read_unlock(&vcpu->kvm->srcu, vcpu->arch.srcu_idx); 149 - kvm_vcpu_halt(vcpu); 150 - vcpu->arch.srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); 151 - kvm_clear_request(KVM_REQ_UNHALT, vcpu); 152 - } 147 + kvm_riscv_vcpu_wfi(vcpu); 153 148 vcpu->arch.guest_context.sepc += INSN_LEN(insn); 154 149 return 1; 155 150 } ··· 446 451 return ret; 447 452 448 453 return 1; 454 + } 455 + 456 + /** 457 + * kvm_riscv_vcpu_wfi -- Emulate wait for interrupt (WFI) behaviour 458 + * 459 + * @vcpu: The VCPU pointer 460 + */ 461 + void kvm_riscv_vcpu_wfi(struct kvm_vcpu *vcpu) 462 + { 463 + if (!kvm_arch_vcpu_runnable(vcpu)) { 464 + srcu_read_unlock(&vcpu->kvm->srcu, vcpu->arch.srcu_idx); 465 + kvm_vcpu_halt(vcpu); 466 + vcpu->arch.srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); 467 + kvm_clear_request(KVM_REQ_UNHALT, vcpu); 468 + } 449 469 } 450 470 451 471 /**
+19
arch/riscv/kvm/vcpu_sbi.c
··· 45 45 extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_time; 46 46 extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_ipi; 47 47 extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence; 48 + extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst; 48 49 extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_hsm; 49 50 extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental; 50 51 extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor; ··· 56 55 &vcpu_sbi_ext_time, 57 56 &vcpu_sbi_ext_ipi, 58 57 &vcpu_sbi_ext_rfence, 58 + &vcpu_sbi_ext_srst, 59 59 &vcpu_sbi_ext_hsm, 60 60 &vcpu_sbi_ext_experimental, 61 61 &vcpu_sbi_ext_vendor, ··· 79 77 run->riscv_sbi.args[5] = cp->a5; 80 78 run->riscv_sbi.ret[0] = cp->a0; 81 79 run->riscv_sbi.ret[1] = cp->a1; 80 + } 81 + 82 + void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu, 83 + struct kvm_run *run, 84 + u32 type, u64 flags) 85 + { 86 + unsigned long i; 87 + struct kvm_vcpu *tmp; 88 + 89 + kvm_for_each_vcpu(i, tmp, vcpu->kvm) 90 + tmp->arch.power_off = true; 91 + kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP); 92 + 93 + memset(&run->system_event, 0, sizeof(run->system_event)); 94 + run->system_event.type = type; 95 + run->system_event.flags = flags; 96 + run->exit_reason = KVM_EXIT_SYSTEM_EVENT; 82 97 } 83 98 84 99 int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
+16 -2
arch/riscv/kvm/vcpu_sbi_hsm.c
··· 60 60 if (!target_vcpu) 61 61 return -EINVAL; 62 62 if (!target_vcpu->arch.power_off) 63 - return SBI_HSM_HART_STATUS_STARTED; 63 + return SBI_HSM_STATE_STARTED; 64 + else if (vcpu->stat.generic.blocking) 65 + return SBI_HSM_STATE_SUSPENDED; 64 66 else 65 - return SBI_HSM_HART_STATUS_STOPPED; 67 + return SBI_HSM_STATE_STOPPED; 66 68 } 67 69 68 70 static int kvm_sbi_ext_hsm_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, ··· 91 89 if (ret >= 0) { 92 90 *out_val = ret; 93 91 ret = 0; 92 + } 93 + break; 94 + case SBI_EXT_HSM_HART_SUSPEND: 95 + switch (cp->a0) { 96 + case SBI_HSM_SUSPEND_RET_DEFAULT: 97 + kvm_riscv_vcpu_wfi(vcpu); 98 + break; 99 + case SBI_HSM_SUSPEND_NON_RET_DEFAULT: 100 + ret = -EOPNOTSUPP; 101 + break; 102 + default: 103 + ret = -EINVAL; 94 104 } 95 105 break; 96 106 default:
+44
arch/riscv/kvm/vcpu_sbi_replace.c
··· 130 130 .extid_end = SBI_EXT_RFENCE, 131 131 .handler = kvm_sbi_ext_rfence_handler, 132 132 }; 133 + 134 + static int kvm_sbi_ext_srst_handler(struct kvm_vcpu *vcpu, 135 + struct kvm_run *run, 136 + unsigned long *out_val, 137 + struct kvm_cpu_trap *utrap, bool *exit) 138 + { 139 + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; 140 + unsigned long funcid = cp->a6; 141 + u32 reason = cp->a1; 142 + u32 type = cp->a0; 143 + int ret = 0; 144 + 145 + switch (funcid) { 146 + case SBI_EXT_SRST_RESET: 147 + switch (type) { 148 + case SBI_SRST_RESET_TYPE_SHUTDOWN: 149 + kvm_riscv_vcpu_sbi_system_reset(vcpu, run, 150 + KVM_SYSTEM_EVENT_SHUTDOWN, 151 + reason); 152 + *exit = true; 153 + break; 154 + case SBI_SRST_RESET_TYPE_COLD_REBOOT: 155 + case SBI_SRST_RESET_TYPE_WARM_REBOOT: 156 + kvm_riscv_vcpu_sbi_system_reset(vcpu, run, 157 + KVM_SYSTEM_EVENT_RESET, 158 + reason); 159 + *exit = true; 160 + break; 161 + default: 162 + ret = -EOPNOTSUPP; 163 + } 164 + break; 165 + default: 166 + ret = -EOPNOTSUPP; 167 + } 168 + 169 + return ret; 170 + } 171 + 172 + const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst = { 173 + .extid_start = SBI_EXT_SRST, 174 + .extid_end = SBI_EXT_SRST, 175 + .handler = kvm_sbi_ext_srst_handler, 176 + };
+3 -17
arch/riscv/kvm/vcpu_sbi_v01.c
··· 14 14 #include <asm/kvm_vcpu_timer.h> 15 15 #include <asm/kvm_vcpu_sbi.h> 16 16 17 - static void kvm_sbi_system_shutdown(struct kvm_vcpu *vcpu, 18 - struct kvm_run *run, u32 type) 19 - { 20 - unsigned long i; 21 - struct kvm_vcpu *tmp; 22 - 23 - kvm_for_each_vcpu(i, tmp, vcpu->kvm) 24 - tmp->arch.power_off = true; 25 - kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP); 26 - 27 - memset(&run->system_event, 0, sizeof(run->system_event)); 28 - run->system_event.type = type; 29 - run->exit_reason = KVM_EXIT_SYSTEM_EVENT; 30 - } 31 - 32 17 static int kvm_sbi_ext_v01_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, 33 18 unsigned long *out_val, 34 19 struct kvm_cpu_trap *utrap, ··· 65 80 } 66 81 break; 67 82 case SBI_EXT_0_1_SHUTDOWN: 68 - kvm_sbi_system_shutdown(vcpu, run, KVM_SYSTEM_EVENT_SHUTDOWN); 83 + kvm_riscv_vcpu_sbi_system_reset(vcpu, run, 84 + KVM_SYSTEM_EVENT_SHUTDOWN, 0); 69 85 *exit = true; 70 86 break; 71 87 case SBI_EXT_0_1_REMOTE_FENCE_I: ··· 97 111 default: 98 112 ret = -EINVAL; 99 113 break; 100 - }; 114 + } 101 115 102 116 return ret; 103 117 }
+34 -26
arch/riscv/kvm/vcpu_switch.S
··· 41 41 REG_S s10, (KVM_ARCH_HOST_S10)(a0) 42 42 REG_S s11, (KVM_ARCH_HOST_S11)(a0) 43 43 44 - /* Save Host and Restore Guest SSTATUS */ 44 + /* Load Guest CSR values */ 45 45 REG_L t0, (KVM_ARCH_GUEST_SSTATUS)(a0) 46 + REG_L t1, (KVM_ARCH_GUEST_HSTATUS)(a0) 47 + REG_L t2, (KVM_ARCH_GUEST_SCOUNTEREN)(a0) 48 + la t4, __kvm_switch_return 49 + REG_L t5, (KVM_ARCH_GUEST_SEPC)(a0) 50 + 51 + /* Save Host and Restore Guest SSTATUS */ 46 52 csrrw t0, CSR_SSTATUS, t0 47 - REG_S t0, (KVM_ARCH_HOST_SSTATUS)(a0) 48 53 49 54 /* Save Host and Restore Guest HSTATUS */ 50 - REG_L t1, (KVM_ARCH_GUEST_HSTATUS)(a0) 51 55 csrrw t1, CSR_HSTATUS, t1 52 - REG_S t1, (KVM_ARCH_HOST_HSTATUS)(a0) 53 56 54 57 /* Save Host and Restore Guest SCOUNTEREN */ 55 - REG_L t2, (KVM_ARCH_GUEST_SCOUNTEREN)(a0) 56 58 csrrw t2, CSR_SCOUNTEREN, t2 57 - REG_S t2, (KVM_ARCH_HOST_SCOUNTEREN)(a0) 59 + 60 + /* Save Host STVEC and change it to return path */ 61 + csrrw t4, CSR_STVEC, t4 58 62 59 63 /* Save Host SSCRATCH and change it to struct kvm_vcpu_arch pointer */ 60 64 csrrw t3, CSR_SSCRATCH, a0 61 - REG_S t3, (KVM_ARCH_HOST_SSCRATCH)(a0) 62 - 63 - /* Save Host STVEC and change it to return path */ 64 - la t4, __kvm_switch_return 65 - csrrw t4, CSR_STVEC, t4 66 - REG_S t4, (KVM_ARCH_HOST_STVEC)(a0) 67 65 68 66 /* Restore Guest SEPC */ 69 - REG_L t0, (KVM_ARCH_GUEST_SEPC)(a0) 70 - csrw CSR_SEPC, t0 67 + csrw CSR_SEPC, t5 68 + 69 + /* Store Host CSR values */ 70 + REG_S t0, (KVM_ARCH_HOST_SSTATUS)(a0) 71 + REG_S t1, (KVM_ARCH_HOST_HSTATUS)(a0) 72 + REG_S t2, (KVM_ARCH_HOST_SCOUNTEREN)(a0) 73 + REG_S t3, (KVM_ARCH_HOST_SSCRATCH)(a0) 74 + REG_S t4, (KVM_ARCH_HOST_STVEC)(a0) 71 75 72 76 /* Restore Guest GPRs (except A0) */ 73 77 REG_L ra, (KVM_ARCH_GUEST_RA)(a0) ··· 149 145 REG_S t5, (KVM_ARCH_GUEST_T5)(a0) 150 146 REG_S t6, (KVM_ARCH_GUEST_T6)(a0) 151 147 148 + /* Load Host CSR values */ 149 + REG_L t1, (KVM_ARCH_HOST_STVEC)(a0) 150 + REG_L t2, (KVM_ARCH_HOST_SSCRATCH)(a0) 151 + REG_L t3, (KVM_ARCH_HOST_SCOUNTEREN)(a0) 152 + REG_L t4, (KVM_ARCH_HOST_HSTATUS)(a0) 153 + REG_L t5, (KVM_ARCH_HOST_SSTATUS)(a0) 154 + 152 155 /* Save Guest SEPC */ 153 156 csrr t0, CSR_SEPC 154 - REG_S t0, (KVM_ARCH_GUEST_SEPC)(a0) 155 - 156 - /* Restore Host STVEC */ 157 - REG_L t1, (KVM_ARCH_HOST_STVEC)(a0) 158 - csrw CSR_STVEC, t1 159 157 160 158 /* Save Guest A0 and Restore Host SSCRATCH */ 161 - REG_L t2, (KVM_ARCH_HOST_SSCRATCH)(a0) 162 159 csrrw t2, CSR_SSCRATCH, t2 163 - REG_S t2, (KVM_ARCH_GUEST_A0)(a0) 160 + 161 + /* Restore Host STVEC */ 162 + csrw CSR_STVEC, t1 164 163 165 164 /* Save Guest and Restore Host SCOUNTEREN */ 166 - REG_L t3, (KVM_ARCH_HOST_SCOUNTEREN)(a0) 167 165 csrrw t3, CSR_SCOUNTEREN, t3 168 - REG_S t3, (KVM_ARCH_GUEST_SCOUNTEREN)(a0) 169 166 170 167 /* Save Guest and Restore Host HSTATUS */ 171 - REG_L t4, (KVM_ARCH_HOST_HSTATUS)(a0) 172 168 csrrw t4, CSR_HSTATUS, t4 173 - REG_S t4, (KVM_ARCH_GUEST_HSTATUS)(a0) 174 169 175 170 /* Save Guest and Restore Host SSTATUS */ 176 - REG_L t5, (KVM_ARCH_HOST_SSTATUS)(a0) 177 171 csrrw t5, CSR_SSTATUS, t5 172 + 173 + /* Store Guest CSR values */ 174 + REG_S t0, (KVM_ARCH_GUEST_SEPC)(a0) 175 + REG_S t2, (KVM_ARCH_GUEST_A0)(a0) 176 + REG_S t3, (KVM_ARCH_GUEST_SCOUNTEREN)(a0) 177 + REG_S t4, (KVM_ARCH_GUEST_HSTATUS)(a0) 178 178 REG_S t5, (KVM_ARCH_GUEST_SSTATUS)(a0) 179 179 180 180 /* Restore Host GPRs (except A0 and T0-T6) */
+1 -1
virt/kvm/Kconfig
··· 53 53 54 54 config KVM_COMPAT 55 55 def_bool y 56 - depends on KVM && COMPAT && !(S390 || ARM64) 56 + depends on KVM && COMPAT && !(S390 || ARM64 || RISCV) 57 57 58 58 config HAVE_KVM_IRQ_BYPASS 59 59 bool