[PATCH] LoongArch: KVM: Fix memory leak in kvm_loongarch_env_init() error path

Chaithanya Lagisetty posted 1 patch 1 month, 1 week ago
arch/loongarch/kvm/main.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
[PATCH] LoongArch: KVM: Fix memory leak in kvm_loongarch_env_init() error path
Posted by Chaithanya Lagisetty 1 month, 1 week ago
kvm_loongarch_env_init() allocates the per-CPU kvm_context (vmcs) and
kvm_loongarch_ops, and registers the perf callbacks, before registering
the IPI/EIOINTC/PCH-PIC/DMSINTC KVM devices. If any of those device
registrations fails, the function returned the error directly without
freeing vmcs and kvm_loongarch_ops or unregistering the perf callbacks.
kvm_loongarch_init() propagates the error without calling
kvm_loongarch_env_exit(), so these resources are leaked.

Unwind the already-acquired resources on the error path, mirroring
kvm_loongarch_env_exit().

Fixes: c532de5a67a7 ("LoongArch: KVM: Add IPI device support")
Signed-off-by: Chaithanya Lagisetty <nagachaithanya9911@gmail.com>
---
 arch/loongarch/kvm/main.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
index 3e1005526f4b..685d334cf957 100644
--- a/arch/loongarch/kvm/main.c
+++ b/arch/loongarch/kvm/main.c
@@ -385,22 +385,33 @@ static int kvm_loongarch_env_init(void)
 	/* Register LoongArch IPI interrupt controller interface. */
 	ret = kvm_loongarch_register_ipi_device();
 	if (ret)
-		return ret;
+		goto err;
 
 	/* Register LoongArch EIOINTC interrupt controller interface. */
 	ret = kvm_loongarch_register_eiointc_device();
 	if (ret)
-		return ret;
+		goto err;
 
 	/* Register LoongArch PCH-PIC interrupt controller interface. */
 	ret = kvm_loongarch_register_pch_pic_device();
 	if (ret)
-		return ret;
+		goto err;
 
 	/* Register LoongArch DMSINTC interrupt contrroller interface */
-	if (cpu_has_msgint)
+	if (cpu_has_msgint) {
 		ret = kvm_loongarch_register_dmsintc_device();
+		if (ret)
+			goto err;
+	}
 
+	return 0;
+
+err:
+	kvm_unregister_perf_callbacks();
+	kfree(kvm_loongarch_ops);
+	kvm_loongarch_ops = NULL;
+	free_percpu(vmcs);
+	vmcs = NULL;
 	return ret;
 }
 
-- 
2.43.0
[PATCH v2 0/2] LoongArch: KVM: Fix kvm_loongarch_env_init() error path
Posted by Chaithanya Lagisetty 3 weeks, 5 days ago
kvm_loongarch_env_init() leaves everything it has already acquired behind
when one of the IPI/EIOINTC/PCH-PIC/DMSINTC device registrations fails, and
kvm_loongarch_init() does not call kvm_loongarch_env_exit() on that error,
so nothing else cleans up either.

v1 unwound only the memory and the perf callbacks. Bibo Mao pointed out
that the device registrations should be undone through wrapped unregister
helpers, so patch 1 adds those and patch 2 uses them to unwind the error
path in reverse order of registration. Patch 2 also uses them in
kvm_loongarch_env_exit(), so that the device ops are unregistered on normal
teardown as well.

Link: https://lore.kernel.org/all/20260817115847.2705791-1-nagachaithanya9911@gmail.com/ [v1]

v2:
 - Add unregister helpers as suggested by Bibo Mao
 - Unwind device registrations in reverse order
 - Use unregister helpers in kvm_loongarch_env_exit()
 - Split into two patches, so the fix only uses the helpers
 - Reword commit message to avoid implementation-specific details, and
   retitle from "memory leak" to "resource leak"

Compile-tested only, no LoongArch hardware: loongson64_defconfig with
CONFIG_KVM=m and CONFIG_KVM=y, W=1, each patch built individually, no new
warnings.

