[PATCH] LoongArch: KVM: Reload guest CSR registers after S4

Bibo Mao posted 1 patch 11 months, 1 week ago
arch/loongarch/kvm/main.c | 8 ++++++++
arch/loongarch/kvm/vcpu.c | 2 +-
2 files changed, 9 insertions(+), 1 deletion(-)
[PATCH] LoongArch: KVM: Reload guest CSR registers after S4
Posted by Bibo Mao 11 months, 1 week ago
On host HW guest CSR registers are lost after suspend and resume
operation. Since last_vcpu of boot CPU still records latest vCPU pointer
so that guest CSR register skips to reload when boot CPU resumes and
vCPU is scheduled.

Here last_vcpu is cleared so that guest CSR register will reload from
scheduled vCPU context after suspend and resume.

Also there is another small fix for Loongson AVEC support, bit 14 is added
in CSR ESTAT register. Macro CSR_ESTAT_IS is replaced with hardcoded value
0x1fff and AVEC interrupt status bit 14 is supported with macro
CSR_ESTAT_IS.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 arch/loongarch/kvm/main.c | 8 ++++++++
 arch/loongarch/kvm/vcpu.c | 2 +-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
index f6d3242b9234..b177773f38f6 100644
--- a/arch/loongarch/kvm/main.c
+++ b/arch/loongarch/kvm/main.c
@@ -284,6 +284,7 @@ long kvm_arch_dev_ioctl(struct file *filp,
 int kvm_arch_enable_virtualization_cpu(void)
 {
 	unsigned long env, gcfg = 0;
+	struct kvm_context *context;
 
 	env = read_csr_gcfg();
 
@@ -317,6 +318,13 @@ int kvm_arch_enable_virtualization_cpu(void)
 	kvm_debug("GCFG:%lx GSTAT:%lx GINTC:%lx GTLBC:%lx",
 		  read_csr_gcfg(), read_csr_gstat(), read_csr_gintc(), read_csr_gtlbc());
 
+	/*
+	 * HW Guest CSR registers are lost after CPU suspend and resume
+	 * Clear last_vcpu so that Guest CSR register forced to reload
+	 * from vCPU SW state
+	 */
+	context = this_cpu_ptr(vmcs);
+	context->last_vcpu = NULL;
 	return 0;
 }
 
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 20f941af3e9e..9e1a9b4aa4c6 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -311,7 +311,7 @@ static int kvm_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
 {
 	int ret = RESUME_GUEST;
 	unsigned long estat = vcpu->arch.host_estat;
-	u32 intr = estat & 0x1fff; /* Ignore NMI */
+	u32 intr = estat & CSR_ESTAT_IS;
 	u32 ecode = (estat & CSR_ESTAT_EXC) >> CSR_ESTAT_EXC_SHIFT;
 
 	vcpu->mode = OUTSIDE_GUEST_MODE;

base-commit: 1e15510b71c99c6e49134d756df91069f7d18141
-- 
2.39.3
Re: [PATCH] LoongArch: KVM: Reload guest CSR registers after S4
Posted by Huacai Chen 11 months, 1 week ago
Hi, Bibo,

On Mon, Mar 3, 2025 at 5:11 PM Bibo Mao <maobibo@loongson.cn> wrote:
>
> On host HW guest CSR registers are lost after suspend and resume
> operation. Since last_vcpu of boot CPU still records latest vCPU pointer
> so that guest CSR register skips to reload when boot CPU resumes and
> vCPU is scheduled.
>
> Here last_vcpu is cleared so that guest CSR register will reload from
> scheduled vCPU context after suspend and resume.
>
> Also there is another small fix for Loongson AVEC support, bit 14 is added
> in CSR ESTAT register. Macro CSR_ESTAT_IS is replaced with hardcoded value
> 0x1fff and AVEC interrupt status bit 14 is supported with macro
> CSR_ESTAT_IS.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
>  arch/loongarch/kvm/main.c | 8 ++++++++
>  arch/loongarch/kvm/vcpu.c | 2 +-
>  2 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
> index f6d3242b9234..b177773f38f6 100644
> --- a/arch/loongarch/kvm/main.c
> +++ b/arch/loongarch/kvm/main.c
> @@ -284,6 +284,7 @@ long kvm_arch_dev_ioctl(struct file *filp,
>  int kvm_arch_enable_virtualization_cpu(void)
>  {
>         unsigned long env, gcfg = 0;
> +       struct kvm_context *context;
>
>         env = read_csr_gcfg();
>
> @@ -317,6 +318,13 @@ int kvm_arch_enable_virtualization_cpu(void)
>         kvm_debug("GCFG:%lx GSTAT:%lx GINTC:%lx GTLBC:%lx",
>                   read_csr_gcfg(), read_csr_gstat(), read_csr_gintc(), read_csr_gtlbc());
>
> +       /*
> +        * HW Guest CSR registers are lost after CPU suspend and resume
> +        * Clear last_vcpu so that Guest CSR register forced to reload
> +        * from vCPU SW state
> +        */
> +       context = this_cpu_ptr(vmcs);
> +       context->last_vcpu = NULL;
This can be simplified as this_cpu_ptr(vmcs)->last_vcpu = NULL;

>         return 0;
>  }
>
> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
> index 20f941af3e9e..9e1a9b4aa4c6 100644
> --- a/arch/loongarch/kvm/vcpu.c
> +++ b/arch/loongarch/kvm/vcpu.c
> @@ -311,7 +311,7 @@ static int kvm_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
>  {
>         int ret = RESUME_GUEST;
>         unsigned long estat = vcpu->arch.host_estat;
> -       u32 intr = estat & 0x1fff; /* Ignore NMI */
> +       u32 intr = estat & CSR_ESTAT_IS;
This part has nothing to do with S4, please split to another patch.

Huacai

>         u32 ecode = (estat & CSR_ESTAT_EXC) >> CSR_ESTAT_EXC_SHIFT;
>
>         vcpu->mode = OUTSIDE_GUEST_MODE;
>
> base-commit: 1e15510b71c99c6e49134d756df91069f7d18141
> --
> 2.39.3
>
>
Re: [PATCH] LoongArch: KVM: Reload guest CSR registers after S4
Posted by bibo mao 11 months, 1 week ago

On 2025/3/3 下午10:06, Huacai Chen wrote:
> Hi, Bibo,
> 
> On Mon, Mar 3, 2025 at 5:11 PM Bibo Mao <maobibo@loongson.cn> wrote:
>>
>> On host HW guest CSR registers are lost after suspend and resume
>> operation. Since last_vcpu of boot CPU still records latest vCPU pointer
>> so that guest CSR register skips to reload when boot CPU resumes and
>> vCPU is scheduled.
>>
>> Here last_vcpu is cleared so that guest CSR register will reload from
>> scheduled vCPU context after suspend and resume.
>>
>> Also there is another small fix for Loongson AVEC support, bit 14 is added
>> in CSR ESTAT register. Macro CSR_ESTAT_IS is replaced with hardcoded value
>> 0x1fff and AVEC interrupt status bit 14 is supported with macro
>> CSR_ESTAT_IS.
>>
>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
>> ---
>>   arch/loongarch/kvm/main.c | 8 ++++++++
>>   arch/loongarch/kvm/vcpu.c | 2 +-
>>   2 files changed, 9 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
>> index f6d3242b9234..b177773f38f6 100644
>> --- a/arch/loongarch/kvm/main.c
>> +++ b/arch/loongarch/kvm/main.c
>> @@ -284,6 +284,7 @@ long kvm_arch_dev_ioctl(struct file *filp,
>>   int kvm_arch_enable_virtualization_cpu(void)
>>   {
>>          unsigned long env, gcfg = 0;
>> +       struct kvm_context *context;
>>
>>          env = read_csr_gcfg();
>>
>> @@ -317,6 +318,13 @@ int kvm_arch_enable_virtualization_cpu(void)
>>          kvm_debug("GCFG:%lx GSTAT:%lx GINTC:%lx GTLBC:%lx",
>>                    read_csr_gcfg(), read_csr_gstat(), read_csr_gintc(), read_csr_gtlbc());
>>
>> +       /*
>> +        * HW Guest CSR registers are lost after CPU suspend and resume
>> +        * Clear last_vcpu so that Guest CSR register forced to reload
>> +        * from vCPU SW state
>> +        */
>> +       context = this_cpu_ptr(vmcs);
>> +       context->last_vcpu = NULL;
> This can be simplified as this_cpu_ptr(vmcs)->last_vcpu = NULL;
Sure, will do.
> 
>>          return 0;
>>   }
>>
>> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
>> index 20f941af3e9e..9e1a9b4aa4c6 100644
>> --- a/arch/loongarch/kvm/vcpu.c
>> +++ b/arch/loongarch/kvm/vcpu.c
>> @@ -311,7 +311,7 @@ static int kvm_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
>>   {
>>          int ret = RESUME_GUEST;
>>          unsigned long estat = vcpu->arch.host_estat;
>> -       u32 intr = estat & 0x1fff; /* Ignore NMI */
>> +       u32 intr = estat & CSR_ESTAT_IS;
> This part has nothing to do with S4, please split to another patch.
ok, will split into two patches.

Regards
Bibo Mao
> 
> Huacai
> 
>>          u32 ecode = (estat & CSR_ESTAT_EXC) >> CSR_ESTAT_EXC_SHIFT;
>>
>>          vcpu->mode = OUTSIDE_GUEST_MODE;
>>
>> base-commit: 1e15510b71c99c6e49134d756df91069f7d18141
>> --
>> 2.39.3
>>
>>