Received: by 2002:a05:7412:37c9:b0:e2:908c:2ebd with SMTP id jz9csp389684rdb; Mon, 18 Sep 2023 20:14:59 -0700 (PDT) X-Google-Smtp-Source: AGHT+IG2eEMgJxWr8FVxxwsnz4lR+oA89EYwTFM/60uMMFzBiUDtrNjMxnlYJn+Ttor+9Cf0ZonU X-Received: by 2002:a05:6808:2a71:b0:3a8:791d:9ce5 with SMTP id fu17-20020a0568082a7100b003a8791d9ce5mr10759560oib.19.1695093299064; Mon, 18 Sep 2023 20:14:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695093299; cv=none; d=google.com; s=arc-20160816; b=IlyD/2Q5fJg+haIrd25KXLcWPIMpLexPZQVwDUREx2I1EU2VMN4CW483mRoRY7agHy wYaIYm9LcQELRnkWkyuVc4SuqqDozU3dLiDD+WgNoCVRmODhJ+T7ixci1yMIJcO56tPi KylFeFGJMt9vI6vIX6tkGHXHUjA4NnMCUS8qXtdOMWPL2VzvNsWBpfaA1o9NaEVfc01f AuPR9whATgMDK7gAHpgHne+mQo8OV8ZUpuRjOocOFqSzQhQ1ij6IO3VgK/QO9ICRSiIb WQan0UPUJFEHQbH3OV0Ik+ydIRwufgLdiavhTqcw70ll9AiIESyqsRZOnQ1VGiOGmEcZ 2bZQ== 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=kO34rb3q3hgevhP1+3eNYbixEi+RH519RGe7lrxlUbg=; fh=E5kM9VnGCFXmMuJFClmYlZfZmpM/O/WLke8iGziKutc=; b=f6XESWCaWLPi7fluh6PK+mCi8PdDCmgruTwmB/rVqhJvJgJRS4YdJZaDJeSES1B4M7 yY1d25aJ2zbBPT3REaTVkVOFWHBYc7Q4HUtBSdpNzvG/zAGP97TNWaikliaQ/N3SWCil Kt7FIOdVpID3UrCcH4oF2sBNOM40yyl2vEMqZknahfS1eks7ZpQR1oPhndJVbJ6Zj/UA 49XIhN2VwmouAsKP2a0xdC13FAAmX3Mduz+XaH6OT+8dtWx2SZXh3XOHH68ogducQSdp ueDMhl7mNJ0CGQuHeOdqZzyn+vlik8Cb64kj2R99D3x4C6iK9KZmWEVzPMEBLzA5ruDn kA6g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id l62-20020a633e41000000b0056a8dc222f1si1348481pga.259.2023.09.18.20.14.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Sep 2023 20:14:59 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 91F6580FDDE4; Mon, 18 Sep 2023 20:13:41 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231256AbjISDNn (ORCPT + 99 others); Mon, 18 Sep 2023 23:13:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40752 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229522AbjISDNl (ORCPT ); Mon, 18 Sep 2023 23:13:41 -0400 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 5D0A710E; Mon, 18 Sep 2023 20:13:32 -0700 (PDT) Received: from loongson.cn (unknown [10.40.46.158]) by gateway (Coremail) with SMTP id _____8AxEvDZEQll7s0pAA--.13965S3; Tue, 19 Sep 2023 11:13:29 +0800 (CST) Received: from [192.168.124.126] (unknown [10.40.46.158]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Dxnd7WEQll2CcLAA--.24269S3; Tue, 19 Sep 2023 11:13:28 +0800 (CST) Subject: Re: [PATCH v21 02/29] LoongArch: KVM: Implement kvm module related interface To: Huacai Chen Cc: bibo mao , linux-kernel@vger.kernel.org, kvm@vger.kernel.org, Paolo Bonzini , WANG Xuerui , Greg Kroah-Hartman , loongarch@lists.linux.dev, Jens Axboe , Mark Brown , Alex Deucher , Oliver Upton , Xi Ruoyao References: <20230915014949.1222777-1-zhaotianrui@loongson.cn> <20230915014949.1222777-3-zhaotianrui@loongson.cn> <525aa9e2-1ebc-6c49-55ef-9f3c7d18d3e0@loongson.cn> <8e23325a-b4d3-db80-7d65-ebadcd3ef5a9@loongson.cn> <33da46a6-45ef-ffbe-f2b3-45a1b29eaa3d@loongson.cn> <35658917-c7d6-19ad-ea23-848a4ef00a97@loongson.cn> From: zhaotianrui Message-ID: Date: Tue, 19 Sep 2023 11:13:26 +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: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US X-CM-TRANSID: AQAAf8Dxnd7WEQll2CcLAA--.24269S3 X-CM-SenderInfo: p2kd03xldq233l6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBj9fXoWfXF43Wr18AFy5Jr1kWw1DCFX_yoW8Kr4rKo WrtF17JF1UJr1UJr4DG34DJay0yw15Gr4Yq34UJr15Jw1Utw13Zr15Cr1UJr45Wr1UAr1U Ja4qqF40vFW2gr15l-sFpf9Il3svdjkaLaAFLSUrUUUUnb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUOn7kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUXVWUAwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26r4j6ryUM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r4j6F4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Gr1j6F4UJwAaw2AFwI0_JF0_Jw1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2 xF0cIa020Ex4CE44I27wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_ JF0_Jw1lYx0Ex4A2jsIE14v26r4j6F4UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvEwI xGrwCYjI0SjxkI62AI1cAE67vIY487MxkF7I0En4kS14v26r126r1DMxAIw28IcxkI7VAK I48JMxC20s026xCaFVCjc4AY6r1j6r4UMxCIbckI1I0E14v26rWY6Fy7MI8I3I0E5I8CrV AFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCI c40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1I6r4UMIIF0xvE2Ix0cI8IcVCY1x0267 AKxVWUJVW8JwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Gr0_ Cr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7IU8uc_3 UUUUU== X-Spam-Status: No, score=-3.4 required=5.0 tests=BAYES_00,NICE_REPLY_A, SPF_HELO_NONE,SPF_PASS 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 X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Mon, 18 Sep 2023 20:13:41 -0700 (PDT) 在 2023/9/19 上午10:57, Huacai Chen 写道: > On Tue, Sep 19, 2023 at 10:53 AM zhaotianrui wrote: >> >> 在 2023/9/19 上午10:14, Huacai Chen 写道: >>> On Mon, Sep 18, 2023 at 4:39 PM bibo mao wrote: >>>> >>>> 在 2023/9/18 14:25, zhaotianrui 写道: >>>>> 在 2023/9/18 下午12:03, Huacai Chen 写道: >>>>>> On Mon, Sep 18, 2023 at 11:20 AM zhaotianrui wrote: >>>>>>> 在 2023/9/18 上午11:12, Huacai Chen 写道: >>>>>>>> On Mon, Sep 18, 2023 at 11:08 AM zhaotianrui wrote: >>>>>>>>> 在 2023/9/18 上午9:45, Huacai Chen 写道: >>>>>>>>>> On Mon, Sep 18, 2023 at 9:21 AM zhaotianrui wrote: >>>>>>>>>>> 在 2023/9/16 下午4:51, Huacai Chen 写道: >>>>>>>>>>>> Hi, Tianrui, >>>>>>>>>>>> >>>>>>>>>>>> On Fri, Sep 15, 2023 at 9:50 AM Tianrui Zhao wrote: >>>>>>>>>>>>> Implement LoongArch kvm module init, module exit interface, >>>>>>>>>>>>> using kvm context to save the vpid info and vcpu world switch >>>>>>>>>>>>> interface pointer. >>>>>>>>>>>>> >>>>>>>>>>>>> Reviewed-by: Bibo Mao >>>>>>>>>>>>> Signed-off-by: Tianrui Zhao >>>>>>>>>>>>> --- >>>>>>>>>>>>> arch/loongarch/kvm/main.c | 367 ++++++++++++++++++++++++++++++++++++++ >>>>>>>>>>>>> 1 file changed, 367 insertions(+) >>>>>>>>>>>>> create mode 100644 arch/loongarch/kvm/main.c >>>>>>>>>>>>> >>>>>>>>>>>>> diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c >>>>>>>>>>>>> new file mode 100644 >>>>>>>>>>>>> index 0000000000..0deb9273d8 >>>>>>>>>>>>> --- /dev/null >>>>>>>>>>>>> +++ b/arch/loongarch/kvm/main.c >>>>>>>>>>>>> @@ -0,0 +1,367 @@ >>>>>>>>>>>>> +// SPDX-License-Identifier: GPL-2.0 >>>>>>>>>>>>> +/* >>>>>>>>>>>>> + * Copyright (C) 2020-2023 Loongson Technology Corporation Limited >>>>>>>>>>>>> + */ >>>>>>>>>>>>> + >>>>>>>>>>>>> +#include >>>>>>>>>>>>> +#include >>>>>>>>>>>>> +#include >>>>>>>>>>>>> +#include >>>>>>>>>>>>> +#include >>>>>>>>>>>>> +#include >>>>>>>>>>>>> +#include "trace.h" >>>>>>>>>>>>> + >>>>>>>>>>>>> +static struct kvm_context __percpu *vmcs; >>>>>>>>>>>>> +struct kvm_world_switch *kvm_loongarch_ops; >>>>>>>>>>>>> +unsigned long vpid_mask; >>>>>>>>>>>>> +static int gcsr_flag[CSR_MAX_NUMS]; >>>>>>>>>>>>> + >>>>>>>>>>>>> +int get_gcsr_flag(int csr) >>>>>>>>>>>>> +{ >>>>>>>>>>>>> + if (csr < CSR_MAX_NUMS) >>>>>>>>>>>>> + return gcsr_flag[csr]; >>>>>>>>>>>>> + >>>>>>>>>>>>> + return INVALID_GCSR; >>>>>>>>>>>>> +} >>>>>>>>>>>>> + >>>>>>>>>>>>> +static inline void set_gcsr_sw_flag(int csr) >>>>>>>>>>>>> +{ >>>>>>>>>>>>> + if (csr < CSR_MAX_NUMS) >>>>>>>>>>>>> + gcsr_flag[csr] |= SW_GCSR; >>>>>>>>>>>>> +} >>>>>>>>>>>>> + >>>>>>>>>>>>> +static inline void set_gcsr_hw_flag(int csr) >>>>>>>>>>>>> +{ >>>>>>>>>>>>> + if (csr < CSR_MAX_NUMS) >>>>>>>>>>>>> + gcsr_flag[csr] |= HW_GCSR; >>>>>>>>>>>>> +} >>>>>>>>>>>>> + >>>>>>>>>>>>> +/* >>>>>>>>>>>>> + * The default value of gcsr_flag[CSR] is 0, and we use this >>>>>>>>>>>>> + * function to set the flag to 1(SW_GCSR) or 2(HW_GCSR) if the >>>>>>>>>>>>> + * gcsr is software or hardware. It will be used by get/set_gcsr, >>>>>>>>>>>>> + * if gcsr_flag is HW we should use gcsrrd/gcsrwr to access it, >>>>>>>>>>>>> + * else use sw csr to emulate it. >>>>>>>>>>>>> + */ >>>>>>>>>>>>> +static void kvm_init_gcsr_flag(void) >>>>>>>>>>>>> +{ >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_CRMD); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_PRMD); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_EUEN); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_MISC); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_ECFG); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_ESTAT); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_ERA); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_BADV); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_BADI); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_EENTRY); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TLBIDX); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TLBEHI); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TLBELO0); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TLBELO1); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_ASID); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_PGDL); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_PGDH); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_PWCTL0); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_PWCTL1); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_STLBPGSIZE); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_RVACFG); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_CPUID); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_PRCFG1); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_PRCFG2); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_PRCFG3); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_KS0); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_KS1); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_KS2); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_KS3); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_KS4); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_KS5); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_KS6); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_KS7); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TMID); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TCFG); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TVAL); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_CNTC); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_LLBCTL); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TLBRENTRY); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TLBRBADV); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TLBRERA); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TLBRSAVE); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TLBRELO0); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TLBRELO1); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TLBREHI); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_TLBRPRMD); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_DMWIN0); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_DMWIN1); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_DMWIN2); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_DMWIN3); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_MWPS); >>>>>>>>>>>>> + set_gcsr_hw_flag(LOONGARCH_CSR_FWPS); >>>>>>>>>>>>> + >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IMPCTL1); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IMPCTL2); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_MERRCTL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_MERRINFO1); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_MERRINFO2); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_MERRENTRY); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_MERRERA); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_MERRSAVE); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_CTAG); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DEBUG); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DERA); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DESAVE); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_PRCFG1); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_PRCFG2); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_PRCFG3); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_PGD); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_TINTCLR); >>>>>>>>>>>>> + >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_FWPS); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_FWPC); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_MWPS); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_MWPC); >>>>>>>>>>>> FWPS and MWPS are both HW CSR and SW CSR? >>>>>>>>>>>> >>>>>>>>>>>> Huacai >>>>>>>>>>> The FWPC and MWPC should be SW GCSR, FWPS and MWPS should be HW GCSR, it >>>>>>>>>>> is my mistake. >>>>>>>>>> But in user manual vol 3, section 1.5, FWPC/FWPS/MWPC/MWPS are all HW >>>>>>>>>> GCSR, while DBxxxx and IBxxxx are SW GCSR. >>>>>>>>> Ok, It is my misunderstanding, as the FWPC and MWPC can control guest >>>>>>>>> debug register numbers, but I know they are all HW GCSR when I look up >>>>>>>>> the manual again. >>>>>>>> So these lines can be removed? >>>>>>>> >>>>>>>> set_gcsr_sw_flag(LOONGARCH_CSR_FWPS); >>>>>>>> set_gcsr_sw_flag(LOONGARCH_CSR_FWPC); >>>>>>>> set_gcsr_sw_flag(LOONGARCH_CSR_MWPS); >>>>>>>> set_gcsr_sw_flag(LOONGARCH_CSR_MWPC); >>>>>>>> >>>>>>>> And add FWPC/MWPC to hw list? >>>>>> Can you discuss more with our hw engineers? I found in section 1.8: >>>>>> PGD, TINTCLR, PRCFG1~3 are all HW GCSR. >>>>> If guest can access hw CSR directly and do not cause a exception, it means hw GCSR. on the other hand, if cause a exception to return to KVM to emulate it by software, it means SW GCSR. And I re-check the PGD, TINTCLR, PRCFG1~3 CSR, they should be hw GCSR. >>>> CSR_PGD is logical read only register instead, its content is the same >>>> CSR_PGDL if highest bit of BADV is 0, else its content is the same with >>>> CSR_PGDH. >>>> >>>> TINTCLR is write only register, write 1 to clear timer interrupt and read >>>> value is 0. >>>> >>>> So CSR_PGD and TINTCLR need not save and restore during vcpu switching or >>>> vm migration, it is not necessary to set CSR_PGD/TINTCLR from qemu user space. >>>> >>>> PRCFG1~3 is read only registers, it is decided by hardware and can not be >>>> set by kvm, it is not necessary to save or retore. However there maybe brings >>>> problems for vm migration on diferent hardwares if PRCFG1~3 is different. >>> During my tests, reading FWPC/FWPS/MWPC/MWPS causes guest exit, but >>> user manual vol 3 says they are HW GCSR, who can tell me why? >> It will cause guest exiting when guest visit these registers above for >> the first time, and KVM could config FWPC, MWPC to enable the debug >> registers for guest, so that it will not cause exiting at next time. And >> we will add this handling later when we want to use this function in guest. > Then what type should we mark them? HW GCSR or SW GCSR? > > Huacai It should be marked by SW GCSR at the initial time in this function, and when guest visit it, we should change the flag to HW GCSR. Thanks Tianrui Zhao > >> Thanks >> Tianrui Zhao >>> Huacai >>> >>>> Regards >>>> Bibo Mao >>>>> Thanks >>>>> Tianrui Zhao >>>>>> Huacai >>>>>> >>>>>>>> Huacai >>>>>>> Yes, It is. >>>>>>> >>>>>>> Thanks >>>>>>> Tianrui Zhao >>>>>>>>> Thanks >>>>>>>>> Tianrui Zhao >>>>>>>>>> Huacai >>>>>>>>>> >>>>>>>>>>> Thanks >>>>>>>>>>> Tianrui Zhao >>>>>>>>>>>>> + >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB0ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB0MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB0CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB0ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB1ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB1MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB1CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB1ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB2ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB2MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB2CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB2ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB3ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB3MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB3CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB3ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB4ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB4MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB4CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB4ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB5ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB5MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB5CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB5ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB6ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB6MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB6CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB6ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB7ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB7MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB7CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_DB7ASID); >>>>>>>>>>>>> + >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB0ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB0MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB0CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB0ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB1ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB1MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB1CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB1ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB2ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB2MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB2CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB2ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB3ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB3MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB3CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB3ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB4ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB4MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB4CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB4ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB5ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB5MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB5CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB5ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB6ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB6MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB6CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB6ASID); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB7ADDR); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB7MASK); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB7CTRL); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_IB7ASID); >>>>>>>>>>>>> + >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_PERFCTRL0); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_PERFCNTR0); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_PERFCTRL1); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_PERFCNTR1); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_PERFCTRL2); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_PERFCNTR2); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_PERFCTRL3); >>>>>>>>>>>>> + set_gcsr_sw_flag(LOONGARCH_CSR_PERFCNTR3); >>>>>>>>>>>>> +} >>>>>>>>>>>>> + >>>>>>>>>>>>> +static void kvm_update_vpid(struct kvm_vcpu *vcpu, int cpu) >>>>>>>>>>>>> +{ >>>>>>>>>>>>> + struct kvm_context *context; >>>>>>>>>>>>> + unsigned long vpid; >>>>>>>>>>>>> + >>>>>>>>>>>>> + context = per_cpu_ptr(vcpu->kvm->arch.vmcs, cpu); >>>>>>>>>>>>> + vpid = context->vpid_cache + 1; >>>>>>>>>>>>> + if (!(vpid & vpid_mask)) { >>>>>>>>>>>>> + /* finish round of 64 bit loop */ >>>>>>>>>>>>> + if (unlikely(!vpid)) >>>>>>>>>>>>> + vpid = vpid_mask + 1; >>>>>>>>>>>>> + >>>>>>>>>>>>> + /* vpid 0 reserved for root */ >>>>>>>>>>>>> + ++vpid; >>>>>>>>>>>>> + >>>>>>>>>>>>> + /* start new vpid cycle */ >>>>>>>>>>>>> + kvm_flush_tlb_all(); >>>>>>>>>>>>> + } >>>>>>>>>>>>> + >>>>>>>>>>>>> + context->vpid_cache = vpid; >>>>>>>>>>>>> + vcpu->arch.vpid = vpid; >>>>>>>>>>>>> +} >>>>>>>>>>>>> + >>>>>>>>>>>>> +void kvm_check_vpid(struct kvm_vcpu *vcpu) >>>>>>>>>>>>> +{ >>>>>>>>>>>>> + struct kvm_context *context; >>>>>>>>>>>>> + bool migrated; >>>>>>>>>>>>> + unsigned long ver, old, vpid; >>>>>>>>>>>>> + int cpu; >>>>>>>>>>>>> + >>>>>>>>>>>>> + cpu = smp_processor_id(); >>>>>>>>>>>>> + /* >>>>>>>>>>>>> + * Are we entering guest context on a different CPU to last time? >>>>>>>>>>>>> + * If so, the vCPU's guest TLB state on this CPU may be stale. >>>>>>>>>>>>> + */ >>>>>>>>>>>>> + context = per_cpu_ptr(vcpu->kvm->arch.vmcs, cpu); >>>>>>>>>>>>> + migrated = (vcpu->cpu != cpu); >>>>>>>>>>>>> + >>>>>>>>>>>>> + /* >>>>>>>>>>>>> + * Check if our vpid is of an older version >>>>>>>>>>>>> + * >>>>>>>>>>>>> + * We also discard the stored vpid if we've executed on >>>>>>>>>>>>> + * another CPU, as the guest mappings may have changed without >>>>>>>>>>>>> + * hypervisor knowledge. >>>>>>>>>>>>> + */ >>>>>>>>>>>>> + ver = vcpu->arch.vpid & ~vpid_mask; >>>>>>>>>>>>> + old = context->vpid_cache & ~vpid_mask; >>>>>>>>>>>>> + if (migrated || (ver != old)) { >>>>>>>>>>>>> + kvm_update_vpid(vcpu, cpu); >>>>>>>>>>>>> + trace_kvm_vpid_change(vcpu, vcpu->arch.vpid); >>>>>>>>>>>>> + vcpu->cpu = cpu; >>>>>>>>>>>>> + } >>>>>>>>>>>>> + >>>>>>>>>>>>> + /* Restore GSTAT(0x50).vpid */ >>>>>>>>>>>>> + vpid = (vcpu->arch.vpid & vpid_mask) << CSR_GSTAT_GID_SHIFT; >>>>>>>>>>>>> + change_csr_gstat(vpid_mask << CSR_GSTAT_GID_SHIFT, vpid); >>>>>>>>>>>>> +} >>>>>>>>>>>>> + >>>>>>>>>>>>> +static int kvm_loongarch_env_init(void) >>>>>>>>>>>>> +{ >>>>>>>>>>>>> + struct kvm_context *context; >>>>>>>>>>>>> + int cpu, order; >>>>>>>>>>>>> + void *addr; >>>>>>>>>>>>> + >>>>>>>>>>>>> + vmcs = alloc_percpu(struct kvm_context); >>>>>>>>>>>>> + if (!vmcs) { >>>>>>>>>>>>> + pr_err("kvm: failed to allocate percpu kvm_context\n"); >>>>>>>>>>>>> + return -ENOMEM; >>>>>>>>>>>>> + } >>>>>>>>>>>>> + >>>>>>>>>>>>> + kvm_loongarch_ops = kzalloc(sizeof(*kvm_loongarch_ops), GFP_KERNEL); >>>>>>>>>>>>> + if (!kvm_loongarch_ops) { >>>>>>>>>>>>> + free_percpu(vmcs); >>>>>>>>>>>>> + vmcs = NULL; >>>>>>>>>>>>> + return -ENOMEM; >>>>>>>>>>>>> + } >>>>>>>>>>>>> + /* >>>>>>>>>>>>> + * There will be problem in world switch code if there >>>>>>>>>>>>> + * is page fault reenter, since pgd register is shared >>>>>>>>>>>>> + * between root kernel and kvm hypervisor. World switch >>>>>>>>>>>>> + * entry need be unmapped area, cannot be tlb mapped area. >>>>>>>>>>>>> + * In future if hw pagetable walking is supported, or there >>>>>>>>>>>>> + * is separate pgd registers between root kernel and kvm >>>>>>>>>>>>> + * hypervisor, copying about world switch code will not be used. >>>>>>>>>>>>> + */ >>>>>>>>>>>>> + >>>>>>>>>>>>> + order = get_order(kvm_vector_size + kvm_enter_guest_size); >>>>>>>>>>>>> + addr = (void *)__get_free_pages(GFP_KERNEL, order); >>>>>>>>>>>>> + if (!addr) { >>>>>>>>>>>>> + free_percpu(vmcs); >>>>>>>>>>>>> + vmcs = NULL; >>>>>>>>>>>>> + kfree(kvm_loongarch_ops); >>>>>>>>>>>>> + kvm_loongarch_ops = NULL; >>>>>>>>>>>>> + return -ENOMEM; >>>>>>>>>>>>> + } >>>>>>>>>>>>> + >>>>>>>>>>>>> + memcpy(addr, kvm_vector_entry, kvm_vector_size); >>>>>>>>>>>>> + memcpy(addr + kvm_vector_size, kvm_enter_guest, kvm_enter_guest_size); >>>>>>>>>>>>> + flush_icache_range((unsigned long)addr, (unsigned long)addr + >>>>>>>>>>>>> + kvm_vector_size + kvm_enter_guest_size); >>>>>>>>>>>>> + kvm_loongarch_ops->guest_eentry = addr; >>>>>>>>>>>>> + kvm_loongarch_ops->enter_guest = addr + kvm_vector_size; >>>>>>>>>>>>> + kvm_loongarch_ops->page_order = order; >>>>>>>>>>>>> + >>>>>>>>>>>>> + vpid_mask = read_csr_gstat(); >>>>>>>>>>>>> + vpid_mask = (vpid_mask & CSR_GSTAT_GIDBIT) >> CSR_GSTAT_GIDBIT_SHIFT; >>>>>>>>>>>>> + if (vpid_mask) >>>>>>>>>>>>> + vpid_mask = GENMASK(vpid_mask - 1, 0); >>>>>>>>>>>>> + >>>>>>>>>>>>> + for_each_possible_cpu(cpu) { >>>>>>>>>>>>> + context = per_cpu_ptr(vmcs, cpu); >>>>>>>>>>>>> + context->vpid_cache = vpid_mask + 1; >>>>>>>>>>>>> + context->last_vcpu = NULL; >>>>>>>>>>>>> + } >>>>>>>>>>>>> + >>>>>>>>>>>>> + kvm_init_fault(); >>>>>>>>>>>>> + kvm_init_gcsr_flag(); >>>>>>>>>>>>> + >>>>>>>>>>>>> + return 0; >>>>>>>>>>>>> +} >>>>>>>>>>>>> + >>>>>>>>>>>>> +static void kvm_loongarch_env_exit(void) >>>>>>>>>>>>> +{ >>>>>>>>>>>>> + unsigned long addr; >>>>>>>>>>>>> + >>>>>>>>>>>>> + if (vmcs) >>>>>>>>>>>>> + free_percpu(vmcs); >>>>>>>>>>>>> + >>>>>>>>>>>>> + if (kvm_loongarch_ops) { >>>>>>>>>>>>> + if (kvm_loongarch_ops->guest_eentry) { >>>>>>>>>>>>> + addr = (unsigned long)kvm_loongarch_ops->guest_eentry; >>>>>>>>>>>>> + free_pages(addr, kvm_loongarch_ops->page_order); >>>>>>>>>>>>> + } >>>>>>>>>>>>> + kfree(kvm_loongarch_ops); >>>>>>>>>>>>> + } >>>>>>>>>>>>> +} >>>>>>>>>>>>> + >>>>>>>>>>>>> +static int kvm_loongarch_init(void) >>>>>>>>>>>>> +{ >>>>>>>>>>>>> + int r; >>>>>>>>>>>>> + >>>>>>>>>>>>> + if (!cpu_has_lvz) { >>>>>>>>>>>>> + kvm_info("hardware virtualization not available\n"); >>>>>>>>>>>>> + return -ENODEV; >>>>>>>>>>>>> + } >>>>>>>>>>>>> + r = kvm_loongarch_env_init(); >>>>>>>>>>>>> + if (r) >>>>>>>>>>>>> + return r; >>>>>>>>>>>>> + >>>>>>>>>>>>> + return kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE); >>>>>>>>>>>>> +} >>>>>>>>>>>>> + >>>>>>>>>>>>> +static void kvm_loongarch_exit(void) >>>>>>>>>>>>> +{ >>>>>>>>>>>>> + kvm_exit(); >>>>>>>>>>>>> + kvm_loongarch_env_exit(); >>>>>>>>>>>>> +} >>>>>>>>>>>>> + >>>>>>>>>>>>> +module_init(kvm_loongarch_init); >>>>>>>>>>>>> +module_exit(kvm_loongarch_exit); >>>>>>>>>>>>> + >>>>>>>>>>>>> +#ifdef MODULE >>>>>>>>>>>>> +static const struct cpu_feature loongarch_kvm_feature[] = { >>>>>>>>>>>>> + { .feature = cpu_feature(LOONGARCH_LVZ) }, >>>>>>>>>>>>> + {}, >>>>>>>>>>>>> +}; >>>>>>>>>>>>> +MODULE_DEVICE_TABLE(cpu, loongarch_kvm_feature); >>>>>>>>>>>>> +#endif >>>>>>>>>>>>> -- >>>>>>>>>>>>> 2.39.1 >>>>>>>>>>>>> >>