Chaithanya Lagisetty (2):
  LoongArch: KVM: Add unregister helpers for the KVM interrupt devices
  LoongArch: KVM: Fix resource leak in kvm_loongarch_env_init() error
    path

 arch/loongarch/include/asm/kvm_dmsintc.h |  1 +
 arch/loongarch/include/asm/kvm_eiointc.h |  1 +
 arch/loongarch/include/asm/kvm_ipi.h     |  1 +
 arch/loongarch/include/asm/kvm_pch_pic.h |  1 +
 arch/loongarch/kvm/intc/dmsintc.c        |  5 ++++
 arch/loongarch/kvm/intc/eiointc.c        |  5 ++++
 arch/loongarch/kvm/intc/ipi.c            |  5 ++++
 arch/loongarch/kvm/intc/pch_pic.c        |  5 ++++
 arch/loongarch/kvm/main.c                | 32 +++++++++++++++++++++---
 9 files changed, 52 insertions(+), 4 deletions(-)

-- 
2.43.0
Re: [PATCH v2 0/2] LoongArch: KVM: Fix kvm_loongarch_env_init() error path
Posted by Huacai Chen 3 weeks, 2 days ago
Applied, thanks.


Huacai

On Wed, Sep 2, 2026 at 3:07 PM Chaithanya Lagisetty
<nagachaithanya9911@gmail.com> wrote:
>
> kvm_loongarch_env_init() leaves everything it has already acquired behind
> when one of the IPI/EIOINTC/PCH-PIC/DMSINTC device registrations fails, and
> kvm_loongarch_init() does not call kvm_loongarch_env_exit() on that error,
> so nothing else cleans up either.
>
> v1 unwound only the memory and the perf callbacks. Bibo Mao pointed out
> that the device registrations should be undone through wrapped unregister
> helpers, so patch 1 adds those and patch 2 uses them to unwind the error
> path in reverse order of registration. Patch 2 also uses them in
> kvm_loongarch_env_exit(), so that the device ops are unregistered on normal
> teardown as well.
>
> Link: https://lore.kernel.org/all/20260817115847.2705791-1-nagachaithanya9911@gmail.com/ [v1]
>
> v2:
>  - Add unregister helpers as suggested by Bibo Mao
>  - Unwind device registrations in reverse order
>  - Use unregister helpers in kvm_loongarch_env_exit()
>  - Split into two patches, so the fix only uses the helpers
>  - Reword commit message to avoid implementation-specific details, and
>    retitle from "memory leak" to "resource leak"
>
> Compile-tested only, no LoongArch hardware: loongson64_defconfig with
> CONFIG_KVM=m and CONFIG_KVM=y, W=1, each patch built individually, no new
> warnings.
>
> Chaithanya Lagisetty (2):
>   LoongArch: KVM: Add unregister helpers for the KVM interrupt devices
>   LoongArch: KVM: Fix resource leak in kvm_loongarch_env_init() error
>     path
>
>  arch/loongarch/include/asm/kvm_dmsintc.h |  1 +
>  arch/loongarch/include/asm/kvm_eiointc.h |  1 +
>  arch/loongarch/include/asm/kvm_ipi.h     |  1 +
>  arch/loongarch/include/asm/kvm_pch_pic.h |  1 +
>  arch/loongarch/kvm/intc/dmsintc.c        |  5 ++++
>  arch/loongarch/kvm/intc/eiointc.c        |  5 ++++
>  arch/loongarch/kvm/intc/ipi.c            |  5 ++++
>  arch/loongarch/kvm/intc/pch_pic.c        |  5 ++++
>  arch/loongarch/kvm/main.c                | 32 +++++++++++++++++++++---
>  9 files changed, 52 insertions(+), 4 deletions(-)
>
> --
> 2.43.0
>
Re: [PATCH v2 0/2] LoongArch: KVM: Fix kvm_loongarch_env_init() error path
Posted by Bibo Mao 3 weeks, 5 days ago

