Message ID | 20230831083020.2187109-17-zhaotianrui@loongson.cn (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add KVM LoongArch support | expand |
Hi, Tianrui, On Thu, Aug 31, 2023 at 4:30 PM Tianrui Zhao <zhaotianrui@loongson.cn> wrote: > > Implement kvm check vmid and update vmid, the vmid should be checked before > vcpu enter guest. > > Reviewed-by: Bibo Mao <maobibo@loongson.cn> > Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn> > --- > 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. Moreover, no need to create a vmid.c file, just putting them in main.c is OK. Huacai > -- > 2.27.0 >
在 2023/9/11 18:00, Huacai Chen 写道: > Hi, Tianrui, > > On Thu, Aug 31, 2023 at 4:30 PM Tianrui Zhao <zhaotianrui@loongson.cn> wrote: >> >> Implement kvm check vmid and update vmid, the vmid should be checked before >> vcpu enter guest. >> >> Reviewed-by: Bibo Mao <maobibo@loongson.cn> >> Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn> >> --- >> 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 >>
On Mon, Sep 11, 2023 at 6:23 PM bibo mao <maobibo@loongson.cn> wrote: > > > > 在 2023/9/11 18:00, Huacai Chen 写道: > > Hi, Tianrui, > > > > On Thu, Aug 31, 2023 at 4:30 PM Tianrui Zhao <zhaotianrui@loongson.cn> wrote: > >> > >> Implement kvm check vmid and update vmid, the vmid should be checked before > >> vcpu enter guest. > >> > >> Reviewed-by: Bibo Mao <maobibo@loongson.cn> > >> Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn> > >> --- > >> 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 :) If so, then I think there should be a 'vmid' in kvm_arch and a 'vpid' in kvm_vcpu_arch? This patch only handles kvm_vcpu_arch so I think all should be vpid here. And again, this code can be just put in main.c. Huacai > > Regards > Bibo Mao > > > > > Moreover, no need to create a vmid.c file, just putting them in main.c is OK. > > > > Huacai > > > >> -- > >> 2.27.0 > >> >
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); +}