Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp18883908rwd; Wed, 28 Jun 2023 01:55:02 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6DctQA7QikUZG4cg0ZGBzC/ScbrXOi0ckdDBWyXLcfe0/2KzEGgRIwstVj0rcuImRoEVNS X-Received: by 2002:aa7:d614:0:b0:51d:b89d:9819 with SMTP id c20-20020aa7d614000000b0051db89d9819mr1346380edr.1.1687942502682; Wed, 28 Jun 2023 01:55:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1687942502; cv=none; d=google.com; s=arc-20160816; b=poLpV98RQ1gYm5fSkVjXkqp2Lpk5otvgYRABCz9F7a6VOHw4FYxWHFINawOv5AK9gy /epv94d4mv24ivfoSjgB5yV6VtyXPI7JR9JdB+VTNADwvnXBLz6XSFbgB0dWwSgkrRBB zuaIr02cr8IYk1/yB1nYcKiUzYiTD0liATek0kC8CzFkEHJwErqSa/RLac9Ye4gANw5R n1oUuAZBXe9EqJfX4fWht+iqIa467QKhTOZyzHVfqDw6tmoQYJZWBbJOWG/rwK7UWkx1 Zny6s5uf+Q0wkrtaJDvqYvTaw2hGvgANURBHyCDBapPCmePt6CHTjXtFsmKU9UOgm7I4 3z3Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-language:content-transfer-encoding :in-reply-to:mime-version:user-agent:date:message-id:from:references :cc:to:subject; bh=f25eIoRLpi6pxoTx4mCOnNR8Vo/a/usUMltVndw7758=; fh=+jRsA19VzTOXFDXgvnPrMHA6Wr6+dQxFs7FER4+Wxwg=; b=WtViaQ2yHK4w0wXglvL+o4dTCzaE/v+lRvUpD/nX0IPGewipnrXJYu+cExesVmr4wP SVjU3+r5Xa3bEYJJQb32la6182ShvZlXuKM8YOug/0Jr5niP6cak0CI97qJBhIhVxykg 3jlpAtlDTajvzezjdQ+1o9uQMSOIAzrnJ+IF1rCPHorq0E5jR+tbSlp72zpkYa8Oogvu cvcBuNo10M8E68fwhGLyTVfv22r1Mv1ZhxoZ7DiT4AA2o2urImkplxtzs8jjHrmhVfSQ dB74nGbS3vkVW7j9yDoIKZ8JdVVaLmBm8d89PNjWVQRWnm0UltaMjZWSDtdhcnGi2RYJ 3Vog== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id l4-20020a056402124400b0051bec407311si1362780edw.176.2023.06.28.01.54.38; Wed, 28 Jun 2023 01:55:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230409AbjF1Dmz (ORCPT + 99 others); Tue, 27 Jun 2023 23:42:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229892AbjF1Dmx (ORCPT ); Tue, 27 Jun 2023 23:42:53 -0400 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 2CDAC2D74; Tue, 27 Jun 2023 20:42:49 -0700 (PDT) Received: from loongson.cn (unknown [111.9.175.10]) by gateway (Coremail) with SMTP id _____8AxhMQ4rJtkwFYDAA--.5485S3; Wed, 28 Jun 2023 11:42:48 +0800 (CST) Received: from [10.136.12.26] (unknown [111.9.175.10]) by localhost.localdomain (Coremail) with SMTP id AQAAf8AxzyM0rJtkm4sNAA--.11940S3; Wed, 28 Jun 2023 11:42:46 +0800 (CST) Subject: Re: [PATCH v15 27/30] LoongArch: KVM: Implement vcpu world switch To: Tianrui Zhao , linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , Huacai Chen , WANG Xuerui , Greg Kroah-Hartman , loongarch@lists.linux.dev, Jens Axboe , Mark Brown , Alex Deucher , Oliver Upton , maobibo@loongson.cn, Xi Ruoyao , tangyouling@loongson.cn References: <20230626084752.1138621-1-zhaotianrui@loongson.cn> <20230626084752.1138621-28-zhaotianrui@loongson.cn> From: Jinyang He Message-ID: Date: Wed, 28 Jun 2023 11:42:44 +0800 User-Agent: Mozilla/5.0 (X11; Linux loongarch64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <20230626084752.1138621-28-zhaotianrui@loongson.cn> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-Language: en-US X-CM-TRANSID: AQAAf8AxzyM0rJtkm4sNAA--.11940S3 X-CM-SenderInfo: pkhmx0p1dqwqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBj93XoW3Cw18Kw4xXr17Ary5ZFW7KFX_yoWkKr13pr 9xArsYv3yj9Fn5uFs7tFyj9r13XFWxXrWagwnrGFs5AryDWFyvq3WvkFn8GFyUAw18XFnY qF9Ykw48CFWDA3cCm3ZEXasCq-sJn29KB7ZKAUJUUUUf529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUP2b4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1Y6r17M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Gr0_Xr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv6xkF7I0E14v2 6r4UJVWxJr1ln4kS14v26r126r1DM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12 xvs2x26I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r12 6r1DMcIj6I8E87Iv67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IY64vIr4 1lc7I2V7IY0VAS07AlzVAYIcxG8wCY1x0262kKe7AKxVWUAVWUtwCF04k20xvY0x0EwIxG rwCFx2IqxVCFs4IE7xkEbVWUJVW8JwCFI7km07C267AKxVWUAVWUtwC20s026c02F40E14 v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkG c2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvEc7CjxVAFwI 0_Jr0_Gr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4U MIIF0xvEx4A2jsIEc7CjxVAFwI0_Jr0_GrUvcSsGvfC2KfnxnUUI43ZEXa7IU8uc_3UUUU U== X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,NICE_REPLY_A, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2023-06-26 16:47, Tianrui Zhao wrote: > Implement LoongArch vcpu world switch, including vcpu enter guest and > vcpu exit from guest, both operations need to save or restore the host > and guest registers. > > Reviewed-by: Bibo Mao > Signed-off-by: Tianrui Zhao > --- > arch/loongarch/kernel/asm-offsets.c | 32 +++ > arch/loongarch/kvm/switch.S | 299 ++++++++++++++++++++++++++++ > 2 files changed, 331 insertions(+) > create mode 100644 arch/loongarch/kvm/switch.S > > diff --git a/arch/loongarch/kernel/asm-offsets.c b/arch/loongarch/kernel/asm-offsets.c > index 4bdb203fc66e..cb6c5a5afea9 100644 > --- a/arch/loongarch/kernel/asm-offsets.c > +++ b/arch/loongarch/kernel/asm-offsets.c > @@ -9,6 +9,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -272,3 +273,34 @@ void output_pbe_defines(void) > BLANK(); > } > #endif > + > +static void __used output_kvm_defines(void) > +{ > + COMMENT(" KVM/LOONGARCH Specific offsets. "); > + > + OFFSET(VCPU_FCSR0, kvm_vcpu_arch, fpu.fcsr); > + OFFSET(VCPU_FCC, kvm_vcpu_arch, fpu.fcc); > + BLANK(); > + > + OFFSET(KVM_VCPU_ARCH, kvm_vcpu, arch); > + OFFSET(KVM_VCPU_KVM, kvm_vcpu, kvm); > + OFFSET(KVM_VCPU_RUN, kvm_vcpu, run); > + BLANK(); > + > + OFFSET(KVM_ARCH_HSP, kvm_vcpu_arch, host_sp); > + OFFSET(KVM_ARCH_HTP, kvm_vcpu_arch, host_tp); > + OFFSET(KVM_ARCH_HANDLE_EXIT, kvm_vcpu_arch, handle_exit); > + OFFSET(KVM_ARCH_HPGD, kvm_vcpu_arch, host_pgd); > + OFFSET(KVM_ARCH_GEENTRY, kvm_vcpu_arch, guest_eentry); > + OFFSET(KVM_ARCH_GPC, kvm_vcpu_arch, pc); > + OFFSET(KVM_ARCH_GGPR, kvm_vcpu_arch, gprs); > + OFFSET(KVM_ARCH_HESTAT, kvm_vcpu_arch, host_estat); > + OFFSET(KVM_ARCH_HBADV, kvm_vcpu_arch, badv); > + OFFSET(KVM_ARCH_HBADI, kvm_vcpu_arch, badi); > + OFFSET(KVM_ARCH_HECFG, kvm_vcpu_arch, host_ecfg); > + OFFSET(KVM_ARCH_HEENTRY, kvm_vcpu_arch, host_eentry); > + OFFSET(KVM_ARCH_HPERCPU, kvm_vcpu_arch, host_percpu); > + > + OFFSET(KVM_GPGD, kvm, arch.gpa_mm.pgd); > + BLANK(); > +} > diff --git a/arch/loongarch/kvm/switch.S b/arch/loongarch/kvm/switch.S > new file mode 100644 > index 000000000000..7e55976c6fec > --- /dev/null > +++ b/arch/loongarch/kvm/switch.S > @@ -0,0 +1,299 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2020-2023 Loongson Technology Corporation Limited > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define PT_GPR_OFFSET(x) (PT_R0 + 8*x) > + .text The .text is redundant, you also marked it later. > + > +.macro kvm_save_host_gpr base > + .irp n,1,2,3,22,23,24,25,26,27,28,29,30,31 > + st.d $r\n, \base, PT_GPR_OFFSET(\n) > + .endr > +.endm > + > +.macro kvm_restore_host_gpr base > + .irp n,1,2,3,22,23,24,25,26,27,28,29,30,31 > + ld.d $r\n, \base, PT_GPR_OFFSET(\n) > + .endr > +.endm > + > +/* > + * prepare switch to guest, save host reg and restore guest reg. > + * a2: kvm_vcpu_arch, don't touch it until 'ertn' > + * t0, t1: temp register > + */ > +.macro kvm_switch_to_guest > + /* set host excfg.VS=0, all exceptions share one exception entry */ > + csrrd t0, LOONGARCH_CSR_ECFG > + bstrins.w t0, zero, CSR_ECFG_VS_SHIFT_END, CSR_ECFG_VS_SHIFT > + csrwr t0, LOONGARCH_CSR_ECFG > + > + /* Load up the new EENTRY */ > + ld.d t0, a2, KVM_ARCH_GEENTRY > + csrwr t0, LOONGARCH_CSR_EENTRY > + > + /* Set Guest ERA */ > + ld.d t0, a2, KVM_ARCH_GPC > + csrwr t0, LOONGARCH_CSR_ERA > + > + /* Save host PGDL */ > + csrrd t0, LOONGARCH_CSR_PGDL > + st.d t0, a2, KVM_ARCH_HPGD > + > + /* Switch to kvm */ > + ld.d t1, a2, KVM_VCPU_KVM - KVM_VCPU_ARCH > + > + /* Load guest PGDL */ > + lu12i.w t0, KVM_GPGD > + srli.w t0, t0, 12 I think the "lu12i.w+srli.w" can be replaced by "li.w t0, KVM_GPGD" . > + ldx.d t0, t1, t0 > + csrwr t0, LOONGARCH_CSR_PGDL > + > + /* Mix GID and RID */ > + csrrd t1, LOONGARCH_CSR_GSTAT > + bstrpick.w t1, t1, CSR_GSTAT_GID_SHIFT_END, CSR_GSTAT_GID_SHIFT > + csrrd t0, LOONGARCH_CSR_GTLBC > + bstrins.w t0, t1, CSR_GTLBC_TGID_SHIFT_END, CSR_GTLBC_TGID_SHIFT > + csrwr t0, LOONGARCH_CSR_GTLBC > + > + /* > + * Switch to guest: > + * GSTAT.PGM = 1, ERRCTL.ISERR = 0, TLBRPRMD.ISTLBR = 0 > + * ertn > + */ > + > + /* > + * Enable intr in root mode with future ertn so that host interrupt > + * can be responsed during VM runs > + * guest crmd comes from separate gcsr_CRMD register > + */ > + ori t0, zero, CSR_PRMD_PIE li.w t0, CSR_PRMD_PIE > + csrxchg t0, t0, LOONGARCH_CSR_PRMD > + > + /* Set PVM bit to setup ertn to guest context */ > + ori t0, zero, CSR_GSTAT_PVM li.w t0, ... > + csrxchg t0, t0, LOONGARCH_CSR_GSTAT > + > + /* Load Guest gprs */ > + ld.d ra, a2, (KVM_ARCH_GGPR + 8 * REG_RA) > + ld.d tp, a2, (KVM_ARCH_GGPR + 8 * REG_TP) > + ld.d sp, a2, (KVM_ARCH_GGPR + 8 * REG_SP) > + ld.d a0, a2, (KVM_ARCH_GGPR + 8 * REG_A0) > + ld.d a1, a2, (KVM_ARCH_GGPR + 8 * REG_A1) > + ld.d a3, a2, (KVM_ARCH_GGPR + 8 * REG_A3) > + ld.d a4, a2, (KVM_ARCH_GGPR + 8 * REG_A4) > + ld.d a5, a2, (KVM_ARCH_GGPR + 8 * REG_A5) > + ld.d a6, a2, (KVM_ARCH_GGPR + 8 * REG_A6) > + ld.d a7, a2, (KVM_ARCH_GGPR + 8 * REG_A7) > + ld.d t0, a2, (KVM_ARCH_GGPR + 8 * REG_T0) > + ld.d t1, a2, (KVM_ARCH_GGPR + 8 * REG_T1) > + ld.d t2, a2, (KVM_ARCH_GGPR + 8 * REG_T2) > + ld.d t3, a2, (KVM_ARCH_GGPR + 8 * REG_T3) > + ld.d t4, a2, (KVM_ARCH_GGPR + 8 * REG_T4) > + ld.d t5, a2, (KVM_ARCH_GGPR + 8 * REG_T5) > + ld.d t6, a2, (KVM_ARCH_GGPR + 8 * REG_T6) > + ld.d t7, a2, (KVM_ARCH_GGPR + 8 * REG_T7) > + ld.d t8, a2, (KVM_ARCH_GGPR + 8 * REG_T8) > + ld.d u0, a2, (KVM_ARCH_GGPR + 8 * REG_U0) > + ld.d fp, a2, (KVM_ARCH_GGPR + 8 * REG_FP) > + ld.d s0, a2, (KVM_ARCH_GGPR + 8 * REG_S0) > + ld.d s1, a2, (KVM_ARCH_GGPR + 8 * REG_S1) > + ld.d s2, a2, (KVM_ARCH_GGPR + 8 * REG_S2) > + ld.d s3, a2, (KVM_ARCH_GGPR + 8 * REG_S3) > + ld.d s4, a2, (KVM_ARCH_GGPR + 8 * REG_S4) > + ld.d s5, a2, (KVM_ARCH_GGPR + 8 * REG_S5) > + ld.d s6, a2, (KVM_ARCH_GGPR + 8 * REG_S6) > + ld.d s7, a2, (KVM_ARCH_GGPR + 8 * REG_S7) > + ld.d s8, a2, (KVM_ARCH_GGPR + 8 * REG_S8) Why not use .irp which like kvm_save/restore_host_gpr do here? > + /* Load KVM_ARCH register */ > + ld.d a2, a2, (KVM_ARCH_GGPR + 8 * REG_A2) > + > + ertn > +.endm > + > + /* > + * exception entry for general exception from guest mode > + * - IRQ is disabled > + * - kernel privilege in root mode > + * - page mode keep unchanged from previous prmd in root mode > + * - Fixme: tlb exception cannot happen since registers relative with TLB > + * - is still in guest mode, such as pgd table/vmid registers etc, > + * - will fix with hw page walk enabled in future > + * load kvm_vcpu from reserved CSR KVM_VCPU_KS, and save a2 to KVM_TEMP_KS > + */ > + .section .text here. > + .cfi_sections .debug_frame > +SYM_CODE_START(kvm_vector_entry) > + csrwr a2, KVM_TEMP_KS > + csrrd a2, KVM_VCPU_KS > + addi.d a2, a2, KVM_VCPU_ARCH > + > + /* After save gprs, free to use any gpr */ > + st.d ra, a2, (KVM_ARCH_GGPR + 8 * REG_RA) > + st.d tp, a2, (KVM_ARCH_GGPR + 8 * REG_TP) > + st.d sp, a2, (KVM_ARCH_GGPR + 8 * REG_SP) > + st.d a0, a2, (KVM_ARCH_GGPR + 8 * REG_A0) > + st.d a1, a2, (KVM_ARCH_GGPR + 8 * REG_A1) > + st.d a3, a2, (KVM_ARCH_GGPR + 8 * REG_A3) > + st.d a4, a2, (KVM_ARCH_GGPR + 8 * REG_A4) > + st.d a5, a2, (KVM_ARCH_GGPR + 8 * REG_A5) > + st.d a6, a2, (KVM_ARCH_GGPR + 8 * REG_A6) > + st.d a7, a2, (KVM_ARCH_GGPR + 8 * REG_A7) > + st.d t0, a2, (KVM_ARCH_GGPR + 8 * REG_T0) > + st.d t1, a2, (KVM_ARCH_GGPR + 8 * REG_T1) > + st.d t2, a2, (KVM_ARCH_GGPR + 8 * REG_T2) > + st.d t3, a2, (KVM_ARCH_GGPR + 8 * REG_T3) > + st.d t4, a2, (KVM_ARCH_GGPR + 8 * REG_T4) > + st.d t5, a2, (KVM_ARCH_GGPR + 8 * REG_T5) > + st.d t6, a2, (KVM_ARCH_GGPR + 8 * REG_T6) > + st.d t7, a2, (KVM_ARCH_GGPR + 8 * REG_T7) > + st.d t8, a2, (KVM_ARCH_GGPR + 8 * REG_T8) > + st.d u0, a2, (KVM_ARCH_GGPR + 8 * REG_U0) > + st.d fp, a2, (KVM_ARCH_GGPR + 8 * REG_FP) > + st.d s0, a2, (KVM_ARCH_GGPR + 8 * REG_S0) > + st.d s1, a2, (KVM_ARCH_GGPR + 8 * REG_S1) > + st.d s2, a2, (KVM_ARCH_GGPR + 8 * REG_S2) > + st.d s3, a2, (KVM_ARCH_GGPR + 8 * REG_S3) > + st.d s4, a2, (KVM_ARCH_GGPR + 8 * REG_S4) > + st.d s5, a2, (KVM_ARCH_GGPR + 8 * REG_S5) > + st.d s6, a2, (KVM_ARCH_GGPR + 8 * REG_S6) > + st.d s7, a2, (KVM_ARCH_GGPR + 8 * REG_S7) > + st.d s8, a2, (KVM_ARCH_GGPR + 8 * REG_S8) Why not .irp ... ? > + /* Save guest a2 */ > + csrrd t0, KVM_TEMP_KS > + st.d t0, a2, (KVM_ARCH_GGPR + 8 * REG_A2) > + > + /* a2: kvm_vcpu_arch, a1 is free to use */ > + csrrd s1, KVM_VCPU_KS > + ld.d s0, s1, KVM_VCPU_RUN > + > + csrrd t0, LOONGARCH_CSR_ESTAT > + st.d t0, a2, KVM_ARCH_HESTAT > + csrrd t0, LOONGARCH_CSR_ERA > + st.d t0, a2, KVM_ARCH_GPC > + csrrd t0, LOONGARCH_CSR_BADV > + st.d t0, a2, KVM_ARCH_HBADV > + csrrd t0, LOONGARCH_CSR_BADI > + st.d t0, a2, KVM_ARCH_HBADI > + > + /* Restore host excfg.VS */ > + csrrd t0, LOONGARCH_CSR_ECFG > + ld.d t1, a2, KVM_ARCH_HECFG > + or t0, t0, t1 > + csrwr t0, LOONGARCH_CSR_ECFG > + > + /* Restore host eentry */ > + ld.d t0, a2, KVM_ARCH_HEENTRY > + csrwr t0, LOONGARCH_CSR_EENTRY > + > + /* restore host pgd table */ > + ld.d t0, a2, KVM_ARCH_HPGD > + csrwr t0, LOONGARCH_CSR_PGDL > + > + /* > + * Disable PGM bit to enter root mode by default with next ertn > + */ > + ori t0, zero, CSR_GSTAT_PVM li.w > + csrxchg zero, t0, LOONGARCH_CSR_GSTAT > + /* > + * Clear GTLBC.TGID field > + * 0: for root tlb update in future tlb instr > + * others: for guest tlb update like gpa to hpa in future tlb instr > + */ > + csrrd t0, LOONGARCH_CSR_GTLBC > + bstrins.w t0, zero, CSR_GTLBC_TGID_SHIFT_END, CSR_GTLBC_TGID_SHIFT > + csrwr t0, LOONGARCH_CSR_GTLBC > + ld.d tp, a2, KVM_ARCH_HTP > + ld.d sp, a2, KVM_ARCH_HSP > + /* restore per cpu register */ > + ld.d u0, a2, KVM_ARCH_HPERCPU > + addi.d sp, sp, -PT_SIZE > + > + /* Prepare handle exception */ > + or a0, s0, zero move > + or a1, s1, zero move > + ld.d t8, a2, KVM_ARCH_HANDLE_EXIT > + jirl ra, t8, 0 > + > + or a2, s1, zero move > + addi.d a2, a2, KVM_VCPU_ARCH > + > + /* resume host when ret <= 0 */ > + bge zero, a0, ret_to_host blez a0, ret_to_host > + > + /* > + * return to guest > + * save per cpu register again, maybe switched to another cpu > + */ > + st.d u0, a2, KVM_ARCH_HPERCPU > + > + /* Save kvm_vcpu to kscratch */ > + csrwr s1, KVM_VCPU_KS > + kvm_switch_to_guest > + > +ret_to_host: > + ld.d a2, a2, KVM_ARCH_HSP > + addi.d a2, a2, -PT_SIZE > + kvm_restore_host_gpr a2 > + jr ra > +SYM_CODE_END(kvm_vector_entry) > +kvm_vector_entry_end: > + > +/* > + * int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu) > + * > + * @register_param: > + * a0: kvm_run* run > + * a1: kvm_vcpu* vcpu > + */ > +SYM_FUNC_START(kvm_enter_guest) > + /* allocate space in stack bottom */ > + addi.d a2, sp, -PT_SIZE > + /* save host gprs */ > + kvm_save_host_gpr a2 > + > + /* save host crmd,prmd csr to stack */ > + csrrd a3, LOONGARCH_CSR_CRMD > + st.d a3, a2, PT_CRMD > + csrrd a3, LOONGARCH_CSR_PRMD > + st.d a3, a2, PT_PRMD > + > + addi.d a2, a1, KVM_VCPU_ARCH > + st.d sp, a2, KVM_ARCH_HSP > + st.d tp, a2, KVM_ARCH_HTP > + /* Save per cpu register */ > + st.d u0, a2, KVM_ARCH_HPERCPU > + > + /* Save kvm_vcpu to kscratch */ > + csrwr a1, KVM_VCPU_KS > + kvm_switch_to_guest > +SYM_FUNC_END(kvm_enter_guest) > +kvm_enter_guest_end: > + > + .section ".rodata" > +SYM_DATA(kvm_vector_size, .quad kvm_vector_entry_end - kvm_vector_entry) > +SYM_DATA(kvm_enter_guest_size, .quad kvm_enter_guest_end - kvm_enter_guest) Not restore .text section. Although I'd like to use .pushsection ... .pop after marked kvm_..._end, you can put them after kvm_restore_fpu, too. Jinyang > + > + > +SYM_FUNC_START(kvm_save_fpu) > + fpu_save_csr a0 t1 > + fpu_save_double a0 t1 > + fpu_save_cc a0 t1 t2 > + jr ra > +SYM_FUNC_END(kvm_save_fpu) > + > +SYM_FUNC_START(kvm_restore_fpu) > + fpu_restore_double a0 t1 > + fpu_restore_csr a0 t1 > + fpu_restore_cc a0 t1 t2 > + jr ra > +SYM_FUNC_END(kvm_restore_fpu)