From: zhaotianrui <zhaotianrui@loongson.cn>
To: Huacai Chen <chenhuacai@kernel.org>, bibo mao <maobibo@loongson.cn>
Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
Paolo Bonzini <pbonzini@redhat.com>,
WANG Xuerui <kernel@xen0n.name>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
loongarch@lists.linux.dev, Jens Axboe <axboe@kernel.dk>,
Mark Brown <broonie@kernel.org>,
Alex Deucher <alexander.deucher@amd.com>,
Oliver Upton <oliver.upton@linux.dev>,
Xi Ruoyao <xry111@xry111.site>
Subject: Re: [PATCH v21 02/29] LoongArch: KVM: Implement kvm module related interface
Date: Tue, 19 Sep 2023 10:53:25 +0800 [thread overview]
Message-ID: <35658917-c7d6-19ad-ea23-848a4ef00a97@loongson.cn> (raw)
In-Reply-To: <CAAhV-H49YTLJKW=rnp_=GOtGby-QG_S=bwQSFy+MWgkFRmUjCg@mail.gmail.com>
在 2023/9/19 上午10:14, Huacai Chen 写道:
> On Mon, Sep 18, 2023 at 4:39 PM bibo mao <maobibo@loongson.cn> wrote:
>>
>>
>> 在 2023/9/18 14:25, zhaotianrui 写道:
>>> 在 2023/9/18 下午12:03, Huacai Chen 写道:
>>>> On Mon, Sep 18, 2023 at 11:20 AM zhaotianrui <zhaotianrui@loongson.cn> wrote:
>>>>> 在 2023/9/18 上午11:12, Huacai Chen 写道:
>>>>>> On Mon, Sep 18, 2023 at 11:08 AM zhaotianrui <zhaotianrui@loongson.cn> wrote:
>>>>>>> 在 2023/9/18 上午9:45, Huacai Chen 写道:
>>>>>>>> On Mon, Sep 18, 2023 at 9:21 AM zhaotianrui <zhaotianrui@loongson.cn> wrote:
>>>>>>>>> 在 2023/9/16 下午4:51, Huacai Chen 写道:
>>>>>>>>>> Hi, Tianrui,
>>>>>>>>>>
>>>>>>>>>> On Fri, Sep 15, 2023 at 9:50 AM Tianrui Zhao <zhaotianrui@loongson.cn> 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 <maobibo@loongson.cn>
>>>>>>>>>>> Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
>>>>>>>>>>> ---
>>>>>>>>>>> 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 <linux/err.h>
>>>>>>>>>>> +#include <linux/module.h>
>>>>>>>>>>> +#include <linux/kvm_host.h>
>>>>>>>>>>> +#include <asm/cacheflush.h>
>>>>>>>>>>> +#include <asm/cpufeature.h>
>>>>>>>>>>> +#include <asm/kvm_csr.h>
>>>>>>>>>>> +#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.
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
>>>>>>>>>>>
>>
next prev parent reply other threads:[~2023-09-19 2:53 UTC|newest]
Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-15 1:49 [PATCH v21 00/29] Add KVM LoongArch support Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 01/29] LoongArch: KVM: Add kvm related header files Tianrui Zhao
2023-09-16 8:48 ` Huacai Chen
2023-09-18 1:32 ` zhaotianrui
2023-09-18 1:36 ` Huacai Chen
2023-09-18 6:28 ` zhaotianrui
2023-09-18 6:35 ` Huacai Chen
2023-09-19 2:56 ` zhaotianrui
2023-09-17 14:22 ` Huacai Chen
2023-09-18 6:32 ` zhaotianrui
2023-09-18 6:37 ` Huacai Chen
2023-09-19 2:58 ` zhaotianrui
2023-09-15 1:49 ` [PATCH v21 02/29] LoongArch: KVM: Implement kvm module related interface Tianrui Zhao
2023-09-16 6:57 ` Huacai Chen
2023-09-16 9:01 ` zhaotianrui
2023-09-16 8:51 ` Huacai Chen
2023-09-18 1:21 ` zhaotianrui
2023-09-18 1:45 ` Huacai Chen
2023-09-18 3:08 ` zhaotianrui
2023-09-18 3:12 ` Huacai Chen
2023-09-18 3:20 ` zhaotianrui
2023-09-18 4:03 ` Huacai Chen
2023-09-18 6:25 ` zhaotianrui
2023-09-18 8:39 ` bibo mao
2023-09-19 2:14 ` Huacai Chen
2023-09-19 2:53 ` zhaotianrui [this message]
2023-09-19 2:57 ` Huacai Chen
2023-09-19 3:13 ` zhaotianrui
2023-09-17 4:21 ` Huacai Chen
2023-09-19 2:38 ` zhaotianrui
2023-09-19 2:41 ` Huacai Chen
2023-09-19 5:07 ` zhaotianrui
2023-09-15 1:49 ` [PATCH v21 03/29] LoongArch: KVM: Implement kvm hardware enable, disable interface Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 04/29] LoongArch: KVM: Implement VM related functions Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 05/29] LoongArch: KVM: Add vcpu related header files Tianrui Zhao
2023-09-16 10:16 ` Huacai Chen
2023-09-18 2:21 ` zhaotianrui
2023-09-15 1:49 ` [PATCH v21 06/29] LoongArch: KVM: Implement vcpu create and destroy interface Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 07/29] LoongArch: KVM: Implement vcpu run interface Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 08/29] LoongArch: KVM: Implement vcpu handle exit interface Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 09/29] LoongArch: KVM: Implement vcpu get, vcpu set registers Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 10/29] LoongArch: KVM: Implement vcpu ENABLE_CAP ioctl interface Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 11/29] LoongArch: KVM: Implement fpu related operations for vcpu Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 12/29] LoongArch: KVM: Implement vcpu interrupt operations Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 13/29] LoongArch: KVM: Implement misc vcpu related interfaces Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 14/29] LoongArch: KVM: Implement vcpu load and vcpu put operations Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 15/29] LoongArch: KVM: Implement vcpu status description Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 16/29] LoongArch: KVM: Implement virtual machine tlb operations Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 17/29] LoongArch: KVM: Implement vcpu timer operations Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 18/29] LoongArch: KVM: Implement kvm mmu operations Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 19/29] LoongArch: KVM: Implement handle csr exception Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 20/29] LoongArch: KVM: Implement handle iocsr exception Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 21/29] LoongArch: KVM: Implement handle idle exception Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 22/29] LoongArch: KVM: Implement handle gspr exception Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 23/29] LoongArch: KVM: Implement handle mmio exception Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 24/29] LoongArch: KVM: Implement handle fpu exception Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 25/29] LoongArch: KVM: Implement kvm exception vector Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 26/29] LoongArch: KVM: Implement vcpu world switch Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 27/29] LoongArch: KVM: Enable kvm config and add the makefile Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 28/29] LoongArch: KVM: Supplement kvm document about LoongArch-specific part Tianrui Zhao
2023-09-15 1:49 ` [PATCH v21 29/29] LoongArch: KVM: Add maintainers for LoongArch KVM Tianrui Zhao
2023-09-15 4:11 ` [PATCH v21 00/29] Add KVM LoongArch support Huacai Chen
2023-09-15 6:58 ` zhaotianrui
2023-09-15 7:10 ` Huacai Chen
2023-09-15 7:53 ` zhaotianrui
2023-09-16 3:17 ` Huacai Chen
2023-09-16 6:29 ` zhaotianrui
2023-09-21 7:17 ` Huacai Chen
2023-09-20 15:22 ` Paolo Bonzini
2023-09-21 7:30 ` Huacai Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=35658917-c7d6-19ad-ea23-848a4ef00a97@loongson.cn \
--to=zhaotianrui@loongson.cn \
--cc=alexander.deucher@amd.com \
--cc=axboe@kernel.dk \
--cc=broonie@kernel.org \
--cc=chenhuacai@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=kernel@xen0n.name \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=loongarch@lists.linux.dev \
--cc=maobibo@loongson.cn \
--cc=oliver.upton@linux.dev \
--cc=pbonzini@redhat.com \
--cc=xry111@xry111.site \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®