Re: [PATCH] LoongArch: KVM: Add hypercall crash support

From: Huacai Chen

Date: Fri Oct 16 2026 - 00:32:50 EST


On Fri, Oct 16, 2026 at 11:27 AM Bibo Mao <maobibo@xxxxxxxxxxx> wrote:
>
>
>
> On 2026/10/16 上午9:06, Bibo Mao wrote:
> >
> >
> > On 2026/10/14 下午12:30, Huacai Chen wrote:
> >> On Mon, Oct 12, 2026 at 8:55 AM Bibo Mao <maobibo@xxxxxxxxxxx> wrote:
> >>>
> >>>
> >>>
> >>> On 2026/10/11 下午10:06, Huacai Chen wrote:
> >>>> On Thu, Oct 8, 2026 at 9:50 AM Bibo Mao <maobibo@xxxxxxxxxxx> wrote:
> >>>>>
> >>>>>
> >>>>>
> >>>>> On 2026/10/3 下午12:02, Huacai Chen wrote:
> >>>>>> Hi, Bibo,
> >>>>>>
> >>>>>> On Wed, Sep 9, 2026 at 5:01 PM Bibo Mao <maobibo@xxxxxxxxxxx> wrote:
> >>>>>>>
> >>>>>>> Now generic pvpanic is supported in Linux kernel which will
> >>>>>>> notify VMM
> >>>>>>> with VM crash event. There is some limitations with pvpanic, such
> >>>>>>> as it
> >>>>>>> requires good kernel stack or CPU hardware context and panic() C
> >>>>>>> function
> >>>>>>> is in health state.
> >>>>>>>
> >>>>>>> Sometimes CPU hardware context or kernel/irq stack is corrupted.
> >>>>>>> Hypercall
> >>>>>>> code is more direct and low-level crash method, which is useful in
> >>>>>>> exception entry with assmble language, here add one hypercall
> >>>>>>> code to
> >>>>>>> support VM crash function, so that VMM can capture CPU crash context
> >>>>>>> in time.
> >>>>>>>
> >>>>>>> Signed-off-by: Bibo Mao <maobibo@xxxxxxxxxxx>
> >>>>>>> ---
> >>>>>>> arch/loongarch/include/asm/kvm_host.h | 1 +
> >>>>>>> arch/loongarch/include/asm/kvm_para.h | 15 +++++++++++++++
> >>>>>>> arch/loongarch/include/uapi/asm/kvm.h | 1 +
> >>>>>>> arch/loongarch/include/uapi/asm/kvm_para.h | 1 +
> >>>>>>> arch/loongarch/kvm/exit.c | 11 +++++++++++
> >>>>>>> arch/loongarch/kvm/vm.c | 3 ++-
> >>>>>>> 6 files changed, 31 insertions(+), 1 deletion(-)
> >>>>>>>
> >>>>>>> diff --git a/arch/loongarch/include/asm/kvm_host.h
> >>>>>>> b/arch/loongarch/include/asm/kvm_host.h
> >>>>>>> index 65d91c3ce313..96f9f1317cad 100644
> >>>>>>> --- a/arch/loongarch/include/asm/kvm_host.h
> >>>>>>> +++ b/arch/loongarch/include/asm/kvm_host.h
> >>>>>>> @@ -168,6 +168,7 @@ enum emulation_result {
> >>>>>>> #define LOONGARCH_PV_FEAT_MASK (BIT(KVM_FEATURE_IPI)
> >>>>>>> | \
> >>>>>>>
> >>>>>>> BIT(KVM_FEATURE_PREEMPT) | \
> >>>>>>>
> >>>>>>> BIT(KVM_FEATURE_STEAL_TIME) | \
> >>>>>>> + BIT(KVM_FEATURE_CRASH)
> >>>>>>> | \
> >>>>>>>
> >>>>>>> BIT(KVM_FEATURE_USER_HCALL) | \
> >>>>>>>
> >>>>>>> BIT(KVM_FEATURE_VIRT_EXTIOI))
> >>>>>>>
> >>>>>>> diff --git a/arch/loongarch/include/asm/kvm_para.h
> >>>>>>> b/arch/loongarch/include/asm/kvm_para.h
> >>>>>>> index fb17ba0fa101..3b183bb1aaa8 100644
> >>>>>>> --- a/arch/loongarch/include/asm/kvm_para.h
> >>>>>>> +++ b/arch/loongarch/include/asm/kvm_para.h
> >>>>>>> @@ -14,6 +14,7 @@
> >>>>>>> #define KVM_HCALL_CODE_SERVICE 0
> >>>>>>> #define KVM_HCALL_CODE_SWDBG 1
> >>>>>>> #define KVM_HCALL_CODE_USER_SERVICE 2
> >>>>>>> +#define KVM_HCALL_CODE_CRASH 3
> >>>>>>>
> >>>>>>> #define KVM_HCALL_SERVICE
> >>>>>>> HYPERCALL_ENCODE(HYPERVISOR_KVM, KVM_HCALL_CODE_SERVICE)
> >>>>>>> #define KVM_HCALL_FUNC_IPI 1
> >>>>>>> @@ -22,6 +23,7 @@
> >>>>>>> #define KVM_HCALL_SWDBG
> >>>>>>> HYPERCALL_ENCODE(HYPERVISOR_KVM, KVM_HCALL_CODE_SWDBG)
> >>>>>>>
> >>>>>>> #define KVM_HCALL_USER_SERVICE
> >>>>>>> HYPERCALL_ENCODE(HYPERVISOR_KVM, KVM_HCALL_CODE_USER_SERVICE)
> >>>>>>> +#define KVM_HCALL_CRASH
> >>>>>>> HYPERCALL_ENCODE(HYPERVISOR_KVM, KVM_HCALL_CODE_CRASH)
> >>>>>>>
> >>>>>>> /*
> >>>>>>> * LoongArch hypercall return code
> >>>>>>> @@ -161,6 +163,19 @@ static __always_inline long
> >>>>>>> kvm_hypercall5(u64 fid,
> >>>>>>> return ret;
> >>>>>>> }
> >>>>>>>
> >>>>>>> +static __always_inline long kvm_hypercall_crash(void)
> >>>>>>> +{
> >>>>>>> + register long ret asm("a0");
> >>>>>>> +
> >>>>>>> + __asm__ __volatile__(
> >>>>>>> + "hvcl "__stringify(KVM_HCALL_CRASH)
> >>>>>>> + : "=r" (ret)
> >>>>>>> + : : "memory"
> >>>>>>> + );
> >>>>>>> +
> >>>>>>> + return ret;
> >>>>>>> +}
> >>>>>> Why this function has no caller?
> >>>>> Currently we directly modify guest kernel and hard-code the hypercall
> >>>>> instruction to debug. This inline function is only example for howto
> >>>>> usage, the normal usage such as checking KVM_FEATURE_USER_HCALL
> >>>>> feature
> >>>>> + kvm_hypercall_crash() is too complicated in exception entry assemble
> >>>>> language.
> >>>> There are no examples for KVM_HCALL_SWDBG and KVM_HCALL_USER_SERVICE,
> >>>> I think KVM_HCALL_CRASH is no special.
> >>>>
> >>>> So if you agree, I will remove this example when applying.
> >>> Removinge the example usage with KVM_HCALL_CRASH is fine to me.
> >> Now all KVM patches for 7.4 is merged to loongarch-kvm. You can test
> >> it if you want.
> > Thanks. there is no problem from the code side, will test this in 7.4-
> > rc1 version.
> My bad. There is problem which is pointed out by sashiko-bot. I had
> thought I have sent v2 version already. Will send v2 soon.
The pull request has been merged.

Huacai

>
> diff --git a/arch/loongarch/kvm/vm.c b/arch/loongarch/kvm/vm.c
> index e5d10ceb5e67..9bf4b3bb8f25 100644
> --- a/arch/loongarch/kvm/vm.c
> +++ b/arch/loongarch/kvm/vm.c
> @@ -164,6 +164,7 @@ static int kvm_vm_feature_has_attr(struct kvm *kvm,
> struct kvm_device_attr *attr
> case KVM_LOONGARCH_VM_FEAT_PV_IPI:
> case KVM_LOONGARCH_VM_FEAT_PV_PREEMPT:
> case KVM_LOONGARCH_VM_FEAT_PV_STEALTIME:
> + case KVM_LOONGARCH_VM_FEAT_CRASH:
> if (kvm_vm_support(&kvm->arch, attr->attr))
> return 0;
> return -ENXIO;
>
> Regards
> Bibo Mao
> >
> > Regards
> > bibo
> >>
> >>
> >> Huacai
> >>
> >>>
> >>> Regards
> >>> Bibo Mao
> >>>>
> >>>>
> >>>> Huacai
> >>>>
> >>>>>
> >>>>> Regards
> >>>>> Bibo Mao
> >>>>>>
> >>>>>>
> >>>>>> Huacai
> >>>>>>
> >>>>>>> +
> >>>>>>> #ifdef CONFIG_PARAVIRT
> >>>>>>> bool kvm_para_available(void);
> >>>>>>> unsigned int kvm_arch_para_features(void);
> >>>>>>> diff --git a/arch/loongarch/include/uapi/asm/kvm.h
> >>>>>>> b/arch/loongarch/include/uapi/asm/kvm.h
> >>>>>>> index cd0b5c11ca9c..b222bfc48042 100644
> >>>>>>> --- a/arch/loongarch/include/uapi/asm/kvm.h
> >>>>>>> +++ b/arch/loongarch/include/uapi/asm/kvm.h
> >>>>>>> @@ -106,6 +106,7 @@ struct kvm_fpu {
> >>>>>>> #define KVM_LOONGARCH_VM_FEAT_PTW 8
> >>>>>>> #define KVM_LOONGARCH_VM_FEAT_MSGINT 9
> >>>>>>> #define KVM_LOONGARCH_VM_FEAT_PV_PREEMPT 10
> >>>>>>> +#define KVM_LOONGARCH_VM_FEAT_CRASH 11
> >>>>>>>
> >>>>>>> /* Device Control API on vcpu fd */
> >>>>>>> #define KVM_LOONGARCH_VCPU_CPUCFG 0
> >>>>>>> diff --git a/arch/loongarch/include/uapi/asm/kvm_para.h
> >>>>>>> b/arch/loongarch/include/uapi/asm/kvm_para.h
> >>>>>>> index d28cbcadd276..bf1a0c826ca6 100644
> >>>>>>> --- a/arch/loongarch/include/uapi/asm/kvm_para.h
> >>>>>>> +++ b/arch/loongarch/include/uapi/asm/kvm_para.h
> >>>>>>> @@ -16,6 +16,7 @@
> >>>>>>> #define KVM_FEATURE_IPI 1
> >>>>>>> #define KVM_FEATURE_STEAL_TIME 2
> >>>>>>> #define KVM_FEATURE_PREEMPT 3
> >>>>>>> +#define KVM_FEATURE_CRASH 4
> >>>>>>> /* BIT 24 - 31 are features configurable by user space vmm */
> >>>>>>> #define KVM_FEATURE_VIRT_EXTIOI 24
> >>>>>>> #define KVM_FEATURE_USER_HCALL 25
> >>>>>>> diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c
> >>>>>>> index 4f58e6e2cf86..3b6daa946c76 100644
> >>>>>>> --- a/arch/loongarch/kvm/exit.c
> >>>>>>> +++ b/arch/loongarch/kvm/exit.c
> >>>>>>> @@ -911,6 +911,17 @@ static int kvm_handle_hypercall(struct
> >>>>>>> kvm_vcpu *vcpu, int ecode)
> >>>>>>> vcpu->run->hypercall.ret =
> >>>>>>> KVM_HCALL_INVALID_CODE;
> >>>>>>> ret = RESUME_HOST;
> >>>>>>> break;
> >>>>>>> + case KVM_HCALL_CRASH:
> >>>>>>> + if (!kvm_guest_has_pv_feature(vcpu,
> >>>>>>> KVM_FEATURE_CRASH)) {
> >>>>>>> + kvm_write_reg(vcpu, LOONGARCH_GPR_A0,
> >>>>>>> KVM_HCALL_INVALID_CODE);
> >>>>>>> + break;
> >>>>>>> + }
> >>>>>>> +
> >>>>>>> + vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
> >>>>>>> + vcpu->run->system_event.type =
> >>>>>>> KVM_SYSTEM_EVENT_CRASH;
> >>>>>>> + vcpu->run->system_event.ndata = 0;
> >>>>>>> + ret = RESUME_HOST;
> >>>>>>> + break;
> >>>>>>> case KVM_HCALL_SWDBG:
> >>>>>>> /* KVM_HCALL_SWDBG only in effective when
> >>>>>>> SW_BP is enabled */
> >>>>>>> if (vcpu->guest_debug &
> >>>>>>> KVM_GUESTDBG_SW_BP_MASK) {
> >>>>>>> diff --git a/arch/loongarch/kvm/vm.c b/arch/loongarch/kvm/vm.c
> >>>>>>> index 6dabb227a732..e5d10ceb5e67 100644
> >>>>>>> --- a/arch/loongarch/kvm/vm.c
> >>>>>>> +++ b/arch/loongarch/kvm/vm.c
> >>>>>>> @@ -49,8 +49,9 @@ static void kvm_vm_init_features(struct kvm *kvm)
> >>>>>>> kvm->arch.kvm_features |=
> >>>>>>> BIT(KVM_LOONGARCH_VM_FEAT_PMU);
> >>>>>>>
> >>>>>>> /* Enable all PV features by default */
> >>>>>>> - kvm->arch.pv_features |= BIT(KVM_FEATURE_IPI);
> >>>>>>> + kvm->arch.pv_features |= BIT(KVM_FEATURE_IPI) |
> >>>>>>> BIT(KVM_FEATURE_CRASH);
> >>>>>>> kvm->arch.kvm_features |=
> >>>>>>> BIT(KVM_LOONGARCH_VM_FEAT_PV_IPI);
> >>>>>>> + kvm->arch.kvm_features |= BIT(KVM_LOONGARCH_VM_FEAT_CRASH);
> >>>>>>> if (kvm_pvtime_supported()) {
> >>>>>>> kvm->arch.pv_features |=
> >>>>>>> BIT(KVM_FEATURE_PREEMPT);
> >>>>>>> kvm->arch.pv_features |=
> >>>>>>> BIT(KVM_FEATURE_STEAL_TIME);
> >>>>>>>
> >>>>>>> base-commit: df2908090cda368b01ff43709f51890076c56157
> >>>>>>> --
> >>>>>>> 2.39.3
> >>>>>>>
> >>>>>>>
> >>>>>
> >>>
>