On 2026/9/2 下午3:07, Chaithanya Lagisetty wrote:
> kvm_loongarch_env_init() leaves everything it has already acquired behind
> when one of the IPI/EIOINTC/PCH-PIC/DMSINTC device registrations fails, and
> kvm_loongarch_init() does not call kvm_loongarch_env_exit() on that error,
> so nothing else cleans up either.
> 
> v1 unwound only the memory and the perf callbacks. Bibo Mao pointed out
> that the device registrations should be undone through wrapped unregister
> helpers, so patch 1 adds those and patch 2 uses them to unwind the error
> path in reverse order of registration. Patch 2 also uses them in
> kvm_loongarch_env_exit(), so that the device ops are unregistered on normal
> teardown as well.
> 
> Link: https://lore.kernel.org/all/20260817115847.2705791-1-nagachaithanya9911@gmail.com/ [v1]
> 
> v2:
>   - Add unregister helpers as suggested by Bibo Mao
>   - Unwind device registrations in reverse order
>   - Use unregister helpers in kvm_loongarch_env_exit()
>   - Split into two patches, so the fix only uses the helpers
>   - Reword commit message to avoid implementation-specific details, and
>     retitle from "memory leak" to "resource leak"
> 
> Compile-tested only, no LoongArch hardware: loongson64_defconfig with
> CONFIG_KVM=m and CONFIG_KVM=y, W=1, each patch built individually, no new
> warnings.
> 
> Chaithanya Lagisetty (2):
>    LoongArch: KVM: Add unregister helpers for the KVM interrupt devices
>    LoongArch: KVM: Fix resource leak in kvm_loongarch_env_init() error
>      path
> 
>   arch/loongarch/include/asm/kvm_dmsintc.h |  1 +
>   arch/loongarch/include/asm/kvm_eiointc.h |  1 +
>   arch/loongarch/include/asm/kvm_ipi.h     |  1 +
>   arch/loongarch/include/asm/kvm_pch_pic.h |  1 +
>   arch/loongarch/kvm/intc/dmsintc.c        |  5 ++++
>   arch/loongarch/kvm/intc/eiointc.c        |  5 ++++
>   arch/loongarch/kvm/intc/ipi.c            |  5 ++++
>   arch/loongarch/kvm/intc/pch_pic.c        |  5 ++++
>   arch/loongarch/kvm/main.c                | 32 +++++++++++++++++++++---
>   9 files changed, 52 insertions(+), 4 deletions(-)
> 
For this series:
Reviewed-by: Bibo Mao <maobibo@loongson.cn>

[PATCH v2 1/2] LoongArch: KVM: Add unregister helpers for the KVM interrupt devices
Posted by Chaithanya Lagisetty 3 weeks, 5 days ago
The IPI/EIOINTC/PCH-PIC/DMSINTC KVM devices each have a helper that
registers their kvm_device_ops, but there is no counterpart to remove
them again, so a caller that needs to undo a registration has to
open-code kvm_unregister_device_ops() with the matching device type.

Add kvm_loongarch_unregister_{ipi,eiointc,pch_pic,dmsintc}_device()
next to the existing register helpers. kvm_unregister_device_ops() is a
no-op when the corresponding device type is not currently registered.

No functional change, as there are no callers yet.

Suggested-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Chaithanya Lagisetty <nagachaithanya9911@gmail.com>
---
 arch/loongarch/include/asm/kvm_dmsintc.h | 1 +
 arch/loongarch/include/asm/kvm_eiointc.h | 1 +
 arch/loongarch/include/asm/kvm_ipi.h     | 1 +
 arch/loongarch/include/asm/kvm_pch_pic.h | 1 +
 arch/loongarch/kvm/intc/dmsintc.c        | 5 +++++
 arch/loongarch/kvm/intc/eiointc.c        | 5 +++++
 arch/loongarch/kvm/intc/ipi.c            | 5 +++++
 arch/loongarch/kvm/intc/pch_pic.c        | 5 +++++
 8 files changed, 24 insertions(+)

diff --git a/arch/loongarch/include/asm/kvm_dmsintc.h b/arch/loongarch/include/asm/kvm_dmsintc.h
index 5a71b9ccbe78..7c0158764d84 100644
--- a/arch/loongarch/include/asm/kvm_dmsintc.h
+++ b/arch/loongarch/include/asm/kvm_dmsintc.h
@@ -20,6 +20,7 @@ struct dmsintc_state {
 };
 
 int kvm_loongarch_register_dmsintc_device(void);
+void kvm_loongarch_unregister_dmsintc_device(void);
 void dmsintc_inject_irq(struct kvm_vcpu *vcpu);
 int dmsintc_set_irq(struct kvm *kvm, u64 addr, int data, int level);
 int dmsintc_deliver_msi_to_vcpu(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 vector, int level);
diff --git a/arch/loongarch/include/asm/kvm_eiointc.h b/arch/loongarch/include/asm/kvm_eiointc.h
index 8b7a2fa3f7f8..9633fbfc066d 100644
--- a/arch/loongarch/include/asm/kvm_eiointc.h
+++ b/arch/loongarch/include/asm/kvm_eiointc.h
@@ -79,6 +79,7 @@ struct loongarch_eiointc {
 };
 
 int kvm_loongarch_register_eiointc_device(void);
