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 world-switch

This patch implements the VCPU world-switch for KVM RISC-V.

The KVM RISC-V world-switch (i.e. __kvm_riscv_switch_to()) mostly
switches general purpose registers, SSTATUS, STVEC, SSCRATCH and
HSTATUS CSRs. Other CSRs are switched via vcpu_load() and vcpu_put()
interface in kvm_arch_vcpu_load() and kvm_arch_vcpu_put() functions
respectively.

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
34bde9d8 92ad8200

+319 -4
+9 -1
arch/riscv/include/asm/kvm_host.h
··· 115 115 /* ISA feature bits (similar to MISA) */ 116 116 unsigned long isa; 117 117 118 + /* SSCRATCH, STVEC, and SCOUNTEREN of Host */ 119 + unsigned long host_sscratch; 120 + unsigned long host_stvec; 121 + unsigned long host_scounteren; 122 + 123 + /* CPU context of Host */ 124 + struct kvm_cpu_context host_context; 125 + 118 126 /* CPU context of Guest VCPU */ 119 127 struct kvm_cpu_context guest_context; 120 128 ··· 171 163 int kvm_riscv_vcpu_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, 172 164 struct kvm_cpu_trap *trap); 173 165 174 - static inline void __kvm_riscv_switch_to(struct kvm_vcpu_arch *vcpu_arch) {} 166 + void __kvm_riscv_switch_to(struct kvm_vcpu_arch *vcpu_arch); 175 167 176 168 int kvm_riscv_vcpu_set_interrupt(struct kvm_vcpu *vcpu, unsigned int irq); 177 169 int kvm_riscv_vcpu_unset_interrupt(struct kvm_vcpu *vcpu, unsigned int irq);
+78
arch/riscv/kernel/asm-offsets.c
··· 7 7 #define GENERATING_ASM_OFFSETS 8 8 9 9 #include <linux/kbuild.h> 10 + #include <linux/mm.h> 10 11 #include <linux/sched.h> 12 + #include <asm/kvm_host.h> 11 13 #include <asm/thread_info.h> 12 14 #include <asm/ptrace.h> 13 15 ··· 112 110 OFFSET(PT_STATUS, pt_regs, status); 113 111 OFFSET(PT_BADADDR, pt_regs, badaddr); 114 112 OFFSET(PT_CAUSE, pt_regs, cause); 113 + 114 + OFFSET(KVM_ARCH_GUEST_ZERO, kvm_vcpu_arch, guest_context.zero); 115 + OFFSET(KVM_ARCH_GUEST_RA, kvm_vcpu_arch, guest_context.ra); 116 + OFFSET(KVM_ARCH_GUEST_SP, kvm_vcpu_arch, guest_context.sp); 117 + OFFSET(KVM_ARCH_GUEST_GP, kvm_vcpu_arch, guest_context.gp); 118 + OFFSET(KVM_ARCH_GUEST_TP, kvm_vcpu_arch, guest_context.tp); 119 + OFFSET(KVM_ARCH_GUEST_T0, kvm_vcpu_arch, guest_context.t0); 120 + OFFSET(KVM_ARCH_GUEST_T1, kvm_vcpu_arch, guest_context.t1); 121 + OFFSET(KVM_ARCH_GUEST_T2, kvm_vcpu_arch, guest_context.t2); 122 + OFFSET(KVM_ARCH_GUEST_S0, kvm_vcpu_arch, guest_context.s0); 123 + OFFSET(KVM_ARCH_GUEST_S1, kvm_vcpu_arch, guest_context.s1); 124 + OFFSET(KVM_ARCH_GUEST_A0, kvm_vcpu_arch, guest_context.a0); 125 + OFFSET(KVM_ARCH_GUEST_A1, kvm_vcpu_arch, guest_context.a1); 126 + OFFSET(KVM_ARCH_GUEST_A2, kvm_vcpu_arch, guest_context.a2); 127 + OFFSET(KVM_ARCH_GUEST_A3, kvm_vcpu_arch, guest_context.a3); 128 + OFFSET(KVM_ARCH_GUEST_A4, kvm_vcpu_arch, guest_context.a4); 129 + OFFSET(KVM_ARCH_GUEST_A5, kvm_vcpu_arch, guest_context.a5); 130 + OFFSET(KVM_ARCH_GUEST_A6, kvm_vcpu_arch, guest_context.a6); 131 + OFFSET(KVM_ARCH_GUEST_A7, kvm_vcpu_arch, guest_context.a7); 132 + OFFSET(KVM_ARCH_GUEST_S2, kvm_vcpu_arch, guest_context.s2); 133 + OFFSET(KVM_ARCH_GUEST_S3, kvm_vcpu_arch, guest_context.s3); 134 + OFFSET(KVM_ARCH_GUEST_S4, kvm_vcpu_arch, guest_context.s4); 135 + OFFSET(KVM_ARCH_GUEST_S5, kvm_vcpu_arch, guest_context.s5); 136 + OFFSET(KVM_ARCH_GUEST_S6, kvm_vcpu_arch, guest_context.s6); 137 + OFFSET(KVM_ARCH_GUEST_S7, kvm_vcpu_arch, guest_context.s7); 138 + OFFSET(KVM_ARCH_GUEST_S8, kvm_vcpu_arch, guest_context.s8); 139 + OFFSET(KVM_ARCH_GUEST_S9, kvm_vcpu_arch, guest_context.s9); 140 + OFFSET(KVM_ARCH_GUEST_S10, kvm_vcpu_arch, guest_context.s10); 141 + OFFSET(KVM_ARCH_GUEST_S11, kvm_vcpu_arch, guest_context.s11); 142 + OFFSET(KVM_ARCH_GUEST_T3, kvm_vcpu_arch, guest_context.t3); 143 + OFFSET(KVM_ARCH_GUEST_T4, kvm_vcpu_arch, guest_context.t4); 144 + OFFSET(KVM_ARCH_GUEST_T5, kvm_vcpu_arch, guest_context.t5); 145 + OFFSET(KVM_ARCH_GUEST_T6, kvm_vcpu_arch, guest_context.t6); 146 + OFFSET(KVM_ARCH_GUEST_SEPC, kvm_vcpu_arch, guest_context.sepc); 147 + OFFSET(KVM_ARCH_GUEST_SSTATUS, kvm_vcpu_arch, guest_context.sstatus); 148 + OFFSET(KVM_ARCH_GUEST_HSTATUS, kvm_vcpu_arch, guest_context.hstatus); 149 + OFFSET(KVM_ARCH_GUEST_SCOUNTEREN, kvm_vcpu_arch, guest_csr.scounteren); 150 + 151 + OFFSET(KVM_ARCH_HOST_ZERO, kvm_vcpu_arch, host_context.zero); 152 + OFFSET(KVM_ARCH_HOST_RA, kvm_vcpu_arch, host_context.ra); 153 + OFFSET(KVM_ARCH_HOST_SP, kvm_vcpu_arch, host_context.sp); 154 + OFFSET(KVM_ARCH_HOST_GP, kvm_vcpu_arch, host_context.gp); 155 + OFFSET(KVM_ARCH_HOST_TP, kvm_vcpu_arch, host_context.tp); 156 + OFFSET(KVM_ARCH_HOST_T0, kvm_vcpu_arch, host_context.t0); 157 + OFFSET(KVM_ARCH_HOST_T1, kvm_vcpu_arch, host_context.t1); 158 + OFFSET(KVM_ARCH_HOST_T2, kvm_vcpu_arch, host_context.t2); 159 + OFFSET(KVM_ARCH_HOST_S0, kvm_vcpu_arch, host_context.s0); 160 + OFFSET(KVM_ARCH_HOST_S1, kvm_vcpu_arch, host_context.s1); 161 + OFFSET(KVM_ARCH_HOST_A0, kvm_vcpu_arch, host_context.a0); 162 + OFFSET(KVM_ARCH_HOST_A1, kvm_vcpu_arch, host_context.a1); 163 + OFFSET(KVM_ARCH_HOST_A2, kvm_vcpu_arch, host_context.a2); 164 + OFFSET(KVM_ARCH_HOST_A3, kvm_vcpu_arch, host_context.a3); 165 + OFFSET(KVM_ARCH_HOST_A4, kvm_vcpu_arch, host_context.a4); 166 + OFFSET(KVM_ARCH_HOST_A5, kvm_vcpu_arch, host_context.a5); 167 + OFFSET(KVM_ARCH_HOST_A6, kvm_vcpu_arch, host_context.a6); 168 + OFFSET(KVM_ARCH_HOST_A7, kvm_vcpu_arch, host_context.a7); 169 + OFFSET(KVM_ARCH_HOST_S2, kvm_vcpu_arch, host_context.s2); 170 + OFFSET(KVM_ARCH_HOST_S3, kvm_vcpu_arch, host_context.s3); 171 + OFFSET(KVM_ARCH_HOST_S4, kvm_vcpu_arch, host_context.s4); 172 + OFFSET(KVM_ARCH_HOST_S5, kvm_vcpu_arch, host_context.s5); 173 + OFFSET(KVM_ARCH_HOST_S6, kvm_vcpu_arch, host_context.s6); 174 + OFFSET(KVM_ARCH_HOST_S7, kvm_vcpu_arch, host_context.s7); 175 + OFFSET(KVM_ARCH_HOST_S8, kvm_vcpu_arch, host_context.s8); 176 + OFFSET(KVM_ARCH_HOST_S9, kvm_vcpu_arch, host_context.s9); 177 + OFFSET(KVM_ARCH_HOST_S10, kvm_vcpu_arch, host_context.s10); 178 + OFFSET(KVM_ARCH_HOST_S11, kvm_vcpu_arch, host_context.s11); 179 + OFFSET(KVM_ARCH_HOST_T3, kvm_vcpu_arch, host_context.t3); 180 + OFFSET(KVM_ARCH_HOST_T4, kvm_vcpu_arch, host_context.t4); 181 + OFFSET(KVM_ARCH_HOST_T5, kvm_vcpu_arch, host_context.t5); 182 + OFFSET(KVM_ARCH_HOST_T6, kvm_vcpu_arch, host_context.t6); 183 + OFFSET(KVM_ARCH_HOST_SEPC, kvm_vcpu_arch, host_context.sepc); 184 + OFFSET(KVM_ARCH_HOST_SSTATUS, kvm_vcpu_arch, host_context.sstatus); 185 + OFFSET(KVM_ARCH_HOST_HSTATUS, kvm_vcpu_arch, host_context.hstatus); 186 + OFFSET(KVM_ARCH_HOST_SSCRATCH, kvm_vcpu_arch, host_sscratch); 187 + OFFSET(KVM_ARCH_HOST_STVEC, kvm_vcpu_arch, host_stvec); 188 + OFFSET(KVM_ARCH_HOST_SCOUNTEREN, kvm_vcpu_arch, host_scounteren); 115 189 116 190 /* 117 191 * THREAD_{F,X}* might be larger than a S-type offset can handle, but
+1 -1
arch/riscv/kvm/Makefile
··· 10 10 obj-$(CONFIG_KVM) += kvm.o 11 11 12 12 kvm-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/binary_stats.o \ 13 - main.o vm.o mmu.o vcpu.o vcpu_exit.o 13 + main.o vm.o mmu.o vcpu.o vcpu_exit.o vcpu_switch.o
+28 -2
arch/riscv/kvm/vcpu.c
··· 565 565 566 566 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) 567 567 { 568 - /* TODO: */ 568 + struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; 569 + 570 + csr_write(CSR_VSSTATUS, csr->vsstatus); 571 + csr_write(CSR_VSIE, csr->vsie); 572 + csr_write(CSR_VSTVEC, csr->vstvec); 573 + csr_write(CSR_VSSCRATCH, csr->vsscratch); 574 + csr_write(CSR_VSEPC, csr->vsepc); 575 + csr_write(CSR_VSCAUSE, csr->vscause); 576 + csr_write(CSR_VSTVAL, csr->vstval); 577 + csr_write(CSR_HVIP, csr->hvip); 578 + csr_write(CSR_VSATP, csr->vsatp); 569 579 570 580 kvm_riscv_stage2_update_hgatp(vcpu); 581 + 582 + vcpu->cpu = cpu; 571 583 } 572 584 573 585 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) 574 586 { 575 - /* TODO: */ 587 + struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; 588 + 589 + vcpu->cpu = -1; 590 + 591 + csr_write(CSR_HGATP, 0); 592 + 593 + csr->vsstatus = csr_read(CSR_VSSTATUS); 594 + csr->vsie = csr_read(CSR_VSIE); 595 + csr->vstvec = csr_read(CSR_VSTVEC); 596 + csr->vsscratch = csr_read(CSR_VSSCRATCH); 597 + csr->vsepc = csr_read(CSR_VSEPC); 598 + csr->vscause = csr_read(CSR_VSCAUSE); 599 + csr->vstval = csr_read(CSR_VSTVAL); 600 + csr->hvip = csr_read(CSR_HVIP); 601 + csr->vsatp = csr_read(CSR_VSATP); 576 602 } 577 603 578 604 static void kvm_riscv_check_vcpu_requests(struct kvm_vcpu *vcpu)
+203
arch/riscv/kvm/vcpu_switch.S
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2019 Western Digital Corporation or its affiliates. 4 + * 5 + * Authors: 6 + * Anup Patel <anup.patel@wdc.com> 7 + */ 8 + 9 + #include <linux/linkage.h> 10 + #include <asm/asm.h> 11 + #include <asm/asm-offsets.h> 12 + #include <asm/csr.h> 13 + 14 + .text 15 + .altmacro 16 + .option norelax 17 + 18 + ENTRY(__kvm_riscv_switch_to) 19 + /* Save Host GPRs (except A0 and T0-T6) */ 20 + REG_S ra, (KVM_ARCH_HOST_RA)(a0) 21 + REG_S sp, (KVM_ARCH_HOST_SP)(a0) 22 + REG_S gp, (KVM_ARCH_HOST_GP)(a0) 23 + REG_S tp, (KVM_ARCH_HOST_TP)(a0) 24 + REG_S s0, (KVM_ARCH_HOST_S0)(a0) 25 + REG_S s1, (KVM_ARCH_HOST_S1)(a0) 26 + REG_S a1, (KVM_ARCH_HOST_A1)(a0) 27 + REG_S a2, (KVM_ARCH_HOST_A2)(a0) 28 + REG_S a3, (KVM_ARCH_HOST_A3)(a0) 29 + REG_S a4, (KVM_ARCH_HOST_A4)(a0) 30 + REG_S a5, (KVM_ARCH_HOST_A5)(a0) 31 + REG_S a6, (KVM_ARCH_HOST_A6)(a0) 32 + REG_S a7, (KVM_ARCH_HOST_A7)(a0) 33 + REG_S s2, (KVM_ARCH_HOST_S2)(a0) 34 + REG_S s3, (KVM_ARCH_HOST_S3)(a0) 35 + REG_S s4, (KVM_ARCH_HOST_S4)(a0) 36 + REG_S s5, (KVM_ARCH_HOST_S5)(a0) 37 + REG_S s6, (KVM_ARCH_HOST_S6)(a0) 38 + REG_S s7, (KVM_ARCH_HOST_S7)(a0) 39 + REG_S s8, (KVM_ARCH_HOST_S8)(a0) 40 + REG_S s9, (KVM_ARCH_HOST_S9)(a0) 41 + REG_S s10, (KVM_ARCH_HOST_S10)(a0) 42 + REG_S s11, (KVM_ARCH_HOST_S11)(a0) 43 + 44 + /* Save Host and Restore Guest SSTATUS */ 45 + REG_L t0, (KVM_ARCH_GUEST_SSTATUS)(a0) 46 + csrrw t0, CSR_SSTATUS, t0 47 + REG_S t0, (KVM_ARCH_HOST_SSTATUS)(a0) 48 + 49 + /* Save Host and Restore Guest HSTATUS */ 50 + REG_L t1, (KVM_ARCH_GUEST_HSTATUS)(a0) 51 + csrrw t1, CSR_HSTATUS, t1 52 + REG_S t1, (KVM_ARCH_HOST_HSTATUS)(a0) 53 + 54 + /* Save Host and Restore Guest SCOUNTEREN */ 55 + REG_L t2, (KVM_ARCH_GUEST_SCOUNTEREN)(a0) 56 + csrrw t2, CSR_SCOUNTEREN, t2 57 + REG_S t2, (KVM_ARCH_HOST_SCOUNTEREN)(a0) 58 + 59 + /* Save Host SSCRATCH and change it to struct kvm_vcpu_arch pointer */ 60 + 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 + 68 + /* Restore Guest SEPC */ 69 + REG_L t0, (KVM_ARCH_GUEST_SEPC)(a0) 70 + csrw CSR_SEPC, t0 71 + 72 + /* Restore Guest GPRs (except A0) */ 73 + REG_L ra, (KVM_ARCH_GUEST_RA)(a0) 74 + REG_L sp, (KVM_ARCH_GUEST_SP)(a0) 75 + REG_L gp, (KVM_ARCH_GUEST_GP)(a0) 76 + REG_L tp, (KVM_ARCH_GUEST_TP)(a0) 77 + REG_L t0, (KVM_ARCH_GUEST_T0)(a0) 78 + REG_L t1, (KVM_ARCH_GUEST_T1)(a0) 79 + REG_L t2, (KVM_ARCH_GUEST_T2)(a0) 80 + REG_L s0, (KVM_ARCH_GUEST_S0)(a0) 81 + REG_L s1, (KVM_ARCH_GUEST_S1)(a0) 82 + REG_L a1, (KVM_ARCH_GUEST_A1)(a0) 83 + REG_L a2, (KVM_ARCH_GUEST_A2)(a0) 84 + REG_L a3, (KVM_ARCH_GUEST_A3)(a0) 85 + REG_L a4, (KVM_ARCH_GUEST_A4)(a0) 86 + REG_L a5, (KVM_ARCH_GUEST_A5)(a0) 87 + REG_L a6, (KVM_ARCH_GUEST_A6)(a0) 88 + REG_L a7, (KVM_ARCH_GUEST_A7)(a0) 89 + REG_L s2, (KVM_ARCH_GUEST_S2)(a0) 90 + REG_L s3, (KVM_ARCH_GUEST_S3)(a0) 91 + REG_L s4, (KVM_ARCH_GUEST_S4)(a0) 92 + REG_L s5, (KVM_ARCH_GUEST_S5)(a0) 93 + REG_L s6, (KVM_ARCH_GUEST_S6)(a0) 94 + REG_L s7, (KVM_ARCH_GUEST_S7)(a0) 95 + REG_L s8, (KVM_ARCH_GUEST_S8)(a0) 96 + REG_L s9, (KVM_ARCH_GUEST_S9)(a0) 97 + REG_L s10, (KVM_ARCH_GUEST_S10)(a0) 98 + REG_L s11, (KVM_ARCH_GUEST_S11)(a0) 99 + REG_L t3, (KVM_ARCH_GUEST_T3)(a0) 100 + REG_L t4, (KVM_ARCH_GUEST_T4)(a0) 101 + REG_L t5, (KVM_ARCH_GUEST_T5)(a0) 102 + REG_L t6, (KVM_ARCH_GUEST_T6)(a0) 103 + 104 + /* Restore Guest A0 */ 105 + REG_L a0, (KVM_ARCH_GUEST_A0)(a0) 106 + 107 + /* Resume Guest */ 108 + sret 109 + 110 + /* Back to Host */ 111 + .align 2 112 + __kvm_switch_return: 113 + /* Swap Guest A0 with SSCRATCH */ 114 + csrrw a0, CSR_SSCRATCH, a0 115 + 116 + /* Save Guest GPRs (except A0) */ 117 + REG_S ra, (KVM_ARCH_GUEST_RA)(a0) 118 + REG_S sp, (KVM_ARCH_GUEST_SP)(a0) 119 + REG_S gp, (KVM_ARCH_GUEST_GP)(a0) 120 + REG_S tp, (KVM_ARCH_GUEST_TP)(a0) 121 + REG_S t0, (KVM_ARCH_GUEST_T0)(a0) 122 + REG_S t1, (KVM_ARCH_GUEST_T1)(a0) 123 + REG_S t2, (KVM_ARCH_GUEST_T2)(a0) 124 + REG_S s0, (KVM_ARCH_GUEST_S0)(a0) 125 + REG_S s1, (KVM_ARCH_GUEST_S1)(a0) 126 + REG_S a1, (KVM_ARCH_GUEST_A1)(a0) 127 + REG_S a2, (KVM_ARCH_GUEST_A2)(a0) 128 + REG_S a3, (KVM_ARCH_GUEST_A3)(a0) 129 + REG_S a4, (KVM_ARCH_GUEST_A4)(a0) 130 + REG_S a5, (KVM_ARCH_GUEST_A5)(a0) 131 + REG_S a6, (KVM_ARCH_GUEST_A6)(a0) 132 + REG_S a7, (KVM_ARCH_GUEST_A7)(a0) 133 + REG_S s2, (KVM_ARCH_GUEST_S2)(a0) 134 + REG_S s3, (KVM_ARCH_GUEST_S3)(a0) 135 + REG_S s4, (KVM_ARCH_GUEST_S4)(a0) 136 + REG_S s5, (KVM_ARCH_GUEST_S5)(a0) 137 + REG_S s6, (KVM_ARCH_GUEST_S6)(a0) 138 + REG_S s7, (KVM_ARCH_GUEST_S7)(a0) 139 + REG_S s8, (KVM_ARCH_GUEST_S8)(a0) 140 + REG_S s9, (KVM_ARCH_GUEST_S9)(a0) 141 + REG_S s10, (KVM_ARCH_GUEST_S10)(a0) 142 + REG_S s11, (KVM_ARCH_GUEST_S11)(a0) 143 + REG_S t3, (KVM_ARCH_GUEST_T3)(a0) 144 + REG_S t4, (KVM_ARCH_GUEST_T4)(a0) 145 + REG_S t5, (KVM_ARCH_GUEST_T5)(a0) 146 + REG_S t6, (KVM_ARCH_GUEST_T6)(a0) 147 + 148 + /* Save Guest SEPC */ 149 + csrr t0, CSR_SEPC 150 + REG_S t0, (KVM_ARCH_GUEST_SEPC)(a0) 151 + 152 + /* Restore Host STVEC */ 153 + REG_L t1, (KVM_ARCH_HOST_STVEC)(a0) 154 + csrw CSR_STVEC, t1 155 + 156 + /* Save Guest A0 and Restore Host SSCRATCH */ 157 + REG_L t2, (KVM_ARCH_HOST_SSCRATCH)(a0) 158 + csrrw t2, CSR_SSCRATCH, t2 159 + REG_S t2, (KVM_ARCH_GUEST_A0)(a0) 160 + 161 + /* Save Guest and Restore Host SCOUNTEREN */ 162 + REG_L t3, (KVM_ARCH_HOST_SCOUNTEREN)(a0) 163 + csrrw t3, CSR_SCOUNTEREN, t3 164 + REG_S t3, (KVM_ARCH_GUEST_SCOUNTEREN)(a0) 165 + 166 + /* Save Guest and Restore Host HSTATUS */ 167 + REG_L t4, (KVM_ARCH_HOST_HSTATUS)(a0) 168 + csrrw t4, CSR_HSTATUS, t4 169 + REG_S t4, (KVM_ARCH_GUEST_HSTATUS)(a0) 170 + 171 + /* Save Guest and Restore Host SSTATUS */ 172 + REG_L t5, (KVM_ARCH_HOST_SSTATUS)(a0) 173 + csrrw t5, CSR_SSTATUS, t5 174 + REG_S t5, (KVM_ARCH_GUEST_SSTATUS)(a0) 175 + 176 + /* Restore Host GPRs (except A0 and T0-T6) */ 177 + REG_L ra, (KVM_ARCH_HOST_RA)(a0) 178 + REG_L sp, (KVM_ARCH_HOST_SP)(a0) 179 + REG_L gp, (KVM_ARCH_HOST_GP)(a0) 180 + REG_L tp, (KVM_ARCH_HOST_TP)(a0) 181 + REG_L s0, (KVM_ARCH_HOST_S0)(a0) 182 + REG_L s1, (KVM_ARCH_HOST_S1)(a0) 183 + REG_L a1, (KVM_ARCH_HOST_A1)(a0) 184 + REG_L a2, (KVM_ARCH_HOST_A2)(a0) 185 + REG_L a3, (KVM_ARCH_HOST_A3)(a0) 186 + REG_L a4, (KVM_ARCH_HOST_A4)(a0) 187 + REG_L a5, (KVM_ARCH_HOST_A5)(a0) 188 + REG_L a6, (KVM_ARCH_HOST_A6)(a0) 189 + REG_L a7, (KVM_ARCH_HOST_A7)(a0) 190 + REG_L s2, (KVM_ARCH_HOST_S2)(a0) 191 + REG_L s3, (KVM_ARCH_HOST_S3)(a0) 192 + REG_L s4, (KVM_ARCH_HOST_S4)(a0) 193 + REG_L s5, (KVM_ARCH_HOST_S5)(a0) 194 + REG_L s6, (KVM_ARCH_HOST_S6)(a0) 195 + REG_L s7, (KVM_ARCH_HOST_S7)(a0) 196 + REG_L s8, (KVM_ARCH_HOST_S8)(a0) 197 + REG_L s9, (KVM_ARCH_HOST_S9)(a0) 198 + REG_L s10, (KVM_ARCH_HOST_S10)(a0) 199 + REG_L s11, (KVM_ARCH_HOST_S11)(a0) 200 + 201 + /* Return to C code */ 202 + ret 203 + ENDPROC(__kvm_riscv_switch_to)