Re: [PATCH v20 16/30] LoongArch: KVM: Implement update VM id function

From: bibo mao
Date: Mon Sep 11 2023 - 18:24:25 EST




在 2023/9/11 18:00, Huacai Chen 写道:
> Hi, Tianrui,
>
> On Thu, Aug 31, 2023 at 4:30 PM Tianrui Zhao <zhaotianrui@xxxxxxxxxxx> wrote:
>>
>> Implement kvm check vmid and update vmid, the vmid should be checked before
>> vcpu enter guest.
>>
>> Reviewed-by: Bibo Mao <maobibo@xxxxxxxxxxx>
>> Signed-off-by: Tianrui Zhao <zhaotianrui@xxxxxxxxxxx>
>> ---
>> arch/loongarch/kvm/vmid.c | 66 +++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 66 insertions(+)
>> create mode 100644 arch/loongarch/kvm/vmid.c
>>
>> diff --git a/arch/loongarch/kvm/vmid.c b/arch/loongarch/kvm/vmid.c
>> new file mode 100644
>> index 0000000000..fc25ddc3b7
>> --- /dev/null
>> +++ b/arch/loongarch/kvm/vmid.c
>> @@ -0,0 +1,66 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (C) 2020-2023 Loongson Technology Corporation Limited
>> + */
>> +
>> +#include <linux/kvm_host.h>
>> +#include "trace.h"
>> +
>> +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_vmid(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);
>> +}
> I believe that vpid and vmid are both GID in the gstat register, so
> please unify their names. And I think vpid is better than vmid.

For processor 3A5000 vpid is the same with vmid, with next generation processor
like 3A6000, it is seperated. vpid is for vcpu specific and represents
translation from gva to gpa; vmid is the whole vm and represents translation
from gpa to hpa, all vcpus shares the same vmid, so that tlb indexed with vpid
will be still in effective when flushing shadow tlbs indexed with vmid.

Only that VM patch for 3A6000 is not submitted now, generation method for
vpid and vmid will be much different. It is prepared for future processor
update :)

Regards
Bibo Mao

>
> Moreover, no need to create a vmid.c file, just putting them in main.c is OK.
>
> Huacai
>
>> --
>> 2.27.0
>>