+void kvm_loongarch_unregister_eiointc_device(void);
 void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level);
 
 #endif /* __ASM_KVM_EIOINTC_H */
diff --git a/arch/loongarch/include/asm/kvm_ipi.h b/arch/loongarch/include/asm/kvm_ipi.h
index 060163dfb4a3..d1d72d4bb8d1 100644
--- a/arch/loongarch/include/asm/kvm_ipi.h
+++ b/arch/loongarch/include/asm/kvm_ipi.h
@@ -41,5 +41,6 @@ struct ipi_state {
 #define IOCSR_ANY_SEND		0x158
 
 int kvm_loongarch_register_ipi_device(void);
+void kvm_loongarch_unregister_ipi_device(void);
 
 #endif
diff --git a/arch/loongarch/include/asm/kvm_pch_pic.h b/arch/loongarch/include/asm/kvm_pch_pic.h
index e74b3b742634..887b0431fd20 100644
--- a/arch/loongarch/include/asm/kvm_pch_pic.h
+++ b/arch/loongarch/include/asm/kvm_pch_pic.h
@@ -70,6 +70,7 @@ struct loongarch_pch_pic {
 
 struct kvm_kernel_irq_routing_entry;
 int kvm_loongarch_register_pch_pic_device(void);
+void kvm_loongarch_unregister_pch_pic_device(void);
 void pch_pic_set_irq(struct loongarch_pch_pic *s, int irq, int level);
 int pch_msi_set_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, int level);
 
diff --git a/arch/loongarch/kvm/intc/dmsintc.c b/arch/loongarch/kvm/intc/dmsintc.c
index bb7285c49df3..c7d8841df96f 100644
--- a/arch/loongarch/kvm/intc/dmsintc.c
+++ b/arch/loongarch/kvm/intc/dmsintc.c
@@ -180,3 +180,8 @@ int kvm_loongarch_register_dmsintc_device(void)
 {
 	return kvm_register_device_ops(&kvm_dmsintc_dev_ops, KVM_DEV_TYPE_LOONGARCH_DMSINTC);
 }
+
+void kvm_loongarch_unregister_dmsintc_device(void)
+{
+	kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_DMSINTC);
+}
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 84d84bd432d7..80f78e07c74a 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -695,3 +695,8 @@ int kvm_loongarch_register_eiointc_device(void)
 {
 	return kvm_register_device_ops(&kvm_eiointc_dev_ops, KVM_DEV_TYPE_LOONGARCH_EIOINTC);
 }
+
+void kvm_loongarch_unregister_eiointc_device(void)
+{
+	kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_EIOINTC);
+}
diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c
index fcfaf1a66790..7b333a4a0430 100644
--- a/arch/loongarch/kvm/intc/ipi.c
+++ b/arch/loongarch/kvm/intc/ipi.c
@@ -463,3 +463,8 @@ int kvm_loongarch_register_ipi_device(void)
 {
 	return kvm_register_device_ops(&kvm_ipi_dev_ops, KVM_DEV_TYPE_LOONGARCH_IPI);
 }
+
+void kvm_loongarch_unregister_ipi_device(void)
+{
+	kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_IPI);
+}
diff --git a/arch/loongarch/kvm/intc/pch_pic.c b/arch/loongarch/kvm/intc/pch_pic.c
index e7b77705c516..83fa2386cf81 100644
--- a/arch/loongarch/kvm/intc/pch_pic.c
+++ b/arch/loongarch/kvm/intc/pch_pic.c
@@ -500,3 +500,8 @@ int kvm_loongarch_register_pch_pic_device(void)
 {
 	return kvm_register_device_ops(&kvm_pch_pic_dev_ops, KVM_DEV_TYPE_LOONGARCH_PCHPIC);
 }
