diff mbox series

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

Message ID 20230831083020.2187109-17-zhaotianrui@loongson.cn (mailing list archive)
State New, archived
Headers show
Series Add KVM LoongArch support | expand

Commit Message

zhaotianrui Aug. 31, 2023, 8:30 a.m. UTC
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

Comments

Huacai Chen Sept. 11, 2023, 10 a.m. UTC | #1
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
>
Bibo Mao Sept. 11, 2023, 10:23 a.m. UTC | #2
在 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
>>
Huacai Chen Sept. 12, 2023, 3:51 a.m. UTC | #3
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 mbox series

Patch

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);
+}