+
+void kvm_loongarch_unregister_pch_pic_device(void)
+{
+	kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_PCHPIC);
+}
-- 
2.43.0
[PATCH v2 2/2] LoongArch: KVM: Fix resource leak in kvm_loongarch_env_init() error path
Posted by Chaithanya Lagisetty 3 weeks, 5 days ago
kvm_loongarch_env_init() allocates the per-CPU kvm_context (vmcs) and
kvm_loongarch_ops, registers the perf callbacks, and then registers the
IPI/EIOINTC/PCH-PIC/DMSINTC KVM devices. If any of those device
registrations fails, the function returned the error directly, leaving
everything acquired so far in place: vmcs and kvm_loongarch_ops are
never freed, the perf callbacks stay registered, and previously
registered KVM device ops remain registered. kvm_loongarch_init()
propagates the error without calling kvm_loongarch_env_exit(), so
nothing else cleans up either.

Unwind the error path in reverse order of registration, so that each
failure only undoes what had actually been set up. Use the same helpers
in kvm_loongarch_env_exit() to remove the device registrations during
normal teardown as well.

Fixes: c532de5a67a7 ("LoongArch: KVM: Add IPI device support")
Signed-off-by: Chaithanya Lagisetty <nagachaithanya9911@gmail.com>
---
 arch/loongarch/kvm/main.c | 32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
index 3e1005526f4b..c9cb3fc2e560 100644
--- a/arch/loongarch/kvm/main.c
+++ b/arch/loongarch/kvm/main.c
@@ -385,27 +385,51 @@ static int kvm_loongarch_env_init(void)
 	/* Register LoongArch IPI interrupt controller interface. */
 	ret = kvm_loongarch_register_ipi_device();
 	if (ret)
-		return ret;
+		goto err_env;
 
 	/* Register LoongArch EIOINTC interrupt controller interface. */
 	ret = kvm_loongarch_register_eiointc_device();
 	if (ret)
-		return ret;
+		goto err_ipi;
 
 	/* Register LoongArch PCH-PIC interrupt controller interface. */
 	ret = kvm_loongarch_register_pch_pic_device();
 	if (ret)
-		return ret;
+		goto err_eiointc;
 
 	/* Register LoongArch DMSINTC interrupt contrroller interface */
-	if (cpu_has_msgint)
+	if (cpu_has_msgint) {
 		ret = kvm_loongarch_register_dmsintc_device();
+		if (ret)
+			goto err_pch_pic;
+	}
+
+	return 0;
+
+err_pch_pic:
+	kvm_loongarch_unregister_pch_pic_device();
+err_eiointc:
+	kvm_loongarch_unregister_eiointc_device();
+err_ipi:
+	kvm_loongarch_unregister_ipi_device();
+err_env:
+	kvm_unregister_perf_callbacks();
+	kfree(kvm_loongarch_ops);
+	kvm_loongarch_ops = NULL;
+	free_percpu(vmcs);
+	vmcs = NULL;
 
 	return ret;
 }
 
 static void kvm_loongarch_env_exit(void)
 {
+	if (cpu_has_msgint)
+		kvm_loongarch_unregister_dmsintc_device();
+	kvm_loongarch_unregister_pch_pic_device();
+	kvm_loongarch_unregister_eiointc_device();
+	kvm_loongarch_unregister_ipi_device();
+
 	if (vmcs)
 		free_percpu(vmcs);
 
-- 
2.43.0
Re: [PATCH] LoongArch: KVM: Fix memory leak in kvm_loongarch_env_init() error path
Posted by Bibo Mao 3 weeks, 6 days ago

On 2026/8/17 下午7:58, Chaithanya Lagisetty wrote:
> kvm_loongarch_env_init() allocates the per-CPU kvm_context (vmcs) and
> kvm_loongarch_ops, and registers the perf callbacks, before registering
> the IPI/EIOINTC/PCH-PIC/DMSINTC KVM devices. If any of those device
> registrations fails, the function returned the error directly without
> freeing vmcs and kvm_loongarch_ops or unregistering the perf callbacks.
> kvm_loongarch_init() propagates the error without calling
> kvm_loongarch_env_exit(), so these resources are leaked.
> 
> Unwind the already-acquired resources on the error path, mirroring
> kvm_loongarch_env_exit().
> 
> Fixes: c532de5a67a7 ("LoongArch: KVM: Add IPI device support")
> Signed-off-by: Chaithanya Lagisetty <nagachaithanya9911@gmail.com>
> ---
>   arch/loongarch/kvm/main.c | 19 +++++++++++++++----
>   1 file changed, 15 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
> index 3e1005526f4b..685d334cf957 100644
> --- a/arch/loongarch/kvm/main.c
> +++ b/arch/loongarch/kvm/main.c
> @@ -385,22 +385,33 @@ static int kvm_loongarch_env_init(void)
>   	/* Register LoongArch IPI interrupt controller interface. */
>   	ret = kvm_loongarch_register_ipi_device();
>   	if (ret)
> -		return ret;
> +		goto err;
>   
>   	/* Register LoongArch EIOINTC interrupt controller interface. */
>   	ret = kvm_loongarch_register_eiointc_device();
>   	if (ret)
> -		return ret;
> +		goto err;
>   
>   	/* Register LoongArch PCH-PIC interrupt controller interface. */
>   	ret = kvm_loongarch_register_pch_pic_device();
>   	if (ret)
> -		return ret;
> +		goto err;
It will be better if there is wrapped unregister function, to remove 
previous registered callback. The same with eiointc/dmsintc driver, 
something like this:
+
+void kvm_loongarch_unregister_pch_pic_device(void)
+{
+       return kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_PCHPIC);
+}

Regards
Bibo Mao
>   
>   	/* Register LoongArch DMSINTC interrupt contrroller interface */
> -	if (cpu_has_msgint)
> +	if (cpu_has_msgint) {
>   		ret = kvm_loongarch_register_dmsintc_device();
> +		if (ret)
> +			goto err;
> +	}
>   
> +	return 0;
> +
> +err:
> +	kvm_unregister_perf_callbacks();
> +	kfree(kvm_loongarch_ops);
> +	kvm_loongarch_ops = NULL;
> +	free_percpu(vmcs);
> +	vmcs = NULL;
>   	return ret;
>   }
>   
> 

Re: [PATCH] LoongArch: KVM: Fix memory leak in kvm_loongarch_env_init() error path
Posted by Huacai Chen 4 weeks ago
Hi, Bibo,

What do you think about this?


Huacai

On Mon, Aug 17, 2026 at 7:59 PM Chaithanya Lagisetty
<nagachaithanya9911@gmail.com> wrote:
>
> kvm_loongarch_env_init() allocates the per-CPU kvm_context (vmcs) and
> kvm_loongarch_ops, and registers the perf callbacks, before registering
> the IPI/EIOINTC/PCH-PIC/DMSINTC KVM devices. If any of those device
> registrations fails, the function returned the error directly without
> freeing vmcs and kvm_loongarch_ops or unregistering the perf callbacks.
> kvm_loongarch_init() propagates the error without calling
> kvm_loongarch_env_exit(), so these resources are leaked.
>
> Unwind the already-acquired resources on the error path, mirroring
> kvm_loongarch_env_exit().
>
> Fixes: c532de5a67a7 ("LoongArch: KVM: Add IPI device support")
> Signed-off-by: Chaithanya Lagisetty <nagachaithanya9911@gmail.com>
> ---
>  arch/loongarch/kvm/main.c | 19 +++++++++++++++----
>  1 file changed, 15 insertions(+), 4 deletions(-)
>
> diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
> index 3e1005526f4b..685d334cf957 100644
> --- a/arch/loongarch/kvm/main.c
> +++ b/arch/loongarch/kvm/main.c
> @@ -385,22 +385,33 @@ static int kvm_loongarch_env_init(void)
>         /* Register LoongArch IPI interrupt controller interface. */
>         ret = kvm_loongarch_register_ipi_device();
>         if (ret)
> -               return ret;
> +               goto err;
>
>         /* Register LoongArch EIOINTC interrupt controller interface. */
>         ret = kvm_loongarch_register_eiointc_device();
>         if (ret)
> -               return ret;
> +               goto err;
>
>         /* Register LoongArch PCH-PIC interrupt controller interface. */
>         ret = kvm_loongarch_register_pch_pic_device();
>         if (ret)
> -               return ret;
> +               goto err;
>
>         /* Register LoongArch DMSINTC interrupt contrroller interface */
> -       if (cpu_has_msgint)
> +       if (cpu_has_msgint) {
>                 ret = kvm_loongarch_register_dmsintc_device();
> +               if (ret)
> +                       goto err;
> +       }
>
> +       return 0;
> +
> +err:
> +       kvm_unregister_perf_callbacks();
> +       kfree(kvm_loongarch_ops);
> +       kvm_loongarch_ops = NULL;
> +       free_percpu(vmcs);
> +       vmcs = NULL;
>         return ret;
>  }
>
> --
> 2.43.0
>